diff options
author | Pedlar <pedlar88@gmail.com> | 2010-10-05 00:51:57 -0400 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2010-10-17 01:04:47 -0400 |
commit | eb0e39732842151e947f27cf64a00480d75e5631 (patch) | |
tree | 0dd9204ba0593c58ff964fdb49c5502591b5e42f /services | |
parent | c5efffd3ea508745ceba287e1444e69b36b7d6e9 (diff) | |
download | frameworks_base-eb0e39732842151e947f27cf64a00480d75e5631.zip frameworks_base-eb0e39732842151e947f27cf64a00480d75e5631.tar.gz frameworks_base-eb0e39732842151e947f27cf64a00480d75e5631.tar.bz2 |
Galaxy S Style Power Widget
- Finally Ready - Review at will
- This Depends on the following:
CMParts: http://review.cyanogenmod.com/2063
Diffstat (limited to 'services')
16 files changed, 2317 insertions, 21 deletions
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java index 3c31368..7c99b84 100644 --- a/services/java/com/android/server/status/StatusBarService.java +++ b/services/java/com/android/server/status/StatusBarService.java @@ -24,22 +24,30 @@ import android.app.Dialog; import android.app.IStatusBar; import android.app.PendingIntent; import android.app.StatusBarManager; +import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.Resources; +import android.database.ContentObserver; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.location.LocationManager; +import android.media.AudioManager; import android.net.Uri; +import android.net.wifi.WifiManager; +import android.os.AsyncTask; import android.os.IBinder; import android.os.RemoteException; import android.os.Binder; import android.os.Handler; import android.os.Message; import android.os.SystemClock; +import android.provider.Settings; import android.provider.Telephony; import android.util.Log; import android.util.Slog; @@ -66,6 +74,8 @@ import android.widget.FrameLayout; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; +import java.util.Arrays; import java.util.HashMap; import java.util.Set; @@ -75,6 +85,20 @@ import java.lang.reflect.Field; import android.graphics.PorterDuff.Mode; import android.graphics.drawable.StateListDrawable; +import com.android.server.status.widget.PowerButton; +import com.android.server.status.widget.GPSButton; +import com.android.server.status.widget.WifiButton; +import com.android.server.status.widget.BluetoothButton; +import com.android.server.status.widget.BrightnessButton; +import com.android.server.status.widget.SoundButton; +import com.android.server.status.widget.SyncButton; +import com.android.server.status.widget.WifiApButton; +import com.android.server.status.widget.ScreenTimeoutButton; +import com.android.server.status.widget.MobileDataButton; +import com.android.server.status.widget.NetworkModeButton; +import com.android.server.status.widget.LockScreenButton; +import com.android.server.status.widget.AutoRotateButton; +import com.android.server.status.widget.AirplaneButton; /** * The public (ok, semi-public) service for the status bar. @@ -112,7 +136,7 @@ public class StatusBarService extends IStatusBar.Stub private static final int OP_EXPAND = 5; private static final int OP_TOGGLE = 6; private static final int OP_DISABLE = 7; - + private class PendingOp { IBinder key; int code; @@ -165,7 +189,7 @@ public class StatusBarService extends IStatusBar.Stub final Display mDisplay; StatusBarView mStatusBarView; int mPixelFormat; - H mHandler = new H(); + H mHandler; Object mQueueLock = new Object(); ArrayList<PendingOp> mQueue = new ArrayList<PendingOp>(); NotificationCallbacks mNotificationCallbacks; @@ -255,6 +279,8 @@ public class StatusBarService extends IStatusBar.Stub Drawable expBarNotifTitleDrawable; + private WifiManager mWifiManager = null; + private BluetoothAdapter mBluetoothAdapter = null; // for disabling the status bar ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>(); int mDisabled = 0; @@ -264,6 +290,7 @@ public class StatusBarService extends IStatusBar.Stub */ public StatusBarService(Context context) { mContext = context; + mHandler = new H(); notificationTitleColor = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NOTIF_ITEM_TITLE_COLOR, blackColor); notificationTextColor = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NOTIF_ITEM_TEXT_COLOR, blackColor); notificationTimeColor = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NOTIF_ITEM_TIME_COLOR, blackColor); @@ -272,6 +299,8 @@ public class StatusBarService extends IStatusBar.Stub makeStatusBarView(context); updateColors(); mUninstallReceiver = new UninstallReceiver(); + SettingsObserver observer = new SettingsObserver(mHandler); + observer.observe(); } public void setNotificationCallbacks(NotificationCallbacks listener) { @@ -332,15 +361,15 @@ public class StatusBarService extends IStatusBar.Stub mScrollView = (ScrollView)expanded.findViewById(R.id.scroll); mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout); if (custExpBar) { - mExpandedView.findViewById(R.id.exp_view_lin_layout). - setBackgroundDrawable(expBarHeadDrawable); - mNoNotificationsTitle.setBackgroundDrawable(expBarNotifTitleDrawable); - mOngoingTitle.setBackgroundDrawable(expBarNotifTitleDrawable); - mLatestTitle.setBackgroundDrawable(expBarNotifTitleDrawable); - } + mExpandedView.findViewById(R.id.exp_view_lin_layout). + setBackgroundDrawable(expBarHeadDrawable); + mNoNotificationsTitle.setBackgroundDrawable(expBarNotifTitleDrawable); + mOngoingTitle.setBackgroundDrawable(expBarNotifTitleDrawable); + mLatestTitle.setBackgroundDrawable(expBarNotifTitleDrawable); + } mOngoingTitle.setVisibility(View.GONE); mLatestTitle.setVisibility(View.GONE); - + mTicker = new MyTicker(context, sb); tickerView = (TickerView)sb.findViewById(R.id.tickerText); @@ -384,6 +413,12 @@ public class StatusBarService extends IStatusBar.Stub filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION); + filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); + filter.addAction(Settings.SETTINGS_CHANGED); + filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); + filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); + filter.addAction(NetworkModeButton.NETWORK_MODE_CHANGED); context.registerReceiver(mBroadcastReceiver, filter); } @@ -400,10 +435,13 @@ public class StatusBarService extends IStatusBar.Stub lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL; lp.setTitle("StatusBar"); lp.windowAnimations = R.style.Animation_StatusBar; - WindowManagerImpl.getDefault().addView(view, lp); + + mWifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + setupPowerWidget(); } - + // ================================================================================ // From IStatusBar // ================================================================================ @@ -1848,7 +1886,7 @@ public class StatusBarService extends IStatusBar.Stub } } } - + private void updateColors() { mDateView.setTextColor(Settings.System.getInt(mContext.getContentResolver(), Settings.System.DATE_COLOR, blackColor)); mNoNotificationsTitle.setTextColor(Settings.System.getInt(mContext.getContentResolver(), Settings.System.NO_NOTIF_COLOR, whiteColor)); @@ -1866,7 +1904,156 @@ public class StatusBarService extends IStatusBar.Stub addPendingOp(OP_EXPAND, null, false); } }; - + + /** Power Widget **/ + + private View.OnClickListener mPowerListener = new View.OnClickListener() { + public void onClick(View v) { + LinearLayout layout = (LinearLayout)v; + String type = (String)layout.getTag(); + if(PowerButton.TOGGLE_WIFI.equals(type)) { + WifiButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_GPS.equals(type)) { + GPSButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_BLUETOOTH.equals(type)) { + BluetoothButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_BRIGHTNESS.equals(type)) { + BrightnessButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_SOUND.equals(type)) { + SoundButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_SYNC.equals(type)) { + SyncButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_WIFIAP.equals(type)) { + WifiApButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_SCREENTIMEOUT.equals(type)) { + ScreenTimeoutButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_MOBILEDATA.equals(type)) { + MobileDataButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_LOCKSCREEN.equals(type)) { + LockScreenButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_NETWORKMODE.equals(type)) { + NetworkModeButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_AUTOROTATE.equals(type)) { + AutoRotateButton.getInstance().toggleState(mContext); + } else if(PowerButton.TOGGLE_AIRPLANE.equals(type)) { + AirplaneButton.getInstance().toggleState(mContext); + } + updateWidget(); + } + }; + + private void setupPowerWidget() { + LinearLayout layout; + String lists = Settings.System.getString(mContext.getContentResolver(), + Settings.System.WIDGET_BUTTONS); + Log.i("setupPowerWidget", "List: "+lists); + if(lists == null) { + lists = "toggleWifi|toggleBluetooth|toggleGPS|toggleSound"; + } + List<String> list = Arrays.asList(lists.split("\\|")); + clearWidget(); + + int posi; + for(posi = 0; posi < list.size(); posi++) { + layout = (LinearLayout)mExpandedView.findViewById(PowerButton.getLayoutID(posi + 1)); + String buttonType = list.get(posi); + layout.setVisibility(View.VISIBLE); + layout.setTag(list.get(posi)); + layout.setOnClickListener(mPowerListener); + setupWidget(buttonType, posi + 1); + } + updateWidget(); + } + + private void setupWidget(String buttonType, int position) { + + if(PowerButton.TOGGLE_WIFI.equals(buttonType)) { + WifiButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_GPS.equals(buttonType)) { + GPSButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_BLUETOOTH.equals(buttonType)) { + BluetoothButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_BRIGHTNESS.equals(buttonType)) { + BrightnessButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_SOUND.equals(buttonType)) { + SoundButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_SYNC.equals(buttonType)) { + SyncButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_WIFIAP.equals(buttonType)) { + WifiApButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_SCREENTIMEOUT.equals(buttonType)) { + ScreenTimeoutButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_MOBILEDATA.equals(buttonType)) { + MobileDataButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_LOCKSCREEN.equals(buttonType)) { + LockScreenButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_NETWORKMODE.equals(buttonType)) { + NetworkModeButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_AUTOROTATE.equals(buttonType)) { + AutoRotateButton.getInstance().setupButton(position); + } else if(PowerButton.TOGGLE_AIRPLANE.equals(buttonType)) { + AirplaneButton.getInstance().setupButton(position); + } + + } + + private void clearWidget() { + for(int posi = 0; posi < 6; posi++) { + LinearLayout layout = (LinearLayout)mExpandedView.findViewById(PowerButton.getLayoutID(posi + 1)); + layout.setVisibility(View.GONE); + layout.setTag(""); + } + WifiButton.getInstance().setupButton(0); + GPSButton.getInstance().setupButton(0); + BluetoothButton.getInstance().setupButton(0); + BrightnessButton.getInstance().setupButton(0); + SoundButton.getInstance().setupButton(0); + SyncButton.getInstance().setupButton(0); + WifiApButton.getInstance().setupButton(0); + ScreenTimeoutButton.getInstance().setupButton(0); + MobileDataButton.getInstance().setupButton(0); + LockScreenButton.getInstance().setupButton(0); + NetworkModeButton.getInstance().setupButton(0); + AutoRotateButton.getInstance().setupButton(0); + AirplaneButton.getInstance().setupButton(0); + } + + private void updateStates() { + GPSButton.getInstance().updateState(mContext); + WifiButton.getInstance().updateState(mContext); + BluetoothButton.getInstance().updateState(mContext); + BrightnessButton.getInstance().updateState(mContext); + SoundButton.getInstance().updateState(mContext); + SyncButton.getInstance().updateState(mContext); + WifiApButton.getInstance().updateState(mContext); + ScreenTimeoutButton.getInstance().updateState(mContext); + MobileDataButton.getInstance().updateState(mContext); + LockScreenButton.getInstance().updateState(mContext); + NetworkModeButton.getInstance().updateState(mContext); + AutoRotateButton.getInstance().updateState(mContext); + AirplaneButton.getInstance().updateState(mContext); + } + private void updateViews() { + GPSButton.getInstance().updateView(mContext, mExpandedView); + WifiButton.getInstance().updateView(mContext, mExpandedView); + BluetoothButton.getInstance().updateView(mContext, mExpandedView); + BrightnessButton.getInstance().updateView(mContext, mExpandedView); + SoundButton.getInstance().updateView(mContext, mExpandedView); + SyncButton.getInstance().updateView(mContext, mExpandedView); + WifiApButton.getInstance().updateView(mContext, mExpandedView); + ScreenTimeoutButton.getInstance().updateView(mContext, mExpandedView); + MobileDataButton.getInstance().updateView(mContext, mExpandedView); + LockScreenButton.getInstance().updateView(mContext, mExpandedView); + NetworkModeButton.getInstance().updateView(mContext, mExpandedView); + AutoRotateButton.getInstance().updateView(mContext, mExpandedView); + AirplaneButton.getInstance().updateView(mContext, mExpandedView); + } + + private void updateWidget() { + updateStates(); + updateViews(); + } + private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); @@ -1883,6 +2070,16 @@ public class StatusBarService extends IStatusBar.Stub else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { updateResources(); } + else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) { + WifiButton.getInstance().onReceive(context, intent); + } else if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) { + WifiApButton.getInstance().onReceive(context, intent); + } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) { + BluetoothButton.getInstance().onReceive(context, intent); + } else if (NetworkModeButton.NETWORK_MODE_CHANGED.equals(intent.getAction())) { + NetworkModeButton.getInstance().onReceive(context, intent); + } + updateWidget(); } }; @@ -1920,7 +2117,7 @@ public class StatusBarService extends IStatusBar.Stub /** * Reload some of our resources when the configuration changes. - * + * * We don't reload everything when the configuration changes -- we probably * should, but getting that smooth is tough. Someday we'll fix that. In the * meantime, just update the things that we know change. @@ -1969,7 +2166,7 @@ public class StatusBarService extends IStatusBar.Stub vibrate(); } }; - + class UninstallReceiver extends BroadcastReceiver { public UninstallReceiver() { IntentFilter filter = new IntentFilter(); @@ -1980,7 +2177,7 @@ public class StatusBarService extends IStatusBar.Stub IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); mContext.registerReceiver(this, sdFilter); } - + @Override public void onReceive(Context context, Intent intent) { String pkgList[] = null; @@ -2003,7 +2200,7 @@ public class StatusBarService extends IStatusBar.Stub } } } - + if (list != null) { final int N = list.size(); for (int i=0; i<N; i++) { @@ -2012,7 +2209,7 @@ public class StatusBarService extends IStatusBar.Stub } } } - + private void getNotBarConfig() { Resources res = mContext.getResources(); /* @@ -2034,7 +2231,7 @@ public class StatusBarService extends IStatusBar.Stub Settings.System.NOTIF_EXPANDED_BAR_CUSTOM, 0) == 1; expBarColorMask = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NOTIF_EXPANDED_BAR_COLOR, whiteColor); - int noalpha = expBarColorMask | 0xFF000000; + int noalpha = expBarColorMask | 0xFF000000; if (useCustomExp) { closerDrawable = res.getDrawable(com.android.internal.R.drawable.status_bar_close_on_cust); expBarHeadDrawable = res.getDrawable(com.android.internal.R.drawable.status_bar_header_background_cust, @@ -2043,7 +2240,143 @@ public class StatusBarService extends IStatusBar.Stub noalpha, expPDMode); // always solid custExpBar = true; } else { - custExpBar = false; - } + custExpBar = false; + } + } + + public class SettingsObserver extends ContentObserver { + public SettingsObserver(Handler handler) { + super(handler); + } + + public void observe() { + ContentResolver resolver = mContext.getContentResolver(); + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.NOTIF_EXPANDED_BAR_CUSTOM), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.NOTIF_EXPANDED_BAR_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.NOTIF_BAR_CUSTOM), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.NOTIF_BAR_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.NOTIF_ITEM_TITLE_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.NOTIF_ITEM_TEXT_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.NOTIF_ITEM_TIME_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.DATE_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.NO_NOTIF_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.LATEST_NOTIF_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.ONGOING_NOTIF_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.SPN_LABEL_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.PLMN_LABEL_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.CLEAR_BUTTON_LABEL_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.NEW_NOTIF_TICKER_COLOR), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.EXPANDED_VIEW_WIDGET), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON), + false, this); + + resolver.registerContentObserver( + Settings.System.getUriFor(Settings.System.WIDGET_BUTTONS), + false, this); + } + + @Override + public void onChangeUri(Uri uri, boolean selfChange) { + update(uri); + } + + public void update(Uri uri) { + ContentResolver resolver = mContext.getContentResolver(); + Resources res = mContext.getResources(); + updateColors(); + if(uri.equals(Settings.System.getUriFor(Settings.System.NOTIF_EXPANDED_BAR_CUSTOM)) || + uri.equals(Settings.System.getUriFor(Settings.System.NOTIF_EXPANDED_BAR_COLOR)) || + uri.equals(Settings.System.getUriFor(Settings.System.NOTIF_BAR_CUSTOM)) || + uri.equals(Settings.System.getUriFor(Settings.System.NOTIF_BAR_COLOR))) { + + getNotBarConfig(); + if (custExpBar) { + mExpandedView.findViewById(R.id.exp_view_lin_layout). + setBackgroundDrawable(expBarHeadDrawable); + mNoNotificationsTitle.setBackgroundDrawable(expBarNotifTitleDrawable); + mOngoingTitle.setBackgroundDrawable(expBarNotifTitleDrawable); + mLatestTitle.setBackgroundDrawable(expBarNotifTitleDrawable); + } + if (custNotBar) { + mStatusBarView.setBackgroundDrawable( + res.getDrawable(com.android.internal.R.drawable.statusbar_background_sq, + notifBarColorMask, notifPDMode)); + mDateView.setBackgroundDrawable( + res.getDrawable(com.android.internal.R.drawable.statusbar_background_sq, + notifBarColorMask, notifPDMode)); + mDateView.setPadding(6, 0, 6, 0); + } + } else if(uri.equals(Settings.System.getUriFor(Settings.System.WIDGET_BUTTONS))) { + setupPowerWidget(); + } + + boolean powerWidget = Settings.System.getInt(mContext.getContentResolver(), + Settings.System.EXPANDED_VIEW_WIDGET, 0) == 1; + if(!powerWidget) { + mExpandedView.findViewById(R.id.exp_power_stat). + setVisibility(View.GONE); + } else { + mExpandedView.findViewById(R.id.exp_power_stat). + setVisibility(View.VISIBLE); + } + updateWidget(); + } } } diff --git a/services/java/com/android/server/status/widget/AirplaneButton.java b/services/java/com/android/server/status/widget/AirplaneButton.java new file mode 100755 index 0000000..c7a4df7 --- /dev/null +++ b/services/java/com/android/server/status/widget/AirplaneButton.java @@ -0,0 +1,63 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.provider.Settings; + +public class AirplaneButton extends PowerButton { + + static AirplaneButton ownButton=null; + + public void updateState(Context context) { + if (getState(context)) { + currentIcon = R.drawable.stat_airplane_on; + currentState = PowerButton.STATE_ENABLED; + } else { + currentIcon = R.drawable.stat_airplane_off; + currentState = PowerButton.STATE_DISABLED; + } + + } + + /** + * Toggles the state of Airplane + * + * @param context + */ + public void toggleState(Context context) { + boolean state = getState(context); + Settings.System.putInt(context.getContentResolver(), + Settings.System.AIRPLANE_MODE_ON, state ? 0 : 1); + // notify change + Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); + intent.putExtra("state", state); + context.sendBroadcast(intent); + } + + /** + * Gets the state of Airplane. + * + * @param context + * @return true if enabled. + */ + private static boolean getState(Context context) { + return Settings.System.getInt(context.getContentResolver(), + Settings.System.AIRPLANE_MODE_ON,0) == 1; + } + + + public static AirplaneButton getInstance() { + if (ownButton==null) ownButton = new AirplaneButton(); + return ownButton; + } + + @Override + void initButton(int poisition) { + } + +} + diff --git a/services/java/com/android/server/status/widget/AutoRotateButton.java b/services/java/com/android/server/status/widget/AutoRotateButton.java new file mode 100755 index 0000000..501404a --- /dev/null +++ b/services/java/com/android/server/status/widget/AutoRotateButton.java @@ -0,0 +1,50 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; + +import android.content.Context; +import android.provider.Settings; + +public class AutoRotateButton extends PowerButton { + + static AutoRotateButton ownButton = null; + + @Override + public void toggleState(Context context) { + if(getOrientationState(context) == 0) { + Settings.System.putInt( + context.getContentResolver(), + Settings.System.ACCELEROMETER_ROTATION, 1); + } else { + Settings.System.putInt( + context.getContentResolver(), + Settings.System.ACCELEROMETER_ROTATION, 0); + } } + + @Override + public void updateState(Context context) { + if (getOrientationState(context) == 1) { + currentIcon = R.drawable.stat_orientation_on; + currentState = PowerButton.STATE_ENABLED; + } else { + currentIcon = R.drawable.stat_orientation_off; + currentState = PowerButton.STATE_DISABLED; + } + } + + public static int getOrientationState(Context context) { + return Settings.System.getInt( + context.getContentResolver(), + Settings.System.ACCELEROMETER_ROTATION, 0); + } + + public static AutoRotateButton getInstance() { + if (ownButton == null) ownButton = new AutoRotateButton(); + return ownButton; + } + + @Override + void initButton(int position) { + } +} diff --git a/services/java/com/android/server/status/widget/BluetoothButton.java b/services/java/com/android/server/status/widget/BluetoothButton.java new file mode 100755 index 0000000..4461a54 --- /dev/null +++ b/services/java/com/android/server/status/widget/BluetoothButton.java @@ -0,0 +1,141 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; +import com.android.server.status.widget.StateTracker; + +import android.bluetooth.BluetoothAdapter; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.AsyncTask; +import android.util.Log; + +public class BluetoothButton extends PowerButton{ + + private static final StateTracker sBluetoothState = new BluetoothStateTracker(); + + static BluetoothButton ownButton = null; + + + /** + * Subclass of StateTracker to get/set Bluetooth state. + */ + private static final class BluetoothStateTracker extends StateTracker { + + @Override + public int getActualState(Context context) { + BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if (mBluetoothAdapter == null) { + return PowerButton.STATE_UNKNOWN; // On emulator? + } + return bluetoothStateToFiveState(mBluetoothAdapter + .getState()); + } + + @Override + protected void requestStateChange(Context context, + final boolean desiredState) { + // Actually request the Bluetooth change and persistent + // settings write off the UI thread, as it can take a + // user-noticeable amount of time, especially if there's + // disk contention. + new AsyncTask<Void, Void, Void>() { + @Override + protected Void doInBackground(Void... args) { + BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + if(mBluetoothAdapter.isEnabled()) { + mBluetoothAdapter.disable(); + } else { + mBluetoothAdapter.enable(); + } + return null; + } + }.execute(); + } + + @Override + public void onActualStateChange(Context context, Intent intent) { + if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent + .getAction())) { + return; + } + int bluetoothState = intent.getIntExtra( + BluetoothAdapter.EXTRA_STATE, -1); + setCurrentState(context, bluetoothStateToFiveState(bluetoothState)); + } + + /** + * Converts BluetoothAdapter's state values into our + * Wifi/Bluetooth-common state values. + */ + private static int bluetoothStateToFiveState(int bluetoothState) { + switch (bluetoothState) { + case BluetoothAdapter.STATE_OFF: + return PowerButton.STATE_DISABLED; + case BluetoothAdapter.STATE_ON: + return PowerButton.STATE_ENABLED; + case BluetoothAdapter.STATE_TURNING_ON: + return PowerButton.STATE_TURNING_ON; + case BluetoothAdapter.STATE_TURNING_OFF: + return PowerButton.STATE_TURNING_OFF; + default: + return PowerButton.STATE_UNKNOWN; + } + } + } + + + + public static BluetoothButton getInstance() { + if (ownButton == null) ownButton = new BluetoothButton(); + + return ownButton; + } + + @Override + void initButton(int position) { + } + + @Override + public void toggleState(Context context) { + sBluetoothState.toggleState(context); + } + + @Override + public void updateState(Context context) { + currentState = sBluetoothState.getTriState(context); + switch (currentState) { + case PowerButton.STATE_DISABLED: + currentIcon = R.drawable.stat_bluetooth_off; + break; + case PowerButton.STATE_ENABLED: + currentIcon = R.drawable.stat_bluetooth_on; + break; + case PowerButton.STATE_INTERMEDIATE: + // In the transitional state, the bottom green bar + // shows the tri-state (on, off, transitioning), but + // the top dark-gray-or-bright-white logo shows the + // user's intent. This is much easier to see in + // sunlight. + if (sBluetoothState.isTurningOn()) { + currentIcon = R.drawable.stat_bluetooth_on; + } else { + currentIcon = R.drawable.stat_bluetooth_off; + } + break; + } + } + + public void onReceive(Context context, Intent intent) { + sBluetoothState.onActualStateChange(context, intent); + } + + public void toggleState(Context context, int newState) { + int curState = sBluetoothState.getTriState(context); + if (curState != PowerButton.STATE_INTERMEDIATE && + curState != newState) { + toggleState(context); + } + } +} diff --git a/services/java/com/android/server/status/widget/BrightnessButton.java b/services/java/com/android/server/status/widget/BrightnessButton.java new file mode 100755 index 0000000..9a4e098 --- /dev/null +++ b/services/java/com/android/server/status/widget/BrightnessButton.java @@ -0,0 +1,253 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.IPowerManager; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.provider.Settings; +import android.util.Log; + +public class BrightnessButton extends PowerButton { + + /** + * Minimum and maximum brightnesses. Don't go to 0 since that makes the + * display unusable + */ + private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10; + private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON; + private static int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f); + + private static int LOW_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.25f); + private static int MID_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.5f); + private static int HIGH_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.75f); + + private static final int AUTO_BACKLIGHT = -1; + + private static final int MODE_AUTO_MIN_DEF_MAX=0; + private static final int MODE_AUTO_MIN_LOW_MID_HIGH_MAX=1; + private static final int MODE_AUTO_LOW_MAX=2; + private static final int MODE_MIN_MAX=3; + + private static final int DEFAULT_SETTING = 0; + + private static Boolean supportsAutomaticMode=null; + + static BrightnessButton ownButton=null; + + private static int currentMode; + + + /* + * +Auto_Min_Low_Max +Auto_Min . Max +Auto. Min . Low High. Max +Auto_Low / High +Auto_Low / High / Max + + +Min / Max +Min Low Max +Min Low High Max +Low High +Low High Max + + + */ + + public static int getMinBacklight(Context context) { + if (Settings.System.getInt(context.getContentResolver(), + Settings.System.LIGHT_SENSOR_CUSTOM, 0) != 0) { + return Settings.System.getInt(context.getContentResolver(), + Settings.System.LIGHT_SCREEN_DIM, MINIMUM_BACKLIGHT); + } else { + return MINIMUM_BACKLIGHT; + } + } + + + private static boolean isAutomaticModeSupported(Context context) { + if (supportsAutomaticMode == null) { + if (context + .getResources() + .getBoolean( + com.android.internal.R.bool.config_automatic_brightness_available)) { + supportsAutomaticMode=true; + } else { + supportsAutomaticMode=false; + } + } + return supportsAutomaticMode; + } + + /** + * Gets state of brightness mode. + * + * @param context + * @return true if auto brightness is on. + */ + private static boolean isBrightnessSetToAutomatic(Context context) { + try { + IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager + .getService("power")); + if (power != null) { + int brightnessMode = Settings.System.getInt(context + .getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_MODE); + return brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; + } + } catch (Exception e) { + Log.d("PowerWidget", "getBrightnessMode: " + e); + } + return false; + } + + + + private int getNextBrightnessValue(Context context) { + int brightness = Settings.System.getInt(context.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS,0); + + if (isAutomaticModeSupported(context) && isBrightnessSetToAutomatic(context)) { + if (currentMode == MODE_AUTO_LOW_MAX) { + return LOW_BACKLIGHT; + } else { + return getMinBacklight(context); + } + } else if (brightness < LOW_BACKLIGHT) { + if (currentMode == MODE_AUTO_LOW_MAX) { + return LOW_BACKLIGHT; + } else if (currentMode == MODE_MIN_MAX) { + return MAXIMUM_BACKLIGHT; + } else { + return DEFAULT_BACKLIGHT; + } + } else if (brightness < DEFAULT_BACKLIGHT) { + if (currentMode == MODE_AUTO_MIN_DEF_MAX) { + return DEFAULT_BACKLIGHT; + } else if (currentMode == MODE_AUTO_LOW_MAX || currentMode == MODE_MIN_MAX) { + return MAXIMUM_BACKLIGHT; + } else { + return MID_BACKLIGHT; + } + } else if (brightness < MID_BACKLIGHT) { + if (currentMode == MODE_AUTO_MIN_LOW_MID_HIGH_MAX) { + return MID_BACKLIGHT; + } else { + return MAXIMUM_BACKLIGHT; + } + } else if (brightness < HIGH_BACKLIGHT) { + if (currentMode == MODE_AUTO_MIN_LOW_MID_HIGH_MAX) { + return HIGH_BACKLIGHT; + } else { + return MAXIMUM_BACKLIGHT; + } + } else if (brightness < MAXIMUM_BACKLIGHT) { + return MAXIMUM_BACKLIGHT; + } else if (isAutomaticModeSupported(context) && currentMode!=MODE_MIN_MAX) { + return AUTO_BACKLIGHT; + } else if(currentMode == MODE_AUTO_LOW_MAX){ + return LOW_BACKLIGHT; + } else { + return getMinBacklight(context); + } + } + + /** + * Increases or decreases the brightness. + * + * @param context + */ + public void toggleState(Context context) { + try { + IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager + .getService("power")); + if (power != null) { + int brightness = getNextBrightnessValue(context); + ContentResolver contentResolver = context.getContentResolver(); + if (brightness == AUTO_BACKLIGHT) { + Settings.System.putInt(contentResolver, + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC); + } else { + if (isAutomaticModeSupported(context)) { + Settings.System.putInt(contentResolver, + Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); + } + power.setBacklightBrightness(brightness); + Settings.System.putInt(contentResolver, + Settings.System.SCREEN_BRIGHTNESS, brightness); + } + } + } catch (RemoteException e) { + Log.d("PowerWidget", "toggleBrightness: " + e); + } + } + + + public static BrightnessButton getInstance() { + if (ownButton == null) ownButton = new BrightnessButton(); + + return ownButton; + } + + @Override + void initButton(int position) { + } + + @Override + public void updateState(Context context) { + currentMode = Settings.System.getInt(context.getContentResolver(), + Settings.System.EXPANDED_BRIGHTNESS_MODE, DEFAULT_SETTING); + + if (isBrightnessSetToAutomatic(context)) { + currentIcon = R.drawable.stat_brightness_auto; + currentState = PowerButton.STATE_ENABLED; + } else if (getBrightnessState(context) == PowerButton.STATE_ENABLED) { + currentIcon = R.drawable.stat_brightness_on; + currentState = PowerButton.STATE_ENABLED; + } else if (getBrightnessState(context) == PowerButton.STATE_TURNING_ON) { + currentIcon = R.drawable.stat_brightness_on; + currentState = PowerButton.STATE_INTERMEDIATE; + } else if (getBrightnessState(context) == PowerButton.STATE_TURNING_OFF) { + currentIcon = R.drawable.stat_brightness_off; + currentState = PowerButton.STATE_INTERMEDIATE; + } else { + currentIcon = R.drawable.stat_brightness_off; + currentState = PowerButton.STATE_DISABLED; + } + } + + private int getBrightnessState(Context context) { + int brightness = Settings.System.getInt(context.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS,0); + + if (brightness < LOW_BACKLIGHT) { + return PowerButton.STATE_DISABLED; + } else if (brightness < DEFAULT_BACKLIGHT) { + return PowerButton.STATE_DISABLED; + } else if (brightness < MID_BACKLIGHT) { + if (currentMode == MODE_AUTO_MIN_LOW_MID_HIGH_MAX) { + return PowerButton.STATE_DISABLED; + } else { + return PowerButton.STATE_TURNING_OFF; + } + } else if (brightness < HIGH_BACKLIGHT) { + if (currentMode == MODE_AUTO_MIN_LOW_MID_HIGH_MAX) { + return PowerButton.STATE_TURNING_OFF; + } else { + return PowerButton.STATE_TURNING_ON; + } + } else if (brightness < MAXIMUM_BACKLIGHT) { + return PowerButton.STATE_TURNING_ON; + } else { + return PowerButton.STATE_ENABLED; + } + } +} diff --git a/services/java/com/android/server/status/widget/GPSButton.java b/services/java/com/android/server/status/widget/GPSButton.java new file mode 100644 index 0000000..0251745 --- /dev/null +++ b/services/java/com/android/server/status/widget/GPSButton.java @@ -0,0 +1,50 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; + +import android.content.ContentResolver; +import android.content.Context; +import android.location.LocationManager; +import android.provider.Settings; +import android.util.Log; + +public class GPSButton extends PowerButton { + static GPSButton ownButton; + + public void updateState(Context context) { + Log.i("GPSButton", "Update State"); + if(getGpsState(context)) { + currentIcon = com.android.internal.R.drawable.stat_gps_on; + currentState = STATE_ENABLED; + } else { + currentIcon = com.android.internal.R.drawable.stat_gps_off; + currentState = STATE_DISABLED; + } + } + + public void toggleState(Context context) { + Log.i("GPSButton", "ToggleState"); + ContentResolver resolver = context.getContentResolver(); + boolean enabled = getGpsState(context); + Settings.Secure.setLocationProviderEnabled(resolver, + LocationManager.GPS_PROVIDER, !enabled); + } + + private static boolean getGpsState(Context context) { + ContentResolver resolver = context.getContentResolver(); + return Settings.Secure.isLocationProviderEnabled(resolver, + LocationManager.GPS_PROVIDER); + } + + public static GPSButton getInstance() { + if (ownButton==null) ownButton = new GPSButton(); + + return ownButton; + } + + @Override + void initButton(int position) { + } + +} diff --git a/services/java/com/android/server/status/widget/LockScreenButton.java b/services/java/com/android/server/status/widget/LockScreenButton.java new file mode 100755 index 0000000..e1b205d --- /dev/null +++ b/services/java/com/android/server/status/widget/LockScreenButton.java @@ -0,0 +1,92 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; + +import android.app.Activity; +import android.app.KeyguardManager; +import android.app.KeyguardManager.KeyguardLock; +import android.content.Context; +import android.content.SharedPreferences; +import android.view.Gravity; +import android.widget.Toast; + +public class LockScreenButton extends PowerButton { + + static Boolean lockScreen = null; + + public static final String LOCK_SCREEN = "lockScreen"; + static LockScreenButton ownButton = null; + KeyguardLock lock; + + private KeyguardLock getLock(Context context) { + if (lock == null) { + KeyguardManager keyguardManager = (KeyguardManager)context. + getSystemService(Activity.KEYGUARD_SERVICE); + lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE); + } + return lock; + } + + public void updateState(Context context) { + getState(context); + if (lockScreen == null) { + currentIcon = R.drawable.stat_lock_screen_off; + currentState = PowerButton.STATE_INTERMEDIATE; + } else if (lockScreen) { + currentIcon = R.drawable.stat_lock_screen_on; + currentState = PowerButton.STATE_ENABLED; + } else { + currentIcon = R.drawable.stat_lock_screen_off; + currentState = PowerButton.STATE_DISABLED; + } + } + + /** + * Toggles the state of GPS. + * + * @param context + */ + public void toggleState(Context context) { + getState(context); + if(lockScreen == null) { + Toast msg = Toast.makeText(context, "Not yet initialized", Toast.LENGTH_LONG); + msg.setGravity(Gravity.CENTER, msg.getXOffset() / 2, msg.getYOffset() / 2); + msg.show(); + } else { + getLock(context); + if (lockScreen && lock != null) { + lock.disableKeyguard(); + lockScreen = false; + } else if (lock != null) { + lock.reenableKeyguard(); + lockScreen = true; + } + } + } + + /** + * Gets the state of GPS location. + * + * @param context + * @return true if enabled. + */ + private static boolean getState(Context context) { + if (lockScreen == null) { + lockScreen = true; + } + return lockScreen; + } + + + public static LockScreenButton getInstance() { + if (ownButton==null) ownButton = new LockScreenButton(); + + return ownButton; + } + + @Override + void initButton(int position) { + } +} + diff --git a/services/java/com/android/server/status/widget/MobileDataButton.java b/services/java/com/android/server/status/widget/MobileDataButton.java new file mode 100755 index 0000000..69aa304 --- /dev/null +++ b/services/java/com/android/server/status/widget/MobileDataButton.java @@ -0,0 +1,85 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; + +import android.content.Context; +import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.provider.Settings; + +public class MobileDataButton extends PowerButton { + + public static final String MOBILE_DATA_CHANGED = "com.android.internal.telephony.MOBILE_DATA_CHANGED"; + + static MobileDataButton ownButton = null; + + static boolean stateChangeRequest = false; + + public static boolean getDataRomingEnabled(Context context) { + return Settings.Secure.getInt(context.getContentResolver(), + Settings.Secure.DATA_ROAMING,0) > 0; + } + + /** + * Gets the state of data + * + * @return true if enabled. + */ + private static boolean getDataState(Context context) { + ConnectivityManager cm = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + return cm.getMobileDataEnabled(); + } + + /** + * Toggles the state of data. + * + */ + @Override + public void toggleState(Context context) { + boolean enabled = getDataState(context); + + ConnectivityManager cm = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + if (enabled) { + cm.setMobileDataEnabled(false); + } else { + cm.setMobileDataEnabled(true); + } + } + + @Override + public void updateState(Context context) { + if (stateChangeRequest) { + currentIcon = R.drawable.stat_data_on; + currentState = PowerButton.STATE_INTERMEDIATE; + } else if (getDataState(context)) { + currentIcon = R.drawable.stat_data_on; + currentState = PowerButton.STATE_ENABLED; + } else { + currentIcon = R.drawable.stat_data_off; + currentState = PowerButton.STATE_DISABLED; + } + } + + public static MobileDataButton getInstance() { + if (ownButton == null) ownButton = new MobileDataButton(); + + return ownButton; + } + + @Override + void initButton(int position) { + } + + public void networkModeChanged(Context context, int networkMode) { + if (stateChangeRequest) { + ConnectivityManager cm = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + cm.setMobileDataEnabled(true); + stateChangeRequest=false; + } + } + +} diff --git a/services/java/com/android/server/status/widget/NetworkModeButton.java b/services/java/com/android/server/status/widget/NetworkModeButton.java new file mode 100755 index 0000000..b735448 --- /dev/null +++ b/services/java/com/android/server/status/widget/NetworkModeButton.java @@ -0,0 +1,195 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; + +import android.content.Context; +import android.content.Intent; +import android.provider.Settings.SettingNotFoundException; +import android.widget.Toast; +import android.provider.Settings; + +import com.android.internal.telephony.Phone; + +public class NetworkModeButton extends PowerButton{ + + public static final String NETWORK_MODE_CHANGED = "com.android.internal.telephony.NETWORK_MODE_CHANGED"; + public static final String REQUEST_NETWORK_MODE = "com.android.internal.telephony.REQUEST_NETWORK_MODE"; + public static final String MODIFY_NETWORK_MODE = "com.android.internal.telephony.MODIFY_NETWORK_MODE"; + + public static final String NETWORK_MODE = "networkMode"; + + private static final int NO_NETWORK_MODE_YET = -99; + private static final int NETWORK_MODE_UNKNOWN = -100; + + private static final int MODE_3G2G = 0; + private static final int MODE_3GONLY = 1; + private static final int MODE_BOTH = 2; + + private static final int DEFAULT_SETTING = 0; + + static NetworkModeButton ownButton = null; + + private static int networkMode = NO_NETWORK_MODE_YET; + private static int intendedNetworkMode = NO_NETWORK_MODE_YET; + private static int currentInternalState = PowerButton.STATE_INTERMEDIATE; + private int currentMode; + + + private int networkModeToState(Context context) { + if (currentInternalState == PowerButton.STATE_TURNING_ON || + currentInternalState == PowerButton.STATE_TURNING_OFF) + return PowerButton.STATE_INTERMEDIATE; + + switch(networkMode) { + case Phone.NT_MODE_WCDMA_PREF: + case Phone.NT_MODE_WCDMA_ONLY: + return PowerButton.STATE_ENABLED; + case Phone.NT_MODE_GSM_ONLY: + return PowerButton.STATE_DISABLED; + } + return PowerButton.STATE_INTERMEDIATE; + } + + + /** + * Gets the state of 2G3g // NOT working + * + * @param context + * @return true if enabled. + */ + + private int get2G3G(Context context) { + int state = 99; + try { + state = android.provider.Settings.Secure.getInt(context + .getContentResolver(), + android.provider.Settings.Secure.PREFERRED_NETWORK_MODE); + } catch (SettingNotFoundException e) { + } + return state; + } + + + public static NetworkModeButton getInstance() { + if (ownButton == null) ownButton = new NetworkModeButton(); + return ownButton; + } + + @Override + void initButton(int position) { + } + + @Override + public void toggleState(Context context) { + toggleState(context, false); + } + + public void toggleState(Context context, int newState) { + if (currentState != PowerButton.STATE_INTERMEDIATE && currentState != newState) { + toggleState(context,true); + } else if (currentState == PowerButton.STATE_INTERMEDIATE){ + Toast toast = Toast.makeText(context, "Network mode state unknown. Please change it manually!",Toast.LENGTH_SHORT); + toast.show(); + } + } + + public void toggleState(Context context, boolean switchModes) { + Intent intent = new Intent(MODIFY_NETWORK_MODE); + switch (networkMode ) { + case Phone.NT_MODE_WCDMA_PREF: + intent.putExtra(NETWORK_MODE, Phone.NT_MODE_GSM_ONLY); + currentInternalState = PowerButton.STATE_TURNING_OFF; + intendedNetworkMode=Phone.NT_MODE_GSM_ONLY; + break; + case Phone.NT_MODE_WCDMA_ONLY: + if (currentMode == MODE_3GONLY || switchModes) { + intent.putExtra(NETWORK_MODE, Phone.NT_MODE_GSM_ONLY); + currentInternalState = PowerButton.STATE_TURNING_OFF; + intendedNetworkMode=Phone.NT_MODE_GSM_ONLY; + } else { + intent.putExtra(NETWORK_MODE, Phone.NT_MODE_WCDMA_PREF); + currentInternalState = PowerButton.STATE_TURNING_ON; + intendedNetworkMode = Phone.NT_MODE_WCDMA_PREF; + } + break; + case Phone.NT_MODE_GSM_ONLY: + if (currentMode == MODE_3GONLY || currentMode == MODE_BOTH ) { + intent.putExtra(NETWORK_MODE, Phone.NT_MODE_WCDMA_ONLY); + currentInternalState = PowerButton.STATE_TURNING_ON; + intendedNetworkMode = Phone.NT_MODE_WCDMA_ONLY; + } else { + intent.putExtra(NETWORK_MODE, Phone.NT_MODE_WCDMA_PREF); + currentInternalState = PowerButton.STATE_TURNING_ON; + intendedNetworkMode = Phone.NT_MODE_WCDMA_PREF; + } + break; + } + + networkMode = NETWORK_MODE_UNKNOWN; + context.sendBroadcast(intent); + } + + + + + @Override + public void updateState(Context context) { + currentMode = Settings.System.getInt(context.getContentResolver(), + Settings.System.EXPANDED_NETWORK_MODE, DEFAULT_SETTING); + networkMode = get2G3G(context); + currentState = networkModeToState(context); + + switch (currentState) { + case PowerButton.STATE_DISABLED: + currentIcon = R.drawable.stat_2g3g_off; + break; + case PowerButton.STATE_ENABLED: + if (networkMode == Phone.NT_MODE_WCDMA_ONLY) { + currentIcon = R.drawable.stat_3g_on; + } else { + currentIcon = R.drawable.stat_2g3g_on; + } + break; + case PowerButton.STATE_INTERMEDIATE: + // In the transitional state, the bottom green bar + // shows the tri-state (on, off, transitioning), but + // the top dark-gray-or-bright-white logo shows the + // user's intent. This is much easier to see in + // sunlight. + if (currentInternalState == PowerButton.STATE_TURNING_ON) { + if (intendedNetworkMode == Phone.NT_MODE_WCDMA_ONLY) { + currentIcon = R.drawable.stat_3g_on; + } else { + currentIcon = R.drawable.stat_2g3g_on; + } + } else { + currentIcon = R.drawable.stat_2g3g_off; + } + break; + } + } + + + public void onReceive(Context context, Intent intent) { + if (intent.getExtras() != null) { + networkMode = intent.getExtras().getInt(NETWORK_MODE); + //Update to actual state + intendedNetworkMode=networkMode; + } + + //need to clear intermediate states + currentInternalState=PowerButton.STATE_ENABLED; + + int widgetState = networkModeToState(context); + currentInternalState = widgetState; + if (widgetState == PowerButton.STATE_ENABLED) { + MobileDataButton.getInstance().networkModeChanged(context, networkMode); + } + } + + public boolean isDisabled(Context context) { + return networkModeToState(context)==PowerButton.STATE_DISABLED; + } + +} diff --git a/services/java/com/android/server/status/widget/PowerButton.java b/services/java/com/android/server/status/widget/PowerButton.java new file mode 100644 index 0000000..0e61bda --- /dev/null +++ b/services/java/com/android/server/status/widget/PowerButton.java @@ -0,0 +1,135 @@ +package com.android.server.status.widget; + +import com.android.internal.R; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.graphics.PorterDuff.Mode; +import android.widget.ImageView; +import android.widget.RemoteViews; +import android.widget.LinearLayout; +import android.util.Log; +import android.provider.Settings; +import android.view.View; + +import com.android.server.status.ExpandedView; + +public abstract class PowerButton { + public static final String TOGGLE_WIFI = "toggleWifi"; + public static final String TOGGLE_GPS = "toggleGPS"; + public static final String TOGGLE_BLUETOOTH = "toggleBluetooth"; + public static final String TOGGLE_BRIGHTNESS = "toggleBrightness"; + public static final String TOGGLE_SOUND = "toggleSound"; + public static final String TOGGLE_SYNC = "toggleSync"; + public static final String TOGGLE_WIFIAP = "toggleWifiAp"; + public static final String TOGGLE_SCREENTIMEOUT = "toggleScreenTimeout"; + public static final String TOGGLE_MOBILEDATA = "toggleMobileData"; + public static final String TOGGLE_LOCKSCREEN = "toggleLockScreen"; + public static final String TOGGLE_NETWORKMODE = "toggleNetworkMode"; + public static final String TOGGLE_AUTOROTATE = "toggleAutoRotate"; + public static final String TOGGLE_FLASHLIGHT = "toggleFlashlight"; + public static final String TOGGLE_AIRPLANE = "toggleAirplane"; + + private Mode expPDMode = Mode.SCREEN; + public static final int STATE_ENABLED = 1; + public static final int STATE_DISABLED = 2; + public static final int STATE_TURNING_ON = 3; + public static final int STATE_TURNING_OFF = 4; + public static final int STATE_INTERMEDIATE = 5; + public static final int STATE_UNKNOWN = 6; + + public int currentIcon; + public int currentState; + public int currentPosition; + + abstract void initButton(int position); + abstract public void toggleState(Context context); + public abstract void updateState(Context context); + + public void setupButton(int position) { + currentPosition = position; + } + + public void updateView(Context context, ExpandedView views) { + if(currentPosition > 0) { + Resources res = context.getResources(); + int buttonLayer = getLayoutID(currentPosition); + int buttonIcon = getImageID(currentPosition); + int buttonState = getStatusInd(currentPosition); + + views.findViewById(buttonLayer).setVisibility(View.VISIBLE); + + updateImageView(views, buttonIcon, currentIcon); + + /* Button State */ + int sColorMaskBase = Settings.System.getInt(context.getContentResolver(), + Settings.System.EXPANDED_VIEW_WIDGET_COLOR, 0xFF00EFFF); + int sColorMaskOn = (sColorMaskBase & 0x00FFFFFF) | 0xA0000000; + int sColorMaskOff = (sColorMaskBase & 0x00FFFFFF) | 0x33000000; + int sColorMaskInter = (sColorMaskBase & 0x00FFFFFF) | 0x60000000; + + switch(currentState) { + case STATE_ENABLED: + updateImageView(views, buttonState, + res.getDrawable(com.android.internal.R.drawable.stat_bgon_custom, sColorMaskOn, expPDMode)); + break; + case STATE_DISABLED: + updateImageView(views, buttonState, + res.getDrawable(com.android.internal.R.drawable.stat_bgon_custom, sColorMaskOff, expPDMode)); + break; + default: + updateImageView(views, buttonState, + res.getDrawable(com.android.internal.R.drawable.stat_bgon_custom, sColorMaskInter, expPDMode)); + break; + } + } + } + + private void updateImageView(ExpandedView view, int id, int resId) { + ImageView imageIcon = (ImageView)view.findViewById(id); + imageIcon.setImageResource(resId); + } + private void updateImageView(ExpandedView view, int id, Drawable resDraw) { + ImageView statusInd = (ImageView)view.findViewById(id); + statusInd.setImageResource(com.android.internal.R.drawable.stat_bgon_custom); + statusInd.setImageDrawable(resDraw); + } + + public static int getLayoutID(int posi) { + switch(posi) { + case 1: return R.id.exp_power_stat_1; + case 2: return R.id.exp_power_stat_2; + case 3: return R.id.exp_power_stat_3; + case 4: return R.id.exp_power_stat_4; + case 5: return R.id.exp_power_stat_5; + case 6: return R.id.exp_power_stat_6; + } + return 0; + } + + private int getImageID(int posi) { + switch(posi) { + case 1: return R.id.exp_power_image_1; + case 2: return R.id.exp_power_image_2; + case 3: return R.id.exp_power_image_3; + case 4: return R.id.exp_power_image_4; + case 5: return R.id.exp_power_image_5; + case 6: return R.id.exp_power_image_6; + } + return 0; + } + + private int getStatusInd(int posi) { + switch(posi) { + case 1: return R.id.exp_power_indic_1; + case 2: return R.id.exp_power_indic_2; + case 3: return R.id.exp_power_indic_3; + case 4: return R.id.exp_power_indic_4; + case 5: return R.id.exp_power_indic_5; + case 6: return R.id.exp_power_indic_6; + } + return 0; + } +} diff --git a/services/java/com/android/server/status/widget/ScreenTimeoutButton.java b/services/java/com/android/server/status/widget/ScreenTimeoutButton.java new file mode 100755 index 0000000..c64e4fb --- /dev/null +++ b/services/java/com/android/server/status/widget/ScreenTimeoutButton.java @@ -0,0 +1,104 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; +import com.android.server.status.widget.StateTracker; + +import android.content.Context; +import android.content.SharedPreferences; +import android.provider.Settings; + +public class ScreenTimeoutButton extends PowerButton { + + public static final int SCREEN_MINIMUM_TIMEOUT = 15000; + public static final int SCREEN_LOW_TIMEOUT = 30000; + public static final int SCREEN_NORMAL_TIMEOUT = 60000; + public static final int SCREEN_HI_TIMEOUT = 120000; + public static final int SCREEN_MAX_TIMEOUT = 300000; + + + private static final int MODE_15_60_300 = 0; + private static final int MODE_30_120_300 = 1; + + private static final int DEFAULT_SETTING = 0; + + static ScreenTimeoutButton ownButton = null; + + private int currentMode; + + public static int getScreenTtimeout(Context context) { + return Settings.System.getInt( + context.getContentResolver(), + Settings.System.SCREEN_OFF_TIMEOUT, 0); + } + + + public void toggleState(Context context) { + int screentimeout = getScreenTtimeout(context); + if (screentimeout < SCREEN_MINIMUM_TIMEOUT) { + if (currentMode == MODE_15_60_300) { + screentimeout = SCREEN_MINIMUM_TIMEOUT; + } else { + screentimeout = SCREEN_LOW_TIMEOUT; + } + } else if (screentimeout < SCREEN_LOW_TIMEOUT) { + if (currentMode == MODE_15_60_300) { + screentimeout = SCREEN_NORMAL_TIMEOUT; + } else { + screentimeout = SCREEN_LOW_TIMEOUT; + } + } else if (screentimeout < SCREEN_NORMAL_TIMEOUT) { + if (currentMode == MODE_15_60_300) { + screentimeout = SCREEN_NORMAL_TIMEOUT; + } else { + screentimeout = SCREEN_HI_TIMEOUT; + } + } else if (screentimeout < SCREEN_HI_TIMEOUT) { + if (currentMode == MODE_15_60_300) { + screentimeout = SCREEN_MAX_TIMEOUT; + } else { + screentimeout=SCREEN_HI_TIMEOUT; + } + } else if (screentimeout < SCREEN_MAX_TIMEOUT) { + screentimeout = SCREEN_MAX_TIMEOUT; + } else if (currentMode == MODE_30_120_300) { + screentimeout = SCREEN_LOW_TIMEOUT; + } else { + screentimeout = SCREEN_MINIMUM_TIMEOUT; + } + Settings.System.putInt( + context.getContentResolver(), + Settings.System.SCREEN_OFF_TIMEOUT, screentimeout); + } + + public static ScreenTimeoutButton getInstance() { + if (ownButton == null) ownButton = new ScreenTimeoutButton(); + return ownButton; + } + + @Override + void initButton(int position) { + } + + @Override + public void updateState(Context context) { + + currentMode = Settings.System.getInt(context.getContentResolver(), + Settings.System.EXPANDED_SCREENTIMEOUT_MODE, DEFAULT_SETTING); + + int timeout=getScreenTtimeout(context); + //TODO: ADD support for the possible values + if (timeout <= SCREEN_LOW_TIMEOUT) { + currentIcon = R.drawable.stat_screen_timeout_off; + currentState = PowerButton.STATE_DISABLED; + } else if (timeout <= SCREEN_HI_TIMEOUT) { + currentIcon = R.drawable.stat_screen_timeout_off; + currentState = PowerButton.STATE_INTERMEDIATE; + } else { + currentIcon = R.drawable.stat_screen_timeout_on; + currentState = PowerButton.STATE_ENABLED; + } + } +} + + diff --git a/services/java/com/android/server/status/widget/SoundButton.java b/services/java/com/android/server/status/widget/SoundButton.java new file mode 100755 index 0000000..bd96bd7 --- /dev/null +++ b/services/java/com/android/server/status/widget/SoundButton.java @@ -0,0 +1,220 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; + +import android.content.Context; +import android.content.SharedPreferences; +import android.media.AudioManager; +import android.provider.Settings; + +public class SoundButton extends PowerButton { + + static SoundButton ownButton = null; + + public static final int RINGER_MODE_UNKNOWN = 0; + public static final int RINGER_MODE_SILENT = 1; + public static final int RINGER_MODE_VIBRATE_ONLY = 2; + public static final int RINGER_MODE_SOUND_ONLY = 3; + public static final int RINGER_MODE_SOUND_AND_VIBRATE = 4; + + public static final int MODE_SOUNDVIB_VIB = 0; + public static final int MODE_SOUND_VIB = 1; + public static final int MODE_SOUND_SILENT = 2; + public static final int MODE_SOUNDVIB_VIB_SILENT = 3; + public static final int MODE_SOUND_VIB_SILENT = 4; + + private static final int DEFAULT_SETTING = 0; + private static int currentMode; + + private static int getSoundState(Context context) { + AudioManager mAudioManager = (AudioManager) context + .getSystemService(Context.AUDIO_SERVICE); + + int ringMode = mAudioManager.getRingerMode(); + int vibrateMode = mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER); + + if (ringMode == AudioManager.RINGER_MODE_NORMAL && vibrateMode == AudioManager.VIBRATE_SETTING_ON) { + return RINGER_MODE_SOUND_AND_VIBRATE; + } else if (ringMode == AudioManager.RINGER_MODE_NORMAL) { + return RINGER_MODE_SOUND_ONLY; + } else if (ringMode == AudioManager.RINGER_MODE_VIBRATE) { + return RINGER_MODE_VIBRATE_ONLY; + } else if (ringMode == AudioManager.RINGER_MODE_SILENT) { + return RINGER_MODE_SILENT; + } + return RINGER_MODE_UNKNOWN; + } + + /** + * Toggles the state of 2G3G. + * + * @param context + */ + public void toggleState(Context context) { + int currentMode = getSoundState(context); + AudioManager mAudioManager = (AudioManager) context + .getSystemService(Context.AUDIO_SERVICE); + + switch (currentMode) { + case RINGER_MODE_SOUND_AND_VIBRATE: + if(supports(RINGER_MODE_SOUND_ONLY)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager. + setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + } else if(supports(RINGER_MODE_VIBRATE_ONLY)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager. + setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + } else if(supports(RINGER_MODE_SILENT)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,0); + mAudioManager. + setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT); + } else { //Fall Back + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager. + setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + } + break; + case RINGER_MODE_SOUND_ONLY: + if(supports(RINGER_MODE_VIBRATE_ONLY)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager. + setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + } else if(supports(RINGER_MODE_SILENT)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,0); + mAudioManager. + setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT); + } else if(supports(RINGER_MODE_SOUND_AND_VIBRATE)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager. + setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + } else { //Fall back + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager. + setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON); + } + break; + + case RINGER_MODE_VIBRATE_ONLY: + if(supports(RINGER_MODE_SILENT)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,0); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF); + } else if(supports(RINGER_MODE_SOUND_AND_VIBRATE)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON); + } else if(supports(RINGER_MODE_SOUND_ONLY)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT); + } else { //Fall Back + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON); + } + break; + case RINGER_MODE_SILENT: + if(supports(RINGER_MODE_SOUND_AND_VIBRATE)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON); + } else if(supports(RINGER_MODE_SOUND_ONLY)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT); + } else if(supports(RINGER_MODE_VIBRATE_ONLY)) { + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT); + } else { //Fall Back + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON); + } + break; + default: + Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1); + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON); + + } + } + + private boolean supports(int ringerMode) { + switch (ringerMode) { + case RINGER_MODE_SILENT: + if (currentMode == MODE_SOUND_SILENT || + currentMode == MODE_SOUNDVIB_VIB_SILENT || + currentMode == MODE_SOUND_VIB_SILENT) + return true; + break; + case RINGER_MODE_VIBRATE_ONLY: + if (currentMode == MODE_SOUND_VIB || + currentMode == MODE_SOUNDVIB_VIB || + currentMode == MODE_SOUNDVIB_VIB_SILENT || + currentMode == MODE_SOUND_VIB_SILENT) + return true; + break; + case RINGER_MODE_SOUND_ONLY: + if (currentMode == MODE_SOUND_VIB || + currentMode == MODE_SOUND_SILENT || + currentMode == MODE_SOUND_VIB_SILENT) + return true; + break; + case RINGER_MODE_SOUND_AND_VIBRATE: + if (currentMode == MODE_SOUNDVIB_VIB || + currentMode == MODE_SOUNDVIB_VIB_SILENT) + return true; + } + + return false; + } + + public static SoundButton getInstance() { + if (ownButton == null) + ownButton = new SoundButton(); + + return ownButton; + } + + @Override + void initButton(int position) { + } + + @Override + public void updateState(Context context) { + int soundState = getSoundState(context); + currentMode = Settings.System.getInt(context.getContentResolver(), + Settings.System.EXPANDED_RING_MODE, DEFAULT_SETTING); + + switch (soundState) { + case RINGER_MODE_SOUND_AND_VIBRATE: + currentIcon = R.drawable.stat_ring_on; + currentState = PowerButton.STATE_ENABLED; + break; + case RINGER_MODE_SOUND_ONLY: + currentIcon = R.drawable.stat_ring_on; + currentState = PowerButton.STATE_INTERMEDIATE; + break; + case RINGER_MODE_VIBRATE_ONLY: + currentIcon = R.drawable.stat_vibrate_off; + currentState = PowerButton.STATE_DISABLED; + break; + case RINGER_MODE_SILENT: + currentIcon = R.drawable.stat_silent; + currentState = PowerButton.STATE_DISABLED; + break; + + } + } +} diff --git a/services/java/com/android/server/status/widget/StateTracker.java b/services/java/com/android/server/status/widget/StateTracker.java new file mode 100644 index 0000000..fd476b6 --- /dev/null +++ b/services/java/com/android/server/status/widget/StateTracker.java @@ -0,0 +1,160 @@ +package com.android.server.status.widget; + +import com.android.server.status.widget.PowerButton; +import android.content.Context; +import android.content.Intent; +import android.util.Log; + + +/** + * The state machine for Wifi and Bluetooth toggling, tracking reality + * versus the user's intent. + * + * This is necessary because reality moves relatively slowly (turning on + * & off radio drivers), compared to user's expectations. + */ +public abstract class StateTracker { + // Is the state in the process of changing? + private boolean mInTransition = false; + private Boolean mActualState = null; // initially not set + private Boolean mIntendedState = null; // initially not set + + // Did a toggle request arrive while a state update was + // already in-flight? If so, the mIntendedState needs to be + // requested when the other one is done, unless we happened to + // arrive at that state already. + private boolean mDeferredStateChangeRequestNeeded = false; + + /** + * User pressed a button to change the state. Something should + * immediately appear to the user afterwards, even if we effectively do + * nothing. Their press must be heard. + */ + public final void toggleState(Context context) { + int currentState = getTriState(context); + boolean newState = false; + switch (currentState) { + case PowerButton.STATE_ENABLED: + newState = false; + break; + case PowerButton.STATE_DISABLED: + newState = true; + break; + case PowerButton.STATE_INTERMEDIATE: + if (mIntendedState != null) { + newState = !mIntendedState; + } + break; + } + mIntendedState = newState; + if (mInTransition) { + // We don't send off a transition request if we're + // already transitioning. Makes our state tracking + // easier, and is probably nicer on lower levels. + // (even though they should be able to take it...) + mDeferredStateChangeRequestNeeded = true; + } else { + mInTransition = true; + requestStateChange(context, newState); + } + } + + /** + * Update internal state from a broadcast state change. + */ + public abstract void onActualStateChange(Context context, Intent intent); + + /** + * Sets the value that we're now in. To be called from + * onActualStateChange. + * + * @param newState + * one of STATE_DISABLED, STATE_ENABLED, STATE_TURNING_ON, + * STATE_TURNING_OFF, STATE_UNKNOWN + */ + protected final void setCurrentState(Context context, int newState) { + final boolean wasInTransition = mInTransition; + switch (newState) { + case PowerButton.STATE_DISABLED: + mInTransition = false; + mActualState = false; + break; + case PowerButton.STATE_ENABLED: + mInTransition = false; + mActualState = true; + break; + case PowerButton.STATE_TURNING_ON: + mInTransition = true; + mActualState = false; + break; + case PowerButton.STATE_TURNING_OFF: + mInTransition = true; + mActualState = true; + break; + } + + if (wasInTransition && !mInTransition) { + if (mDeferredStateChangeRequestNeeded) { + Log.v("StateTracker", "processing deferred state change"); + if (mActualState != null && mIntendedState != null + && mIntendedState.equals(mActualState)) { + Log.v("StateTracker", "... but intended state matches, so no changes."); + } else if (mIntendedState != null) { + mInTransition = true; + requestStateChange(context, mIntendedState); + } + mDeferredStateChangeRequestNeeded = false; + } + } + } + + /** + * If we're in a transition mode, this returns true if we're + * transitioning towards being enabled. + */ + public final boolean isTurningOn() { + return mIntendedState != null && mIntendedState; + } + + /** + * Returns simplified 3-state value from underlying 5-state. + * + * @param context + * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE + */ + public final int getTriState(Context context) { + /*if (mInTransition) { + // If we know we just got a toggle request recently + // (which set mInTransition), don't even ask the + // underlying interface for its state. We know we're + // changing. This avoids blocking the UI thread + // during UI refresh post-toggle if the underlying + // service state accessor has coarse locking on its + // state (to be fixed separately). + return PowerButton.STATE_INTERMEDIATE; + }*/ + switch (getActualState(context)) { + case PowerButton.STATE_DISABLED: + return PowerButton.STATE_DISABLED; + case PowerButton.STATE_ENABLED: + return PowerButton.STATE_ENABLED; + default: + return PowerButton.STATE_INTERMEDIATE; + } + } + + /** + * Gets underlying actual state. + * + * @param context + * @return STATE_ENABLED, STATE_DISABLED, STATE_ENABLING, + * STATE_DISABLING, or or STATE_UNKNOWN. + */ + public abstract int getActualState(Context context); + + /** + * Actually make the desired change to the underlying radio API. + */ + protected abstract void requestStateChange(Context context, + boolean desiredState); +} diff --git a/services/java/com/android/server/status/widget/SyncButton.java b/services/java/com/android/server/status/widget/SyncButton.java new file mode 100755 index 0000000..f7de226 --- /dev/null +++ b/services/java/com/android/server/status/widget/SyncButton.java @@ -0,0 +1,104 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.SharedPreferences; +import android.net.ConnectivityManager; + +public class SyncButton extends PowerButton { + + static SyncButton ownButton=null; + + /** + * Toggle auto-sync + * + * @param context + */ + public void toggleState(Context context) { + ConnectivityManager connManager = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + boolean backgroundData = getBackgroundDataState(context); + boolean sync = ContentResolver.getMasterSyncAutomatically(); + + // four cases to handle: + // setting toggled from off to on: + // 1. background data was off, sync was off: turn on both + if (!backgroundData && !sync) { + connManager.setBackgroundDataSetting(true); + ContentResolver.setMasterSyncAutomatically(true); + } + + // 2. background data was off, sync was on: turn on background data + if (!backgroundData && sync) { + connManager.setBackgroundDataSetting(true); + } + + // 3. background data was on, sync was off: turn on sync + if (backgroundData && !sync) { + ContentResolver.setMasterSyncAutomatically(true); + } + + // setting toggled from on to off: + // 4. background data was on, sync was on: turn off sync + if (backgroundData && sync) { + ContentResolver.setMasterSyncAutomatically(false); + } + } + + public void toggleState(Context context, int newState) { + if(getSync(context) && newState==PowerButton.STATE_DISABLED) { + toggleState(context); + } else if(!getSync(context) && newState==PowerButton.STATE_ENABLED) { + toggleState(context); + } + } + + /** + * Gets the state of background data. + * + * @param context + * @return true if enabled + */ + private static boolean getBackgroundDataState(Context context) { + ConnectivityManager connManager = (ConnectivityManager) context + .getSystemService(Context.CONNECTIVITY_SERVICE); + return connManager.getBackgroundDataSetting(); + } + + /** + * Gets the state of auto-sync. + * + * @param context + * @return true if enabled + */ + private static boolean getSync(Context context) { + boolean backgroundData = getBackgroundDataState(context); + boolean sync = ContentResolver.getMasterSyncAutomatically(); + return backgroundData && sync; + } + + + + public void updateState(Context context) { + if (getSync(context)) { + currentIcon = R.drawable.stat_sync_on; + currentState = PowerButton.STATE_ENABLED; + } else { + currentIcon = R.drawable.stat_sync_off; + currentState = PowerButton.STATE_DISABLED; + } + } + + public static SyncButton getInstance() { + if (ownButton == null) ownButton = new SyncButton(); + return ownButton; + } + + @Override + void initButton(int poisition) { + } + +} diff --git a/services/java/com/android/server/status/widget/WifiApButton.java b/services/java/com/android/server/status/widget/WifiApButton.java new file mode 100755 index 0000000..d0b7394 --- /dev/null +++ b/services/java/com/android/server/status/widget/WifiApButton.java @@ -0,0 +1,152 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; +import com.android.server.status.widget.StateTracker; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.wifi.WifiManager; +import android.os.AsyncTask; +import android.util.Log; + +public class WifiApButton extends PowerButton { + + static WifiApButton ownButton = null; + + + private static final StateTracker sWifiApState = new WifiApStateTracker(); + + /** + * Subclass of StateTracker to get/set Wifi AP state. + */ + private static final class WifiApStateTracker extends StateTracker { + @Override + public int getActualState(Context context) { + WifiManager wifiManager = (WifiManager) context + .getSystemService(Context.WIFI_SERVICE); + if (wifiManager != null) { + return wifiApStateToFiveState(wifiManager.getWifiApState()); + } + return PowerButton.STATE_UNKNOWN; + } + + @Override + protected void requestStateChange(Context context, + final boolean desiredState) { + + final WifiManager wifiManager = (WifiManager) context + .getSystemService(Context.WIFI_SERVICE); + if (wifiManager == null) { + Log.d("WifiAPManager", "No wifiManager."); + return; + } + Log.i("WifiAp", "Setting: " + desiredState); + + // Actually request the Wi-Fi AP change and persistent + // settings write off the UI thread, as it can take a + // user-noticeable amount of time, especially if there's + // disk contention. + new AsyncTask<Void, Void, Void>() { + @Override + protected Void doInBackground(Void... args) { + /** + * Disable Wif if enabling tethering + */ + int wifiState = wifiManager.getWifiState(); + if (desiredState + && ((wifiState == WifiManager.WIFI_STATE_ENABLING) || (wifiState == WifiManager.WIFI_STATE_ENABLED))) { + wifiManager.setWifiEnabled(false); + } + + wifiManager.setWifiApEnabled(null, desiredState); + Log.i("WifiAp", "Async Setting: " + desiredState); + return null; + } + }.execute(); + } + + @Override + public void onActualStateChange(Context context, Intent intent) { + + if (!WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent + .getAction())) { + return; + } + int wifiState = intent + .getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, -1); + int widgetState=wifiApStateToFiveState(wifiState); + setCurrentState(context, widgetState); + } + + /** + * Converts WifiManager's state values into our Wifi/WifiAP/Bluetooth-common + * state values. + */ + private static int wifiApStateToFiveState(int wifiState) { + switch (wifiState) { + case WifiManager.WIFI_AP_STATE_DISABLED: + return PowerButton.STATE_DISABLED; + case WifiManager.WIFI_AP_STATE_ENABLED: + return PowerButton.STATE_ENABLED; + case WifiManager.WIFI_AP_STATE_DISABLING: + return PowerButton.STATE_TURNING_OFF; + case WifiManager.WIFI_AP_STATE_ENABLING: + return PowerButton.STATE_TURNING_ON; + default: + return PowerButton.STATE_UNKNOWN; + } + } + } + + + + public void updateState(Context context) { + + currentState = sWifiApState.getTriState(context); + switch (currentState) { + case PowerButton.STATE_DISABLED: + currentIcon = R.drawable.stat_wifi_ap_off; + break; + case PowerButton.STATE_ENABLED: + currentIcon = R.drawable.stat_wifi_ap_on; + break; + case PowerButton.STATE_INTERMEDIATE: + // In the transitional state, the bottom green bar + // shows the tri-state (on, off, transitioning), but + // the top dark-gray-or-bright-white logo shows the + // user's intent. This is much easier to see in + // sunlight. + if (sWifiApState.isTurningOn()) { + currentIcon = R.drawable.stat_wifi_ap_on; + } else { + currentIcon = R.drawable.stat_wifi_ap_off; + } + break; + } + } + + + public void onReceive(Context context, Intent intent) { + sWifiApState.onActualStateChange(context, intent); + } + + + public void toggleState(Context context) { + sWifiApState.toggleState(context); + } + + + public static WifiApButton getInstance() { + if (ownButton == null) { + ownButton = new WifiApButton(); + } + + return ownButton; + } + + @Override + void initButton(int position) { + } +} diff --git a/services/java/com/android/server/status/widget/WifiButton.java b/services/java/com/android/server/status/widget/WifiButton.java new file mode 100644 index 0000000..bb89b6a --- /dev/null +++ b/services/java/com/android/server/status/widget/WifiButton.java @@ -0,0 +1,159 @@ +package com.android.server.status.widget; + +import com.android.internal.R; +import com.android.server.status.widget.PowerButton; +import com.android.server.status.widget.StateTracker; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.WifiManager; +import android.os.AsyncTask; +import android.util.Log; + +public class WifiButton extends PowerButton{ + + static WifiButton ownButton = null; + + private static final StateTracker sWifiState = new WifiStateTracker(); + + public void setupButton(Context context, int position) { + currentPosition = position; + } + + /** + * Subclass of StateTracker to get/set Wifi state. + */ + private static final class WifiStateTracker extends StateTracker { + @Override + public int getActualState(Context context) { + WifiManager wifiManager = (WifiManager) context + .getSystemService(Context.WIFI_SERVICE); + if (wifiManager != null) { + return wifiStateToFiveState(wifiManager.getWifiState()); + } + return STATE_UNKNOWN; + } + + @Override + protected void requestStateChange(Context context, + final boolean desiredState) { + final WifiManager wifiManager = (WifiManager) context + .getSystemService(Context.WIFI_SERVICE); + if (wifiManager == null) { + Log.d("WifiButton", "No wifiManager."); + return; + } + + // Actually request the wifi change and persistent + // settings write off the UI thread, as it can take a + // user-noticeable amount of time, especially if there's + // disk contention. + new AsyncTask<Void, Void, Void>() { + @Override + protected Void doInBackground(Void... args) { + /** + * Disable tethering if enabling Wifi + */ + int wifiApState = wifiManager.getWifiApState(); + if (desiredState + && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) || (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) { + wifiManager.setWifiApEnabled(null, false); + } + + wifiManager.setWifiEnabled(desiredState); + return null; + } + }.execute(); + } + + @Override + public void onActualStateChange(Context context, Intent intent) { + if (!WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent + .getAction())) { + return; + } + int wifiState = intent + .getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1); + int widgetState=wifiStateToFiveState(wifiState); + setCurrentState(context, widgetState); + } + + /** + * Converts WifiManager's state values into our Wifi/Bluetooth-common + * state values. + */ + private static int wifiStateToFiveState(int wifiState) { + switch (wifiState) { + case WifiManager.WIFI_STATE_DISABLED: + return STATE_DISABLED; + case WifiManager.WIFI_STATE_ENABLED: + return STATE_ENABLED; + case WifiManager.WIFI_STATE_DISABLING: + return STATE_TURNING_OFF; + case WifiManager.WIFI_STATE_ENABLING: + return STATE_TURNING_ON; + default: + return STATE_UNKNOWN; + } + } + } + + + + public void updateState(Context context) { + currentState = sWifiState.getTriState(context); + switch (currentState) { + case STATE_DISABLED: + currentIcon = com.android.internal.R.drawable.stat_wifi_off; + break; + case STATE_ENABLED: + currentIcon = com.android.internal.R.drawable.stat_wifi_on; + break; + case STATE_INTERMEDIATE: + // In the transitional state, the bottom green bar + // shows the tri-state (on, off, transitioning), but + // the top dark-gray-or-bright-white logo shows the + // user's intent. This is much easier to see in + // sunlight. + if (sWifiState.isTurningOn()) { + currentIcon = com.android.internal.R.drawable.stat_wifi_on; + } else { + currentIcon = com.android.internal.R.drawable.stat_wifi_off; + } + break; + } + } + + public void onReceive(Context context, Intent intent) { + sWifiState.onActualStateChange(context, intent); + } + + public void toggleState(Context context) { + int realstate = sWifiState.getActualState(context); + sWifiState.toggleState(context); + } + + + public static WifiButton getInstance() { + if (ownButton == null) { + ownButton = new WifiButton(); + } + + return ownButton; + } + + @Override + void initButton(int position) { + } + + public void toggleState(Context context, int newState) { + int curState = sWifiState.getTriState(context); + if (curState != STATE_INTERMEDIATE && + curState != newState) { + toggleState(context); + } + } +} |