Loading src/com/android/settings/widget/SettingsAppWidgetProvider.java +343 −101 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { new ComponentName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); private static LocalBluetoothManager mLocalBluetoothManager = null; private static LocalBluetoothManager sLocalBluetoothManager = null; private static final int BUTTON_WIFI = 0; private static final int BUTTON_BRIGHTNESS = 1; Loading @@ -58,9 +58,16 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { private static final int BUTTON_GPS = 3; private static final int BUTTON_BLUETOOTH = 4; // This widget keeps track of two sets of states: // "3-state": STATE_DISABLED, STATE_ENABLED, STATE_INTERMEDIATE // "5-state": STATE_DISABLED, STATE_ENABLED, STATE_TURNING_ON, STATE_TURNING_OFF, STATE_UNKNOWN private static final int STATE_DISABLED = 0; private static final int STATE_ENABLED = 1; private static final int STATE_INTERMEDIATE = 2; private static final int STATE_TURNING_ON = 2; private static final int STATE_TURNING_OFF = 3; private static final int STATE_UNKNOWN = 4; private static final int STATE_INTERMEDIATE = 5; /** * Minimum and maximum brightnesses. Don't go to 0 since that makes the display unusable Loading @@ -69,6 +76,270 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON; private static final int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f); private static final StateTracker sWifiState = new WifiStateTracker(); private static final StateTracker sBluetoothState = new BluetoothStateTracker(); /** * 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. */ private abstract static 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 STATE_ENABLED: newState = false; break; case STATE_DISABLED: newState = true; break; case 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; boolean showToast = newState; // only show Toast on the up transition requestStateChange(context, newState, showToast); } } /** * 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) { boolean wasInTransition = mInTransition; switch (newState) { case STATE_DISABLED: mInTransition = false; mActualState = false; break; case STATE_ENABLED: mInTransition = false; mActualState = true; break; case STATE_TURNING_ON: mInTransition = true; mActualState = false; break; case STATE_TURNING_OFF: mInTransition = true; mActualState = true; break; } if (wasInTransition && !mInTransition) { if (mDeferredStateChangeRequestNeeded) { Log.v(TAG, "processing deferred state change"); if (mActualState != null && mIntendedState != null && mIntendedState.equals(mActualState)) { Log.v(TAG, "... but intended state matches, so no changes."); } else if (mIntendedState != null) { mInTransition = true; requestStateChange(context, mIntendedState, false /* no toast */); } 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) { switch (getActualState(context)) { case STATE_DISABLED: return STATE_DISABLED; case STATE_ENABLED: return STATE_ENABLED; default: return 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, boolean withToast); } /** * 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, boolean desiredState, boolean withToast) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (wifiManager == null) { Log.d(TAG, "No wifiManager."); return; } if (withToast) { Toast.makeText(context, R.string.gadget_toggle_wifi, Toast.LENGTH_SHORT).show(); } wifiManager.setWifiEnabled(desiredState); } @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); setCurrentState(context, wifiStateToFiveState(wifiState)); } /** * 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; } } } /** * Subclass of StateTracker to get/set Bluetooth state. */ private static final class BluetoothStateTracker extends StateTracker { @Override public int getActualState(Context context) { if (sLocalBluetoothManager == null) { sLocalBluetoothManager = LocalBluetoothManager.getInstance(context); if (sLocalBluetoothManager == null) { return STATE_UNKNOWN; // On emulator? } } return bluetoothStateToFiveState(sLocalBluetoothManager.getBluetoothState()); } @Override protected void requestStateChange(Context context, boolean desiredState, boolean withToast) { if (sLocalBluetoothManager == null) { Log.d(TAG, "No LocalBluetoothManager"); return; } if (withToast) { Toast.makeText(context, R.string.gadget_toggle_bluetooth, Toast.LENGTH_SHORT).show(); } sLocalBluetoothManager.setBluetoothEnabled(desiredState); } @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 STATE_DISABLED; case BluetoothAdapter.STATE_ON: return STATE_ENABLED; case BluetoothAdapter.STATE_TURNING_ON: return STATE_TURNING_ON; case BluetoothAdapter.STATE_TURNING_OFF: return STATE_TURNING_OFF; default: return STATE_UNKNOWN; } } } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { Loading Loading @@ -142,29 +413,53 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { * @param context */ private static void updateButtons(RemoteViews views, Context context) { switch (getWifiState(context)) { switch (sWifiState.getTriState(context)) { case STATE_DISABLED: views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_off); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_off_l); views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_off); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_off_l); break; case STATE_ENABLED: views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_on); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_on_l); views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_on); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_on_l); break; case STATE_INTERMEDIATE: views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_off); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_mid_l); // 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()) { views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_on); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_mid_l); } else { views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_off); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_off_l); } break; } if (getBrightnessMode(context)) { views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_auto); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_on_r); views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_auto); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_on_r); } else if (getBrightness(context)) { views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_on); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_on_r); views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_on); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_on_r); } else { views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_off); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_off_r); views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_off); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_off_r); } if (getSync(context)) { views.setImageViewResource(R.id.img_sync, R.drawable.ic_appwidget_settings_sync_on); Loading @@ -180,18 +475,36 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { views.setImageViewResource(R.id.img_gps, R.drawable.ic_appwidget_settings_gps_off); views.setImageViewResource(R.id.ind_gps, R.drawable.appwidget_settings_ind_off_c); } switch (getBluetoothState(context)) { switch (sBluetoothState.getTriState(context)) { case STATE_DISABLED: views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_off); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_off_c); views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_off); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_off_c); break; case STATE_ENABLED: views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_on); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_on_c); views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_on); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_on_c); break; case STATE_INTERMEDIATE: views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_off); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_mid_c); // 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()) { views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_on); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_mid_c); } else { views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_off); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_off_c); } break; } } Loading Loading @@ -223,11 +536,15 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) { if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) { sWifiState.onActualStateChange(context, intent); } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) { sBluetoothState.onActualStateChange(context, intent); } else if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) { Uri data = intent.getData(); int buttonId = Integer.parseInt(data.getSchemeSpecificPart()); if (buttonId == BUTTON_WIFI) { toggleWifi(context); sWifiState.toggleState(context); } else if (buttonId == BUTTON_BRIGHTNESS) { toggleBrightness(context); } else if (buttonId == BUTTON_SYNC) { Loading @@ -235,49 +552,14 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { } else if (buttonId == BUTTON_GPS) { toggleGps(context); } else if (buttonId == BUTTON_BLUETOOTH) { toggleBluetooth(context); sBluetoothState.toggleState(context); } } // State changes fall through updateWidget(context); } /** * Gets the state of Wi-Fi * * @param context * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE */ private static int getWifiState(Context context) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); int wifiState = wifiManager.getWifiState(); if (wifiState == WifiManager.WIFI_STATE_DISABLED) { return STATE_DISABLED; } else if (wifiState == WifiManager.WIFI_STATE_ENABLED) { return STATE_ENABLED; } else { return STATE_INTERMEDIATE; } } /** * Toggles the state of Wi-Fi * * @param context */ private void toggleWifi(Context context) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); int wifiState = getWifiState(context); if (wifiState == STATE_ENABLED) { wifiManager.setWifiEnabled(false); Toast.makeText(context, R.string.gadget_toggle_wifi, Toast.LENGTH_SHORT).show(); } else if (wifiState == STATE_DISABLED) { wifiManager.setWifiEnabled(true); Toast.makeText(context, R.string.gadget_toggle_wifi, Toast.LENGTH_SHORT).show(); } // If wifi is in intermediate state, don't do anything. } /** * Gets the state of background data. * Loading Loading @@ -459,44 +741,4 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { Log.d(TAG, "toggleBrightness: " + e); } } /** * Gets state of bluetooth * * @param context * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE */ private static int getBluetoothState(Context context) { if (mLocalBluetoothManager == null) { mLocalBluetoothManager = LocalBluetoothManager.getInstance(context); if (mLocalBluetoothManager == null) { return STATE_INTERMEDIATE; // On emulator? } } int state = mLocalBluetoothManager.getBluetoothState(); if (state == BluetoothAdapter.STATE_OFF) { return STATE_DISABLED; } else if (state == BluetoothAdapter.STATE_ON) { return STATE_ENABLED; } else { return STATE_INTERMEDIATE; } } /** * Toggles the state of bluetooth * * @param context */ private void toggleBluetooth(Context context) { int state = getBluetoothState(context); if (state == STATE_ENABLED) { mLocalBluetoothManager.setBluetoothEnabled(false); Toast.makeText(context, R.string.gadget_toggle_bluetooth, Toast.LENGTH_SHORT).show(); } else if (state == STATE_DISABLED) { mLocalBluetoothManager.setBluetoothEnabled(true); Toast.makeText(context, R.string.gadget_toggle_bluetooth, Toast.LENGTH_SHORT).show(); } // If bluetooth is in intermediate state, don't do anything. } } Loading
src/com/android/settings/widget/SettingsAppWidgetProvider.java +343 −101 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { new ComponentName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider"); private static LocalBluetoothManager mLocalBluetoothManager = null; private static LocalBluetoothManager sLocalBluetoothManager = null; private static final int BUTTON_WIFI = 0; private static final int BUTTON_BRIGHTNESS = 1; Loading @@ -58,9 +58,16 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { private static final int BUTTON_GPS = 3; private static final int BUTTON_BLUETOOTH = 4; // This widget keeps track of two sets of states: // "3-state": STATE_DISABLED, STATE_ENABLED, STATE_INTERMEDIATE // "5-state": STATE_DISABLED, STATE_ENABLED, STATE_TURNING_ON, STATE_TURNING_OFF, STATE_UNKNOWN private static final int STATE_DISABLED = 0; private static final int STATE_ENABLED = 1; private static final int STATE_INTERMEDIATE = 2; private static final int STATE_TURNING_ON = 2; private static final int STATE_TURNING_OFF = 3; private static final int STATE_UNKNOWN = 4; private static final int STATE_INTERMEDIATE = 5; /** * Minimum and maximum brightnesses. Don't go to 0 since that makes the display unusable Loading @@ -69,6 +76,270 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON; private static final int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f); private static final StateTracker sWifiState = new WifiStateTracker(); private static final StateTracker sBluetoothState = new BluetoothStateTracker(); /** * 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. */ private abstract static 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 STATE_ENABLED: newState = false; break; case STATE_DISABLED: newState = true; break; case 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; boolean showToast = newState; // only show Toast on the up transition requestStateChange(context, newState, showToast); } } /** * 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) { boolean wasInTransition = mInTransition; switch (newState) { case STATE_DISABLED: mInTransition = false; mActualState = false; break; case STATE_ENABLED: mInTransition = false; mActualState = true; break; case STATE_TURNING_ON: mInTransition = true; mActualState = false; break; case STATE_TURNING_OFF: mInTransition = true; mActualState = true; break; } if (wasInTransition && !mInTransition) { if (mDeferredStateChangeRequestNeeded) { Log.v(TAG, "processing deferred state change"); if (mActualState != null && mIntendedState != null && mIntendedState.equals(mActualState)) { Log.v(TAG, "... but intended state matches, so no changes."); } else if (mIntendedState != null) { mInTransition = true; requestStateChange(context, mIntendedState, false /* no toast */); } 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) { switch (getActualState(context)) { case STATE_DISABLED: return STATE_DISABLED; case STATE_ENABLED: return STATE_ENABLED; default: return 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, boolean withToast); } /** * 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, boolean desiredState, boolean withToast) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); if (wifiManager == null) { Log.d(TAG, "No wifiManager."); return; } if (withToast) { Toast.makeText(context, R.string.gadget_toggle_wifi, Toast.LENGTH_SHORT).show(); } wifiManager.setWifiEnabled(desiredState); } @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); setCurrentState(context, wifiStateToFiveState(wifiState)); } /** * 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; } } } /** * Subclass of StateTracker to get/set Bluetooth state. */ private static final class BluetoothStateTracker extends StateTracker { @Override public int getActualState(Context context) { if (sLocalBluetoothManager == null) { sLocalBluetoothManager = LocalBluetoothManager.getInstance(context); if (sLocalBluetoothManager == null) { return STATE_UNKNOWN; // On emulator? } } return bluetoothStateToFiveState(sLocalBluetoothManager.getBluetoothState()); } @Override protected void requestStateChange(Context context, boolean desiredState, boolean withToast) { if (sLocalBluetoothManager == null) { Log.d(TAG, "No LocalBluetoothManager"); return; } if (withToast) { Toast.makeText(context, R.string.gadget_toggle_bluetooth, Toast.LENGTH_SHORT).show(); } sLocalBluetoothManager.setBluetoothEnabled(desiredState); } @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 STATE_DISABLED; case BluetoothAdapter.STATE_ON: return STATE_ENABLED; case BluetoothAdapter.STATE_TURNING_ON: return STATE_TURNING_ON; case BluetoothAdapter.STATE_TURNING_OFF: return STATE_TURNING_OFF; default: return STATE_UNKNOWN; } } } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { Loading Loading @@ -142,29 +413,53 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { * @param context */ private static void updateButtons(RemoteViews views, Context context) { switch (getWifiState(context)) { switch (sWifiState.getTriState(context)) { case STATE_DISABLED: views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_off); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_off_l); views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_off); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_off_l); break; case STATE_ENABLED: views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_on); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_on_l); views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_on); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_on_l); break; case STATE_INTERMEDIATE: views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_off); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_mid_l); // 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()) { views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_on); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_mid_l); } else { views.setImageViewResource(R.id.img_wifi, R.drawable.ic_appwidget_settings_wifi_off); views.setImageViewResource(R.id.ind_wifi, R.drawable.appwidget_settings_ind_off_l); } break; } if (getBrightnessMode(context)) { views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_auto); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_on_r); views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_auto); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_on_r); } else if (getBrightness(context)) { views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_on); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_on_r); views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_on); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_on_r); } else { views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_off); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_off_r); views.setImageViewResource(R.id.img_brightness, R.drawable.ic_appwidget_settings_brightness_off); views.setImageViewResource(R.id.ind_brightness, R.drawable.appwidget_settings_ind_off_r); } if (getSync(context)) { views.setImageViewResource(R.id.img_sync, R.drawable.ic_appwidget_settings_sync_on); Loading @@ -180,18 +475,36 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { views.setImageViewResource(R.id.img_gps, R.drawable.ic_appwidget_settings_gps_off); views.setImageViewResource(R.id.ind_gps, R.drawable.appwidget_settings_ind_off_c); } switch (getBluetoothState(context)) { switch (sBluetoothState.getTriState(context)) { case STATE_DISABLED: views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_off); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_off_c); views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_off); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_off_c); break; case STATE_ENABLED: views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_on); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_on_c); views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_on); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_on_c); break; case STATE_INTERMEDIATE: views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_off); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_mid_c); // 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()) { views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_on); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_mid_c); } else { views.setImageViewResource(R.id.img_bluetooth, R.drawable.ic_appwidget_settings_bluetooth_off); views.setImageViewResource(R.id.ind_bluetooth, R.drawable.appwidget_settings_ind_off_c); } break; } } Loading Loading @@ -223,11 +536,15 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) { if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) { sWifiState.onActualStateChange(context, intent); } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) { sBluetoothState.onActualStateChange(context, intent); } else if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) { Uri data = intent.getData(); int buttonId = Integer.parseInt(data.getSchemeSpecificPart()); if (buttonId == BUTTON_WIFI) { toggleWifi(context); sWifiState.toggleState(context); } else if (buttonId == BUTTON_BRIGHTNESS) { toggleBrightness(context); } else if (buttonId == BUTTON_SYNC) { Loading @@ -235,49 +552,14 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { } else if (buttonId == BUTTON_GPS) { toggleGps(context); } else if (buttonId == BUTTON_BLUETOOTH) { toggleBluetooth(context); sBluetoothState.toggleState(context); } } // State changes fall through updateWidget(context); } /** * Gets the state of Wi-Fi * * @param context * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE */ private static int getWifiState(Context context) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); int wifiState = wifiManager.getWifiState(); if (wifiState == WifiManager.WIFI_STATE_DISABLED) { return STATE_DISABLED; } else if (wifiState == WifiManager.WIFI_STATE_ENABLED) { return STATE_ENABLED; } else { return STATE_INTERMEDIATE; } } /** * Toggles the state of Wi-Fi * * @param context */ private void toggleWifi(Context context) { WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); int wifiState = getWifiState(context); if (wifiState == STATE_ENABLED) { wifiManager.setWifiEnabled(false); Toast.makeText(context, R.string.gadget_toggle_wifi, Toast.LENGTH_SHORT).show(); } else if (wifiState == STATE_DISABLED) { wifiManager.setWifiEnabled(true); Toast.makeText(context, R.string.gadget_toggle_wifi, Toast.LENGTH_SHORT).show(); } // If wifi is in intermediate state, don't do anything. } /** * Gets the state of background data. * Loading Loading @@ -459,44 +741,4 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider { Log.d(TAG, "toggleBrightness: " + e); } } /** * Gets state of bluetooth * * @param context * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE */ private static int getBluetoothState(Context context) { if (mLocalBluetoothManager == null) { mLocalBluetoothManager = LocalBluetoothManager.getInstance(context); if (mLocalBluetoothManager == null) { return STATE_INTERMEDIATE; // On emulator? } } int state = mLocalBluetoothManager.getBluetoothState(); if (state == BluetoothAdapter.STATE_OFF) { return STATE_DISABLED; } else if (state == BluetoothAdapter.STATE_ON) { return STATE_ENABLED; } else { return STATE_INTERMEDIATE; } } /** * Toggles the state of bluetooth * * @param context */ private void toggleBluetooth(Context context) { int state = getBluetoothState(context); if (state == STATE_ENABLED) { mLocalBluetoothManager.setBluetoothEnabled(false); Toast.makeText(context, R.string.gadget_toggle_bluetooth, Toast.LENGTH_SHORT).show(); } else if (state == STATE_DISABLED) { mLocalBluetoothManager.setBluetoothEnabled(true); Toast.makeText(context, R.string.gadget_toggle_bluetooth, Toast.LENGTH_SHORT).show(); } // If bluetooth is in intermediate state, don't do anything. } }