103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff/* 203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Copyright (C) 2009 The Android Open Source Project 303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * 403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Licensed under the Apache License, Version 2.0 (the "License"); 503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * you may not use this file except in compliance with the License. 603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * You may obtain a copy of the License at 703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * 803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * http://www.apache.org/licenses/LICENSE-2.0 903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * 1003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Unless required by applicable law or agreed to in writing, software 1103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * distributed under the License is distributed on an "AS IS" BASIS, 1203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * See the License for the specific language governing permissions and 1403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * limitations under the License. 1503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */ 1603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 1703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffpackage com.android.settings.widget; 1803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 1903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.app.PendingIntent; 2003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.appwidget.AppWidgetManager; 2103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.appwidget.AppWidgetProvider; 22d63c0112251ab4e4e977545368dd703d875012a4Nick Pellyimport android.bluetooth.BluetoothAdapter; 2303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.ComponentName; 2403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.ContentResolver; 2503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.Context; 2603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.content.Intent; 2749c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasaniimport android.database.ContentObserver; 2803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.location.LocationManager; 2903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.net.ConnectivityManager; 3003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.net.Uri; 3103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.net.wifi.WifiManager; 32046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrickimport android.os.AsyncTask; 3349c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasaniimport android.os.Handler; 34cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwoodimport android.os.IPowerManager; 35748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brownimport android.os.PowerManager; 3603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.os.RemoteException; 3703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.os.ServiceManager; 38ea6260d887a7065d65d94be58c05903b3d1fc359Maggie Benthallimport android.os.UserManager; 3903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.provider.Settings; 4003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.util.Log; 4103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport android.widget.RemoteViews; 421d6bf8d46b07cb87d5842324190bc5a31eee5e4bJeff Sharkey 4303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffimport com.android.settings.R; 44f2982a9ba19340b474bafb6b0bf5832673984e0dJason Monkimport com.android.settings.bluetooth.Utils; 45f2982a9ba19340b474bafb6b0bf5832673984e0dJason Monkimport com.android.settingslib.bluetooth.LocalBluetoothAdapter; 46f2982a9ba19340b474bafb6b0bf5832673984e0dJason Monkimport com.android.settingslib.bluetooth.LocalBluetoothManager; 4703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 4803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff/** 4903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Provides control of power-related settings from a widget. 5003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */ 5103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriffpublic class SettingsAppWidgetProvider extends AppWidgetProvider { 5203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff static final String TAG = "SettingsAppWidgetProvider"; 5303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 5403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff static final ComponentName THIS_APPWIDGET = 5503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff new ComponentName("com.android.settings", 5603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff "com.android.settings.widget.SettingsAppWidgetProvider"); 5703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 58436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private static LocalBluetoothAdapter sLocalBluetoothAdapter = null; 5903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 6003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff private static final int BUTTON_WIFI = 0; 6103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff private static final int BUTTON_BRIGHTNESS = 1; 6203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff private static final int BUTTON_SYNC = 2; 63681f79900787c2c40751463ddd8f3476f9b40476David Christie private static final int BUTTON_LOCATION = 3; 6403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff private static final int BUTTON_BLUETOOTH = 4; 6503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 6694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // This widget keeps track of two sets of states: 6794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // "3-state": STATE_DISABLED, STATE_ENABLED, STATE_INTERMEDIATE 6894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // "5-state": STATE_DISABLED, STATE_ENABLED, STATE_TURNING_ON, STATE_TURNING_OFF, STATE_UNKNOWN 6903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff private static final int STATE_DISABLED = 0; 7003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff private static final int STATE_ENABLED = 1; 7194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static final int STATE_TURNING_ON = 2; 7294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static final int STATE_TURNING_OFF = 3; 7394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static final int STATE_UNKNOWN = 4; 7494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static final int STATE_INTERMEDIATE = 5; 7594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 76740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani // Position in the widget bar, to enable different graphics for left, center and right buttons 77740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani private static final int POS_LEFT = 0; 78740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani private static final int POS_CENTER = 1; 79740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani private static final int POS_RIGHT = 2; 80740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani 81740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani private static final int[] IND_DRAWABLE_OFF = { 82a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng R.drawable.appwidget_settings_ind_off_l_holo, 83a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng R.drawable.appwidget_settings_ind_off_c_holo, 84a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng R.drawable.appwidget_settings_ind_off_r_holo 85740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani }; 86740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani 87740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani private static final int[] IND_DRAWABLE_MID = { 88a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng R.drawable.appwidget_settings_ind_mid_l_holo, 89a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng R.drawable.appwidget_settings_ind_mid_c_holo, 90a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng R.drawable.appwidget_settings_ind_mid_r_holo 91740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani }; 92740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani 93740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani private static final int[] IND_DRAWABLE_ON = { 94a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng R.drawable.appwidget_settings_ind_on_l_holo, 95a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng R.drawable.appwidget_settings_ind_on_c_holo, 96a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng R.drawable.appwidget_settings_ind_on_r_holo 97740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani }; 9803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 99a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani /** Minimum brightness at which the indicator is shown at half-full and ON */ 100748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown private static final float HALF_BRIGHTNESS_THRESHOLD = 0.3f; 101a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani /** Minimum brightness at which the indicator is shown at full */ 102748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown private static final float FULL_BRIGHTNESS_THRESHOLD = 0.8f; 10303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 10494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static final StateTracker sWifiState = new WifiStateTracker(); 10594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static final StateTracker sBluetoothState = new BluetoothStateTracker(); 106681f79900787c2c40751463ddd8f3476f9b40476David Christie private static final StateTracker sLocationState = new LocationStateTracker(); 107ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick private static final StateTracker sSyncState = new SyncStateTracker(); 10849c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani private static SettingsObserver sSettingsObserver; 10994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 11094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 111ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick * The state machine for a setting's toggling, tracking reality 112ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick * versus the user's intent. 11394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * 11494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * This is necessary because reality moves relatively slowly 11594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * (turning on & off radio drivers), compared to user's 11694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * expectations. 11794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 11894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private abstract static class StateTracker { 11994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // Is the state in the process of changing? 12094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private boolean mInTransition = false; 12194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private Boolean mActualState = null; // initially not set 12294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private Boolean mIntendedState = null; // initially not set 12394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 12494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // Did a toggle request arrive while a state update was 12594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // already in-flight? If so, the mIntendedState needs to be 12694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // requested when the other one is done, unless we happened to 12794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // arrive at that state already. 12894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private boolean mDeferredStateChangeRequestNeeded = false; 12994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 13094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 13194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * User pressed a button to change the state. Something 13294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * should immediately appear to the user afterwards, even if 13394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * we effectively do nothing. Their press must be heard. 13494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 13594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick public final void toggleState(Context context) { 13694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick int currentState = getTriState(context); 13794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick boolean newState = false; 13894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick switch (currentState) { 13994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case STATE_ENABLED: 14094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick newState = false; 14194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick break; 14294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case STATE_DISABLED: 14394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick newState = true; 14494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick break; 14594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case STATE_INTERMEDIATE: 14694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick if (mIntendedState != null) { 14794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick newState = !mIntendedState; 14894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 14994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick break; 15094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 15194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mIntendedState = newState; 15294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick if (mInTransition) { 15394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // We don't send off a transition request if we're 15494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // already transitioning. Makes our state tracking 15594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // easier, and is probably nicer on lower levels. 15694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick // (even though they should be able to take it...) 15794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mDeferredStateChangeRequestNeeded = true; 15894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } else { 15994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mInTransition = true; 160046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick requestStateChange(context, newState); 16194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 16294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 16394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 16494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 165b9062f26785e53cfc44180e0044c8025ad33af2aalanv * Return the ID of the clickable container for the setting. 166b9062f26785e53cfc44180e0044c8025ad33af2aalanv */ 167b9062f26785e53cfc44180e0044c8025ad33af2aalanv public abstract int getContainerId(); 168b9062f26785e53cfc44180e0044c8025ad33af2aalanv 169b9062f26785e53cfc44180e0044c8025ad33af2aalanv /** 170ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick * Return the ID of the main large image button for the setting. 171ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick */ 172ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public abstract int getButtonId(); 173ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 174ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick /** 175ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick * Returns the small indicator image ID underneath the setting. 176ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick */ 177ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public abstract int getIndicatorId(); 178ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 179ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick /** 180b9062f26785e53cfc44180e0044c8025ad33af2aalanv * Returns the resource ID of the setting's content description. 181b9062f26785e53cfc44180e0044c8025ad33af2aalanv */ 182b9062f26785e53cfc44180e0044c8025ad33af2aalanv public abstract int getButtonDescription(); 183b9062f26785e53cfc44180e0044c8025ad33af2aalanv 184b9062f26785e53cfc44180e0044c8025ad33af2aalanv /** 185ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick * Returns the resource ID of the image to show as a function of 186ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick * the on-vs-off state. 187ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick */ 188ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public abstract int getButtonImageId(boolean on); 189ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 190ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick /** 191740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani * Returns the position in the button bar - either POS_LEFT, POS_RIGHT or POS_CENTER. 192740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani */ 193740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani public int getPosition() { return POS_CENTER; } 194740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani 195740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani /** 196ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick * Updates the remote views depending on the state (off, on, 197ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick * turning off, turning on) of the setting. 198ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick */ 199ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public final void setImageViewResources(Context context, RemoteViews views) { 200b9062f26785e53cfc44180e0044c8025ad33af2aalanv int containerId = getContainerId(); 201ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick int buttonId = getButtonId(); 202ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick int indicatorId = getIndicatorId(); 203740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani int pos = getPosition(); 204ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick switch (getTriState(context)) { 205ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick case STATE_DISABLED: 206b9062f26785e53cfc44180e0044c8025ad33af2aalanv views.setContentDescription(containerId, 207b9062f26785e53cfc44180e0044c8025ad33af2aalanv getContentDescription(context, R.string.gadget_state_off)); 208ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick views.setImageViewResource(buttonId, getButtonImageId(false)); 209ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick views.setImageViewResource( 210740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani indicatorId, IND_DRAWABLE_OFF[pos]); 211ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick break; 212ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick case STATE_ENABLED: 213b9062f26785e53cfc44180e0044c8025ad33af2aalanv views.setContentDescription(containerId, 214b9062f26785e53cfc44180e0044c8025ad33af2aalanv getContentDescription(context, R.string.gadget_state_on)); 215ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick views.setImageViewResource(buttonId, getButtonImageId(true)); 216ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick views.setImageViewResource( 217740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani indicatorId, IND_DRAWABLE_ON[pos]); 218ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick break; 219ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick case STATE_INTERMEDIATE: 220ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick // In the transitional state, the bottom green bar 221ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick // shows the tri-state (on, off, transitioning), but 222ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick // the top dark-gray-or-bright-white logo shows the 223ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick // user's intent. This is much easier to see in 224ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick // sunlight. 225ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick if (isTurningOn()) { 226b9062f26785e53cfc44180e0044c8025ad33af2aalanv views.setContentDescription(containerId, 227b9062f26785e53cfc44180e0044c8025ad33af2aalanv getContentDescription(context, R.string.gadget_state_turning_on)); 228ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick views.setImageViewResource(buttonId, getButtonImageId(true)); 229ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick views.setImageViewResource( 230740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani indicatorId, IND_DRAWABLE_MID[pos]); 231ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } else { 232b9062f26785e53cfc44180e0044c8025ad33af2aalanv views.setContentDescription(containerId, 233b9062f26785e53cfc44180e0044c8025ad33af2aalanv getContentDescription(context, R.string.gadget_state_turning_off)); 234ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick views.setImageViewResource(buttonId, getButtonImageId(false)); 235ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick views.setImageViewResource( 236740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani indicatorId, IND_DRAWABLE_OFF[pos]); 237ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 238ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick break; 239ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 240ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 241ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 242ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick /** 243b9062f26785e53cfc44180e0044c8025ad33af2aalanv * Returns the gadget state template populated with the gadget 244b9062f26785e53cfc44180e0044c8025ad33af2aalanv * description and state. 245b9062f26785e53cfc44180e0044c8025ad33af2aalanv */ 246b9062f26785e53cfc44180e0044c8025ad33af2aalanv private final String getContentDescription(Context context, int stateResId) { 247b9062f26785e53cfc44180e0044c8025ad33af2aalanv final String gadget = context.getString(getButtonDescription()); 248b9062f26785e53cfc44180e0044c8025ad33af2aalanv final String state = context.getString(stateResId); 249b9062f26785e53cfc44180e0044c8025ad33af2aalanv return context.getString(R.string.gadget_state_template, gadget, state); 250b9062f26785e53cfc44180e0044c8025ad33af2aalanv } 251b9062f26785e53cfc44180e0044c8025ad33af2aalanv 252b9062f26785e53cfc44180e0044c8025ad33af2aalanv /** 25394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Update internal state from a broadcast state change. 25494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 25594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick public abstract void onActualStateChange(Context context, Intent intent); 25694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 25794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 25894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Sets the value that we're now in. To be called from onActualStateChange. 25994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * 26094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * @param newState one of STATE_DISABLED, STATE_ENABLED, STATE_TURNING_ON, 26194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * STATE_TURNING_OFF, STATE_UNKNOWN 26294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 26394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick protected final void setCurrentState(Context context, int newState) { 264046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick final boolean wasInTransition = mInTransition; 26594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick switch (newState) { 26694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case STATE_DISABLED: 26794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mInTransition = false; 26894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mActualState = false; 26994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick break; 27094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case STATE_ENABLED: 27194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mInTransition = false; 27294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mActualState = true; 27394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick break; 27494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case STATE_TURNING_ON: 27594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mInTransition = true; 27694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mActualState = false; 27794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick break; 27894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case STATE_TURNING_OFF: 27994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mInTransition = true; 28094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mActualState = true; 28194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick break; 28294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 28394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 28494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick if (wasInTransition && !mInTransition) { 28594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick if (mDeferredStateChangeRequestNeeded) { 28694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick Log.v(TAG, "processing deferred state change"); 28794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick if (mActualState != null && mIntendedState != null && 28894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mIntendedState.equals(mActualState)) { 28994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick Log.v(TAG, "... but intended state matches, so no changes."); 29094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } else if (mIntendedState != null) { 29194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mInTransition = true; 292046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick requestStateChange(context, mIntendedState); 29394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 29494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick mDeferredStateChangeRequestNeeded = false; 29594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 29694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 29794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 29894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 29994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 30094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 30194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * If we're in a transition mode, this returns true if we're 30294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * transitioning towards being enabled. 30394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 30494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick public final boolean isTurningOn() { 30594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return mIntendedState != null && mIntendedState; 30694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 30794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 30894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 30994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Returns simplified 3-state value from underlying 5-state. 31094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * 31194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * @param context 31294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE 31394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 31494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick public final int getTriState(Context context) { 315046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick if (mInTransition) { 316046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // If we know we just got a toggle request recently 317046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // (which set mInTransition), don't even ask the 318046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // underlying interface for its state. We know we're 319046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // changing. This avoids blocking the UI thread 320046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // during UI refresh post-toggle if the underlying 321046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // service state accessor has coarse locking on its 322046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // state (to be fixed separately). 323046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick return STATE_INTERMEDIATE; 324046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick } 32594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick switch (getActualState(context)) { 32694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case STATE_DISABLED: 32794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_DISABLED; 32894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case STATE_ENABLED: 32994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_ENABLED; 33094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick default: 33194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_INTERMEDIATE; 33294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 33394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 33494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 33594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 33694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Gets underlying actual state. 33794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * 33894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * @param context 33994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * @return STATE_ENABLED, STATE_DISABLED, STATE_ENABLING, STATE_DISABLING, 34094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * or or STATE_UNKNOWN. 34194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 34294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick public abstract int getActualState(Context context); 34394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 34494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 34594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Actually make the desired change to the underlying radio 34694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * API. 34794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 348046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick protected abstract void requestStateChange(Context context, boolean desiredState); 34994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 35094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 35194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 35294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Subclass of StateTracker to get/set Wifi state. 35394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 35494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static final class WifiStateTracker extends StateTracker { 355b9062f26785e53cfc44180e0044c8025ad33af2aalanv public int getContainerId() { return R.id.btn_wifi; } 356ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getButtonId() { return R.id.img_wifi; } 357ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getIndicatorId() { return R.id.ind_wifi; } 358b9062f26785e53cfc44180e0044c8025ad33af2aalanv public int getButtonDescription() { return R.string.gadget_wifi; } 359ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getButtonImageId(boolean on) { 360a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng return on ? R.drawable.ic_appwidget_settings_wifi_on_holo 361a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng : R.drawable.ic_appwidget_settings_wifi_off_holo; 362ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 363ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 36494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick @Override 365740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani public int getPosition() { return POS_LEFT; } 366740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani 367740edeaa42d276bca21ea7e077412badecc0eea3Amith Yamasani @Override 36894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick public int getActualState(Context context) { 36994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 37094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick if (wifiManager != null) { 37194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return wifiStateToFiveState(wifiManager.getWifiState()); 37294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 37394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_UNKNOWN; 37494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 37594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 37694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick @Override 377046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick protected void requestStateChange(Context context, final boolean desiredState) { 378ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick final WifiManager wifiManager = 379ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 38094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick if (wifiManager == null) { 38194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick Log.d(TAG, "No wifiManager."); 38294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return; 38394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 384a6a74e222a994e29a1daa7178943a1fc9dd06c47Irfan Sheriff 385046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // Actually request the wifi change and persistent 386046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // settings write off the UI thread, as it can take a 387046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // user-noticeable amount of time, especially if there's 388046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // disk contention. 389046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick new AsyncTask<Void, Void, Void>() { 390046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick @Override 391046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick protected Void doInBackground(Void... args) { 392046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick /** 393046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick * Disable tethering if enabling Wifi 394046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick */ 395046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick int wifiApState = wifiManager.getWifiApState(); 396046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick if (desiredState && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) || 397046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) { 398deca11c87dbe4d49b43961f6b755f4484936e2caRebecca Silberstein final ConnectivityManager connectivityManager = 399deca11c87dbe4d49b43961f6b755f4484936e2caRebecca Silberstein (ConnectivityManager) context.getSystemService( 400deca11c87dbe4d49b43961f6b755f4484936e2caRebecca Silberstein Context.CONNECTIVITY_SERVICE); 401deca11c87dbe4d49b43961f6b755f4484936e2caRebecca Silberstein connectivityManager.stopTethering(ConnectivityManager.TETHERING_WIFI); 402046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick } 403046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick 404046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick wifiManager.setWifiEnabled(desiredState); 405046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick return null; 406046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick } 407046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick }.execute(); 40894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 40994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 41094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick @Override 41194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick public void onActualStateChange(Context context, Intent intent) { 41294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick if (!WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) { 41394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return; 41494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 41594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1); 41694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick setCurrentState(context, wifiStateToFiveState(wifiState)); 41794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 41894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 41994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 42094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Converts WifiManager's state values into our 42194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Wifi/Bluetooth-common state values. 42294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 42394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static int wifiStateToFiveState(int wifiState) { 42494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick switch (wifiState) { 42594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case WifiManager.WIFI_STATE_DISABLED: 42694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_DISABLED; 42794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case WifiManager.WIFI_STATE_ENABLED: 42894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_ENABLED; 42994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case WifiManager.WIFI_STATE_DISABLING: 43094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_TURNING_OFF; 43194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case WifiManager.WIFI_STATE_ENABLING: 43294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_TURNING_ON; 43394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick default: 43494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_UNKNOWN; 43594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 43694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 43794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 43894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 43994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 44094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Subclass of StateTracker to get/set Bluetooth state. 44194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 44294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static final class BluetoothStateTracker extends StateTracker { 443b9062f26785e53cfc44180e0044c8025ad33af2aalanv public int getContainerId() { return R.id.btn_bluetooth; } 444ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getButtonId() { return R.id.img_bluetooth; } 445ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getIndicatorId() { return R.id.ind_bluetooth; } 446b9062f26785e53cfc44180e0044c8025ad33af2aalanv public int getButtonDescription() { return R.string.gadget_bluetooth; } 447ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getButtonImageId(boolean on) { 448a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng return on ? R.drawable.ic_appwidget_settings_bluetooth_on_holo 449a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng : R.drawable.ic_appwidget_settings_bluetooth_off_holo; 450ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 45194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 45294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick @Override 45394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick public int getActualState(Context context) { 454436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (sLocalBluetoothAdapter == null) { 455f2982a9ba19340b474bafb6b0bf5832673984e0dJason Monk LocalBluetoothManager manager = Utils.getLocalBtManager(context); 456436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (manager == null) { 45794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_UNKNOWN; // On emulator? 45894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 459436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby sLocalBluetoothAdapter = manager.getBluetoothAdapter(); 4608d763c03028419884ced41c7b630ce9a5c45437dPrathmesh Prabhu if (sLocalBluetoothAdapter == null) { 4618d763c03028419884ced41c7b630ce9a5c45437dPrathmesh Prabhu return STATE_UNKNOWN; // On emulator? 4628d763c03028419884ced41c7b630ce9a5c45437dPrathmesh Prabhu } 46394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 464436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby return bluetoothStateToFiveState(sLocalBluetoothAdapter.getBluetoothState()); 46594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 46694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 46794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick @Override 468046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick protected void requestStateChange(Context context, final boolean desiredState) { 469436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby if (sLocalBluetoothAdapter == null) { 47094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick Log.d(TAG, "No LocalBluetoothManager"); 47194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return; 47294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 473046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // Actually request the Bluetooth change and persistent 474046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // settings write off the UI thread, as it can take a 475046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // user-noticeable amount of time, especially if there's 476046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // disk contention. 477046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick new AsyncTask<Void, Void, Void>() { 478046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick @Override 479046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick protected Void doInBackground(Void... args) { 480436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby sLocalBluetoothAdapter.setBluetoothEnabled(desiredState); 481046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick return null; 482046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick } 483046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick }.execute(); 48494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 48594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 48694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick @Override 48794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick public void onActualStateChange(Context context, Intent intent) { 48894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) { 48994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return; 49094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 49194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick int bluetoothState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); 49294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick setCurrentState(context, bluetoothStateToFiveState(bluetoothState)); 49394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 49494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 49594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick /** 49694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Converts BluetoothAdapter's state values into our 49794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick * Wifi/Bluetooth-common state values. 49894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick */ 49994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick private static int bluetoothStateToFiveState(int bluetoothState) { 50094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick switch (bluetoothState) { 50194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case BluetoothAdapter.STATE_OFF: 50294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_DISABLED; 50394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case BluetoothAdapter.STATE_ON: 50494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_ENABLED; 50594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case BluetoothAdapter.STATE_TURNING_ON: 50694ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_TURNING_ON; 50794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick case BluetoothAdapter.STATE_TURNING_OFF: 50894ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_TURNING_OFF; 50994ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick default: 51094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick return STATE_UNKNOWN; 51194ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 51294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 51394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } 51494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 515ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick /** 516681f79900787c2c40751463ddd8f3476f9b40476David Christie * Subclass of StateTracker for location state. 517ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick */ 518681f79900787c2c40751463ddd8f3476f9b40476David Christie private static final class LocationStateTracker extends StateTracker { 519587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie private int mCurrentLocationMode = Settings.Secure.LOCATION_MODE_OFF; 520587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie 521681f79900787c2c40751463ddd8f3476f9b40476David Christie public int getContainerId() { return R.id.btn_location; } 522681f79900787c2c40751463ddd8f3476f9b40476David Christie public int getButtonId() { return R.id.img_location; } 523681f79900787c2c40751463ddd8f3476f9b40476David Christie public int getIndicatorId() { return R.id.ind_location; } 524681f79900787c2c40751463ddd8f3476f9b40476David Christie public int getButtonDescription() { return R.string.gadget_location; } 525ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getButtonImageId(boolean on) { 526587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie if (on) { 527587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie switch (mCurrentLocationMode) { 528587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY: 529587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie case Settings.Secure.LOCATION_MODE_SENSORS_ONLY: 530587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie return R.drawable.ic_appwidget_settings_location_on_holo; 531587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie default: 532587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie return R.drawable.ic_appwidget_settings_location_saving_holo; 533587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie } 534587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie } 535587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie 536587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie return R.drawable.ic_appwidget_settings_location_off_holo; 537ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 538ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 539ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 540ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getActualState(Context context) { 541ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick ContentResolver resolver = context.getContentResolver(); 542587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie mCurrentLocationMode = Settings.Secure.getInt(resolver, 54393259c14f3aca4739e2cf7691cb0416ded509d8dTom O'Neill Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 544587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie return (mCurrentLocationMode == Settings.Secure.LOCATION_MODE_OFF) 545587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie ? STATE_DISABLED : STATE_ENABLED; 546ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 547ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 548ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 549ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public void onActualStateChange(Context context, Intent unused) { 550ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick // Note: the broadcast location providers changed intent 551ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick // doesn't include an extras bundles saying what the new value is. 552ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick setCurrentState(context, getActualState(context)); 553ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 554ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 555ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 556ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public void requestStateChange(final Context context, final boolean desiredState) { 557ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick final ContentResolver resolver = context.getContentResolver(); 558ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick new AsyncTask<Void, Void, Boolean>() { 559ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 560ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick protected Boolean doInBackground(Void... args) { 561ea6260d887a7065d65d94be58c05903b3d1fc359Maggie Benthall final UserManager um = 562ea6260d887a7065d65d94be58c05903b3d1fc359Maggie Benthall (UserManager) context.getSystemService(Context.USER_SERVICE); 5630c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall if (!um.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION)) { 5643d0bee59b875c7a47045408a46a599ae290659efLifu Tang int currentMode = Settings.Secure.getInt(resolver, 5653d0bee59b875c7a47045408a46a599ae290659efLifu Tang Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF); 5663d0bee59b875c7a47045408a46a599ae290659efLifu Tang int mode = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 5673d0bee59b875c7a47045408a46a599ae290659efLifu Tang switch (currentMode) { 5683d0bee59b875c7a47045408a46a599ae290659efLifu Tang case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY: 5693d0bee59b875c7a47045408a46a599ae290659efLifu Tang mode = Settings.Secure.LOCATION_MODE_BATTERY_SAVING; 5703d0bee59b875c7a47045408a46a599ae290659efLifu Tang break; 5713d0bee59b875c7a47045408a46a599ae290659efLifu Tang case Settings.Secure.LOCATION_MODE_BATTERY_SAVING: 5723d0bee59b875c7a47045408a46a599ae290659efLifu Tang mode = Settings.Secure.LOCATION_MODE_HIGH_ACCURACY; 5733d0bee59b875c7a47045408a46a599ae290659efLifu Tang break; 5743d0bee59b875c7a47045408a46a599ae290659efLifu Tang case Settings.Secure.LOCATION_MODE_SENSORS_ONLY: 5753d0bee59b875c7a47045408a46a599ae290659efLifu Tang mode = Settings.Secure.LOCATION_MODE_OFF; 5763d0bee59b875c7a47045408a46a599ae290659efLifu Tang break; 5773d0bee59b875c7a47045408a46a599ae290659efLifu Tang case Settings.Secure.LOCATION_MODE_OFF: 578ee0db4c35bd4284102e6a59a4426c85b463b7841Lifu Tang mode = Settings.Secure.LOCATION_MODE_PREVIOUS; 5793d0bee59b875c7a47045408a46a599ae290659efLifu Tang break; 5803d0bee59b875c7a47045408a46a599ae290659efLifu Tang } 58193259c14f3aca4739e2cf7691cb0416ded509d8dTom O'Neill Settings.Secure.putInt(resolver, Settings.Secure.LOCATION_MODE, mode); 582587e6bf3fcfc8dffb4cf021227d896ffcb5488a9David Christie return mode != Settings.Secure.LOCATION_MODE_OFF; 583ea6260d887a7065d65d94be58c05903b3d1fc359Maggie Benthall } 584681f79900787c2c40751463ddd8f3476f9b40476David Christie 5855eed792a76970e4271e03547e61dbbd6fabbf2f4David Christie return getActualState(context) == STATE_ENABLED; 586ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 587ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 588ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 589ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick protected void onPostExecute(Boolean result) { 590ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick setCurrentState( 591ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick context, 592ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick result ? STATE_ENABLED : STATE_DISABLED); 593ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick updateWidget(context); 594ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 595ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick }.execute(); 596ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 597ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 598ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 599ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick /** 600ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick * Subclass of StateTracker for sync state. 601ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick */ 602ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick private static final class SyncStateTracker extends StateTracker { 603b9062f26785e53cfc44180e0044c8025ad33af2aalanv public int getContainerId() { return R.id.btn_sync; } 604ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getButtonId() { return R.id.img_sync; } 605ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getIndicatorId() { return R.id.ind_sync; } 606b9062f26785e53cfc44180e0044c8025ad33af2aalanv public int getButtonDescription() { return R.string.gadget_sync; } 607ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getButtonImageId(boolean on) { 608a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng return on ? R.drawable.ic_appwidget_settings_sync_on_holo 609a1252ccf7b31d01a9612fc0479dc7a632cabf8a7Peter Ng : R.drawable.ic_appwidget_settings_sync_off_holo; 610ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 611ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 612ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 613ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public int getActualState(Context context) { 61449c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani boolean on = ContentResolver.getMasterSyncAutomatically(); 615ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick return on ? STATE_ENABLED : STATE_DISABLED; 616ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 617ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 618ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 619ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public void onActualStateChange(Context context, Intent unused) { 620ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick setCurrentState(context, getActualState(context)); 621ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 622ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 623ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 624ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick public void requestStateChange(final Context context, final boolean desiredState) { 625ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick final ConnectivityManager connManager = 626ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 627ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick final boolean sync = ContentResolver.getMasterSyncAutomatically(); 628ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 629ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick new AsyncTask<Void, Void, Boolean>() { 630ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 631ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick protected Boolean doInBackground(Void... args) { 632ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick // Turning sync on. 633ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick if (desiredState) { 634ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick if (!sync) { 635ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick ContentResolver.setMasterSyncAutomatically(true); 636ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 637ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick return true; 638ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 639ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 640ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick // Turning sync off 641ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick if (sync) { 642ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick ContentResolver.setMasterSyncAutomatically(false); 643ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 644ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick return false; 645ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 646ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 647ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick @Override 648ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick protected void onPostExecute(Boolean result) { 649ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick setCurrentState( 650ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick context, 651ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick result ? STATE_ENABLED : STATE_DISABLED); 652ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick updateWidget(context); 653ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 654ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick }.execute(); 655ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 656ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } 65794ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 658a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani private static void checkObserver(Context context) { 659a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani if (sSettingsObserver == null) { 660a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani sSettingsObserver = new SettingsObserver(new Handler(), 661a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani context.getApplicationContext()); 662a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani sSettingsObserver.startObserving(); 663a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani } 664a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani } 665a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani 66603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff @Override 66703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff public void onUpdate(Context context, AppWidgetManager appWidgetManager, 66803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff int[] appWidgetIds) { 66903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff // Update each requested appWidgetId 670436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby RemoteViews view = buildUpdate(context); 67103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 67203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff for (int i = 0; i < appWidgetIds.length; i++) { 67303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff appWidgetManager.updateAppWidget(appWidgetIds[i], view); 67403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 67503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 67603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 67703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff @Override 67803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff public void onEnabled(Context context) { 679a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani checkObserver(context); 68003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 68103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 68203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff @Override 68303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff public void onDisabled(Context context) { 68449c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani if (sSettingsObserver != null) { 68549c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani sSettingsObserver.stopObserving(); 68649c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani sSettingsObserver = null; 68749c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani } 68803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 68903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 69003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff /** 69103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Load image for given widget and build {@link RemoteViews} for it. 69203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */ 693436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby static RemoteViews buildUpdate(Context context) { 69403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff RemoteViews views = new RemoteViews(context.getPackageName(), 69503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff R.layout.widget); 696436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby views.setOnClickPendingIntent(R.id.btn_wifi, getLaunchPendingIntent(context, 69703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff BUTTON_WIFI)); 69803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff views.setOnClickPendingIntent(R.id.btn_brightness, 69903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff getLaunchPendingIntent(context, 700436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby BUTTON_BRIGHTNESS)); 70103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff views.setOnClickPendingIntent(R.id.btn_sync, 70203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff getLaunchPendingIntent(context, 703436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby BUTTON_SYNC)); 704681f79900787c2c40751463ddd8f3476f9b40476David Christie views.setOnClickPendingIntent(R.id.btn_location, 705681f79900787c2c40751463ddd8f3476f9b40476David Christie getLaunchPendingIntent(context, BUTTON_LOCATION)); 70603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff views.setOnClickPendingIntent(R.id.btn_bluetooth, 70703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff getLaunchPendingIntent(context, 708436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby BUTTON_BLUETOOTH)); 70903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 71003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff updateButtons(views, context); 71103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff return views; 71203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 71303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 71403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff /** 71503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Updates the widget when something changes, or when a button is pushed. 71603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * 71703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * @param context 71803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */ 71903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff public static void updateWidget(Context context) { 720436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby RemoteViews views = buildUpdate(context); 72103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff // Update specific list of appWidgetIds if given, otherwise default to all 72203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff final AppWidgetManager gm = AppWidgetManager.getInstance(context); 72303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff gm.updateAppWidget(THIS_APPWIDGET, views); 724a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani checkObserver(context); 72503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 72603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 72703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff /** 72803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Updates the buttons based on the underlying states of wifi, etc. 72903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * 73003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * @param views The RemoteViews to update. 73103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * @param context 73203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */ 73303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff private static void updateButtons(RemoteViews views, Context context) { 734ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick sWifiState.setImageViewResources(context, views); 735ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick sBluetoothState.setImageViewResources(context, views); 736681f79900787c2c40751463ddd8f3476f9b40476David Christie sLocationState.setImageViewResources(context, views); 737ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick sSyncState.setImageViewResources(context, views); 738ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick 7395c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik if (getBrightnessMode(context)) { 740b9062f26785e53cfc44180e0044c8025ad33af2aalanv views.setContentDescription(R.id.btn_brightness, 741b9062f26785e53cfc44180e0044c8025ad33af2aalanv context.getString(R.string.gadget_brightness_template, 742b9062f26785e53cfc44180e0044c8025ad33af2aalanv context.getString(R.string.gadget_brightness_state_auto))); 74394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick views.setImageViewResource(R.id.img_brightness, 744a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani R.drawable.ic_appwidget_settings_brightness_auto_holo); 74594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick views.setImageViewResource(R.id.ind_brightness, 746a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani R.drawable.appwidget_settings_ind_on_r_holo); 74703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } else { 748a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani final int brightness = getBrightness(context); 749748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown final PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 750a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani // Set the icon 751748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown final int full = (int)(pm.getMaximumScreenBrightnessSetting() 752748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown * FULL_BRIGHTNESS_THRESHOLD); 753748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown final int half = (int)(pm.getMaximumScreenBrightnessSetting() 754748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown * HALF_BRIGHTNESS_THRESHOLD); 755748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown if (brightness > full) { 756b9062f26785e53cfc44180e0044c8025ad33af2aalanv views.setContentDescription(R.id.btn_brightness, 757b9062f26785e53cfc44180e0044c8025ad33af2aalanv context.getString(R.string.gadget_brightness_template, 758b9062f26785e53cfc44180e0044c8025ad33af2aalanv context.getString(R.string.gadget_brightness_state_full))); 759a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani views.setImageViewResource(R.id.img_brightness, 760a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani R.drawable.ic_appwidget_settings_brightness_full_holo); 761748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown } else if (brightness > half) { 762b9062f26785e53cfc44180e0044c8025ad33af2aalanv views.setContentDescription(R.id.btn_brightness, 763b9062f26785e53cfc44180e0044c8025ad33af2aalanv context.getString(R.string.gadget_brightness_template, 764b9062f26785e53cfc44180e0044c8025ad33af2aalanv context.getString(R.string.gadget_brightness_state_half))); 765a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani views.setImageViewResource(R.id.img_brightness, 766a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani R.drawable.ic_appwidget_settings_brightness_half_holo); 767a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani } else { 768b9062f26785e53cfc44180e0044c8025ad33af2aalanv views.setContentDescription(R.id.btn_brightness, 769b9062f26785e53cfc44180e0044c8025ad33af2aalanv context.getString(R.string.gadget_brightness_template, 770b9062f26785e53cfc44180e0044c8025ad33af2aalanv context.getString(R.string.gadget_brightness_state_off))); 771a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani views.setImageViewResource(R.id.img_brightness, 772a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani R.drawable.ic_appwidget_settings_brightness_off_holo); 773a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani } 774a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani // Set the ON state 775748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown if (brightness > half) { 776a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani views.setImageViewResource(R.id.ind_brightness, 777a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani R.drawable.appwidget_settings_ind_on_r_holo); 778a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani } else { 779a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani views.setImageViewResource(R.id.ind_brightness, 780a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani R.drawable.appwidget_settings_ind_off_r_holo); 781a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani } 78203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 78303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 78403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 78503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff /** 78603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Creates PendingIntent to notify the widget of a button click. 78703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * 78803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * @param context 78903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * @return 79003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */ 791436b29e68e6608bed9e8e7d54385b8f62d89208eJake Hamby private static PendingIntent getLaunchPendingIntent(Context context, 792e936f5b386b39781e8f5e1ab423ebaf790dd9742Ken Shirriff int buttonId) { 79303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff Intent launchIntent = new Intent(); 79403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff launchIntent.setClass(context, SettingsAppWidgetProvider.class); 79503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff launchIntent.addCategory(Intent.CATEGORY_ALTERNATIVE); 79603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff launchIntent.setData(Uri.parse("custom:" + buttonId)); 79703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff PendingIntent pi = PendingIntent.getBroadcast(context, 0 /* no requestCode */, 79803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff launchIntent, 0 /* no flags */); 79903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff return pi; 80003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 80103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 80203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff /** 80303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Receives and processes a button pressed intent or state change. 80403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * 80503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * @param context 80603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * @param intent Indicates the pressed button. 80703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */ 80803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff @Override 80903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff public void onReceive(Context context, Intent intent) { 81003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff super.onReceive(context, intent); 811ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick String action = intent.getAction(); 812ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) { 81394ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick sWifiState.onActualStateChange(context, intent); 814ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { 81594ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick sBluetoothState.onActualStateChange(context, intent); 8164af6514c78f2e468fe0f8f6070cf0f3e658b34a0Tom O'Neill } else if (LocationManager.MODE_CHANGED_ACTION.equals(action)) { 817681f79900787c2c40751463ddd8f3476f9b40476David Christie sLocationState.onActualStateChange(context, intent); 8181d6bf8d46b07cb87d5842324190bc5a31eee5e4bJeff Sharkey } else if (ContentResolver.ACTION_SYNC_CONN_STATUS_CHANGED.equals(action)) { 819ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick sSyncState.onActualStateChange(context, intent); 82094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick } else if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) { 82103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff Uri data = intent.getData(); 82203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff int buttonId = Integer.parseInt(data.getSchemeSpecificPart()); 82303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff if (buttonId == BUTTON_WIFI) { 82494ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick sWifiState.toggleState(context); 82503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } else if (buttonId == BUTTON_BRIGHTNESS) { 82603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff toggleBrightness(context); 82703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } else if (buttonId == BUTTON_SYNC) { 828ae0ff95272fe2a7e32114ef4565e8c6b52c269b4Brad Fitzpatrick sSyncState.toggleState(context); 829681f79900787c2c40751463ddd8f3476f9b40476David Christie } else if (buttonId == BUTTON_LOCATION) { 830681f79900787c2c40751463ddd8f3476f9b40476David Christie sLocationState.toggleState(context); 83103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } else if (buttonId == BUTTON_BLUETOOTH) { 83294ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick sBluetoothState.toggleState(context); 83303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 834046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick } else { 835046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // Don't fall-through to updating the widget. The Intent 836046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // was something unrelated or that our super class took 837046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick // care of. 838046915c4c8088ea222cb5a0ea8f0d3988e65c1c3Brad Fitzpatrick return; 83903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 84094ea6e21c337225f01856b65318d34fbaa044ac4Brad Fitzpatrick 84103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff // State changes fall through 84203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff updateWidget(context); 84303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 84403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 84503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff /** 846a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani * Gets brightness level. 84703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * 84803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * @param context 849a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani * @return brightness level between 0 and 255. 85003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */ 851a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani private static int getBrightness(Context context) { 85203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff try { 853748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown int brightness = Settings.System.getInt(context.getContentResolver(), 854748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown Settings.System.SCREEN_BRIGHTNESS); 855748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown return brightness; 85603a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } catch (Exception e) { 85703a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 858a9125d4d59bb3293dd1c92189bec3d0ab9e71d52Amith Yamasani return 0; 85903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 86003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff 86103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff /** 8625c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik * Gets state of brightness mode. 8635c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik * 8645c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik * @param context 8655c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik * @return true if auto brightness is on. 8665c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik */ 8675c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik private static boolean getBrightnessMode(Context context) { 8685c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik try { 869748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown int brightnessMode = Settings.System.getInt(context.getContentResolver(), 870748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown Settings.System.SCREEN_BRIGHTNESS_MODE); 871748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown return brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; 8725c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik } catch (Exception e) { 8735c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik Log.d(TAG, "getBrightnessMode: " + e); 8745c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik } 8755c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik return false; 8765c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik } 8775c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik 8785c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik /** 87903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * Increases or decreases the brightness. 88003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * 88103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff * @param context 88203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff */ 88303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff private void toggleBrightness(Context context) { 88403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff try { 885cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood IPowerManager power = IPowerManager.Stub.asInterface( 886cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood ServiceManager.getService("power")); 887cd03f5320d42290b1619933954a344b59dc55f4fMike Lockwood if (power != null) { 888748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 889748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown 89003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff ContentResolver cr = context.getContentResolver(); 89103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff int brightness = Settings.System.getInt(cr, 89203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff Settings.System.SCREEN_BRIGHTNESS); 8935c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik int brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; 8945c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik //Only get brightness setting if available 8955c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik if (context.getResources().getBoolean( 8965c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik com.android.internal.R.bool.config_automatic_brightness_available)) { 8975c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik brightnessMode = Settings.System.getInt(cr, 8985c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik Settings.System.SCREEN_BRIGHTNESS_MODE); 8995c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik } 9005c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik 9015c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik // Rotate AUTO -> MINIMUM -> DEFAULT -> MAXIMUM 90203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff // Technically, not a toggle... 9035c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) { 904748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown brightness = pm.getMinimumScreenBrightnessSetting(); 9055c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; 906748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown } else if (brightness < pm.getDefaultScreenBrightnessSetting()) { 907748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown brightness = pm.getDefaultScreenBrightnessSetting(); 908748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown } else if (brightness < pm.getMaximumScreenBrightnessSetting()) { 909748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown brightness = pm.getMaximumScreenBrightnessSetting(); 91003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } else { 9115c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; 912748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown brightness = pm.getMinimumScreenBrightnessSetting(); 91303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 9145c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik 915c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff if (context.getResources().getBoolean( 916c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff com.android.internal.R.bool.config_automatic_brightness_available)) { 9175c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik // Set screen brightness mode (automatic or manual) 918c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff Settings.System.putInt(context.getContentResolver(), 919c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff Settings.System.SCREEN_BRIGHTNESS_MODE, 9205c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik brightnessMode); 9215bc5cedc7ae2808ed487d90ff86caedc722021dbErik } else { 9225bc5cedc7ae2808ed487d90ff86caedc722021dbErik // Make sure we set the brightness if automatic mode isn't available 9235bc5cedc7ae2808ed487d90ff86caedc722021dbErik brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; 9245c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik } 9255c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL) { 926748ba16a046a6ac4727f2e39db9a933d81d02465Jeff Brown power.setTemporaryScreenBrightnessSettingOverride(brightness); 9275c9f9ce263b1ce24831d3bb2cc924ea40de1ec7aErik Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS, brightness); 928c4a0576473bd14eec1307ae1e0001a1db4fb5e94Ken Shirriff } 92903a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 93003a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } catch (RemoteException e) { 93103a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff Log.d(TAG, "toggleBrightness: " + e); 93203a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } catch (Settings.SettingNotFoundException e) { 93303a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff Log.d(TAG, "toggleBrightness: " + e); 93403a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 93503a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff } 93649c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani 93749c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani /** Observer to watch for changes to the BRIGHTNESS setting */ 93849c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani private static class SettingsObserver extends ContentObserver { 93949c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani 94049c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani private Context mContext; 94149c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani 94249c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani SettingsObserver(Handler handler, Context context) { 94349c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani super(handler); 94449c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani mContext = context; 94549c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani } 94649c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani 94749c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani void startObserving() { 94849c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani ContentResolver resolver = mContext.getContentResolver(); 94949c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani // Listen to brightness and brightness mode 95049c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani resolver.registerContentObserver(Settings.System 95149c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani .getUriFor(Settings.System.SCREEN_BRIGHTNESS), false, this); 95249c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani resolver.registerContentObserver(Settings.System 95349c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani .getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE), false, this); 954fde3074faa5e87d10b972fde2ea0db10b3a3a9dalongyu.huang resolver.registerContentObserver(Settings.System 955fde3074faa5e87d10b972fde2ea0db10b3a3a9dalongyu.huang .getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ), false, this); 95649c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani } 95749c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani 95849c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani void stopObserving() { 95949c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani mContext.getContentResolver().unregisterContentObserver(this); 96049c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani } 96149c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani 96249c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani @Override 96349c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani public void onChange(boolean selfChange) { 96449c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani updateWidget(mContext); 96549c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani } 96649c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani } 96749c3ef901bd3add86511a17417ee5394771c33f6Amith Yamasani 96803a6110b4f62e72592b451c05848cfaad8c65324Ken Shirriff} 969