am 6442f0b4
: am 22aa2130
: Merge "Make power control widget be more responsive. Fix StrictMode violations." into gingerbread
Merge commit '6442f0b466c64f1cf61f3f4c89ce205c4030963e' * commit '6442f0b466c64f1cf61f3f4c89ce205c4030963e': Make power control widget be more responsive. Fix StrictMode violations.
This commit is contained in:
@@ -829,7 +829,9 @@
|
||||
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
|
||||
<action android:name="android.net.conn.BACKGROUND_DATA_SETTING_CHANGED" />
|
||||
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
|
||||
<action android:name="android.intent.action.CLOSE_SYSTEM_DIALOGS" /> <!-- pick up misc changes -->
|
||||
<action android:name="android.location.PROVIDERS_CHANGED" />
|
||||
<!-- hack: using CLOSE_SYSTEM_DIALOGS to pick up (possible) sync changes -->
|
||||
<action android:name="android.intent.action.CLOSE_SYSTEM_DIALOGS" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_info" />
|
||||
</receiver>
|
||||
|
@@ -78,10 +78,12 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
|
||||
private static final StateTracker sWifiState = new WifiStateTracker();
|
||||
private static final StateTracker sBluetoothState = new BluetoothStateTracker();
|
||||
private static final StateTracker sGpsState = new GpsStateTracker();
|
||||
private static final StateTracker sSyncState = new SyncStateTracker();
|
||||
|
||||
/**
|
||||
* The state machine for Wifi and Bluetooth toggling, tracking
|
||||
* reality versus the user's intent.
|
||||
* The state machine for a setting's 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
|
||||
@@ -133,6 +135,59 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ID of the main large image button for the setting.
|
||||
*/
|
||||
public abstract int getButtonId();
|
||||
|
||||
/**
|
||||
* Returns the small indicator image ID underneath the setting.
|
||||
*/
|
||||
public abstract int getIndicatorId();
|
||||
|
||||
/**
|
||||
* Returns the resource ID of the image to show as a function of
|
||||
* the on-vs-off state.
|
||||
*/
|
||||
public abstract int getButtonImageId(boolean on);
|
||||
|
||||
/**
|
||||
* Updates the remote views depending on the state (off, on,
|
||||
* turning off, turning on) of the setting.
|
||||
*/
|
||||
public final void setImageViewResources(Context context, RemoteViews views) {
|
||||
int buttonId = getButtonId();
|
||||
int indicatorId = getIndicatorId();
|
||||
switch (getTriState(context)) {
|
||||
case STATE_DISABLED:
|
||||
views.setImageViewResource(buttonId, getButtonImageId(false));
|
||||
views.setImageViewResource(
|
||||
indicatorId, R.drawable.appwidget_settings_ind_off_l);
|
||||
break;
|
||||
case STATE_ENABLED:
|
||||
views.setImageViewResource(buttonId, getButtonImageId(true));
|
||||
views.setImageViewResource(
|
||||
indicatorId, R.drawable.appwidget_settings_ind_on_l);
|
||||
break;
|
||||
case STATE_INTERMEDIATE:
|
||||
// In the transitional state, the bottom green bar
|
||||
// shows the tri-state (on, off, transitioning), but
|
||||
// the top dark-gray-or-bright-white logo shows the
|
||||
// user's intent. This is much easier to see in
|
||||
// sunlight.
|
||||
if (isTurningOn()) {
|
||||
views.setImageViewResource(buttonId, getButtonImageId(true));
|
||||
views.setImageViewResource(
|
||||
indicatorId, R.drawable.appwidget_settings_ind_mid_l);
|
||||
} else {
|
||||
views.setImageViewResource(buttonId, getButtonImageId(false));
|
||||
views.setImageViewResource(
|
||||
indicatorId, R.drawable.appwidget_settings_ind_off_l);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update internal state from a broadcast state change.
|
||||
*/
|
||||
@@ -236,6 +291,13 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
* Subclass of StateTracker to get/set Wifi state.
|
||||
*/
|
||||
private static final class WifiStateTracker extends StateTracker {
|
||||
public int getButtonId() { return R.id.img_wifi; }
|
||||
public int getIndicatorId() { return R.id.ind_wifi; }
|
||||
public int getButtonImageId(boolean on) {
|
||||
return on ? R.drawable.ic_appwidget_settings_wifi_on
|
||||
: R.drawable.ic_appwidget_settings_wifi_off;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActualState(Context context) {
|
||||
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
@@ -247,7 +309,8 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
|
||||
@Override
|
||||
protected void requestStateChange(Context context, final boolean desiredState) {
|
||||
final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
final WifiManager wifiManager =
|
||||
(WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
if (wifiManager == null) {
|
||||
Log.d(TAG, "No wifiManager.");
|
||||
return;
|
||||
@@ -308,6 +371,12 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
* Subclass of StateTracker to get/set Bluetooth state.
|
||||
*/
|
||||
private static final class BluetoothStateTracker extends StateTracker {
|
||||
public int getButtonId() { return R.id.img_bluetooth; }
|
||||
public int getIndicatorId() { return R.id.ind_bluetooth; }
|
||||
public int getButtonImageId(boolean on) {
|
||||
return on ? R.drawable.ic_appwidget_settings_bluetooth_on
|
||||
: R.drawable.ic_appwidget_settings_bluetooth_off;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActualState(Context context) {
|
||||
@@ -368,6 +437,120 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclass of StateTracker for GPS state.
|
||||
*/
|
||||
private static final class GpsStateTracker extends StateTracker {
|
||||
public int getButtonId() { return R.id.img_gps; }
|
||||
public int getIndicatorId() { return R.id.ind_gps; }
|
||||
public int getButtonImageId(boolean on) {
|
||||
return on ? R.drawable.ic_appwidget_settings_gps_on
|
||||
: R.drawable.ic_appwidget_settings_gps_off;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActualState(Context context) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
boolean on = Settings.Secure.isLocationProviderEnabled(
|
||||
resolver, LocationManager.GPS_PROVIDER);
|
||||
return on ? STATE_ENABLED : STATE_DISABLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActualStateChange(Context context, Intent unused) {
|
||||
// Note: the broadcast location providers changed intent
|
||||
// doesn't include an extras bundles saying what the new value is.
|
||||
setCurrentState(context, getActualState(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestStateChange(final Context context, final boolean desiredState) {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
new AsyncTask<Void, Void, Boolean>() {
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... args) {
|
||||
Settings.Secure.setLocationProviderEnabled(
|
||||
resolver,
|
||||
LocationManager.GPS_PROVIDER,
|
||||
desiredState);
|
||||
return desiredState;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
setCurrentState(
|
||||
context,
|
||||
result ? STATE_ENABLED : STATE_DISABLED);
|
||||
updateWidget(context);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclass of StateTracker for sync state.
|
||||
*/
|
||||
private static final class SyncStateTracker extends StateTracker {
|
||||
public int getButtonId() { return R.id.img_sync; }
|
||||
public int getIndicatorId() { return R.id.ind_sync; }
|
||||
public int getButtonImageId(boolean on) {
|
||||
return on ? R.drawable.ic_appwidget_settings_sync_on
|
||||
: R.drawable.ic_appwidget_settings_sync_off;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActualState(Context context) {
|
||||
boolean on = getBackgroundDataState(context) &&
|
||||
ContentResolver.getMasterSyncAutomatically();
|
||||
return on ? STATE_ENABLED : STATE_DISABLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActualStateChange(Context context, Intent unused) {
|
||||
// Well, ACTION_CLOSE_SYSTEM_DIALOGS fired. So _maybe_
|
||||
// the Sync settings changed.
|
||||
// TODO: find something more reliable.
|
||||
setCurrentState(context, getActualState(context));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestStateChange(final Context context, final boolean desiredState) {
|
||||
final ConnectivityManager connManager =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
final boolean backgroundData = getBackgroundDataState(context);
|
||||
final boolean sync = ContentResolver.getMasterSyncAutomatically();
|
||||
|
||||
new AsyncTask<Void, Void, Boolean>() {
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... args) {
|
||||
// Turning sync on.
|
||||
if (desiredState) {
|
||||
if (!backgroundData) {
|
||||
connManager.setBackgroundDataSetting(true);
|
||||
}
|
||||
if (!sync) {
|
||||
ContentResolver.setMasterSyncAutomatically(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Turning sync off
|
||||
if (sync) {
|
||||
ContentResolver.setMasterSyncAutomatically(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
setCurrentState(
|
||||
context,
|
||||
result ? STATE_ENABLED : STATE_DISABLED);
|
||||
updateWidget(context);
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
|
||||
@@ -442,38 +625,11 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
* @param context
|
||||
*/
|
||||
private static void updateButtons(RemoteViews views, Context 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);
|
||||
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);
|
||||
break;
|
||||
case STATE_INTERMEDIATE:
|
||||
// In the transitional state, the bottom green bar
|
||||
// shows the tri-state (on, off, transitioning), but
|
||||
// the top dark-gray-or-bright-white logo shows the
|
||||
// user's intent. This is much easier to see in
|
||||
// sunlight.
|
||||
if (sWifiState.isTurningOn()) {
|
||||
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;
|
||||
}
|
||||
sWifiState.setImageViewResources(context, views);
|
||||
sBluetoothState.setImageViewResources(context, views);
|
||||
sGpsState.setImageViewResources(context, views);
|
||||
sSyncState.setImageViewResources(context, views);
|
||||
|
||||
if (getBrightnessMode(context)) {
|
||||
views.setImageViewResource(R.id.img_brightness,
|
||||
R.drawable.ic_appwidget_settings_brightness_auto);
|
||||
@@ -490,52 +646,6 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
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);
|
||||
views.setImageViewResource(R.id.ind_sync, R.drawable.appwidget_settings_ind_on_c);
|
||||
} else {
|
||||
views.setImageViewResource(R.id.img_sync, R.drawable.ic_appwidget_settings_sync_off);
|
||||
views.setImageViewResource(R.id.ind_sync, R.drawable.appwidget_settings_ind_off_c);
|
||||
}
|
||||
if (getGpsState(context)) {
|
||||
views.setImageViewResource(R.id.img_gps, R.drawable.ic_appwidget_settings_gps_on);
|
||||
views.setImageViewResource(R.id.ind_gps, R.drawable.appwidget_settings_ind_on_c);
|
||||
} else {
|
||||
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 (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);
|
||||
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);
|
||||
break;
|
||||
case STATE_INTERMEDIATE:
|
||||
// In the transitional state, the bottom green bar
|
||||
// shows the tri-state (on, off, transitioning), but
|
||||
// the top dark-gray-or-bright-white logo shows the
|
||||
// user's intent. This is much easier to see in
|
||||
// sunlight.
|
||||
if (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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -565,10 +675,19 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
super.onReceive(context, intent);
|
||||
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
|
||||
String action = intent.getAction();
|
||||
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
|
||||
sWifiState.onActualStateChange(context, intent);
|
||||
} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
|
||||
} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
|
||||
sBluetoothState.onActualStateChange(context, intent);
|
||||
} else if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(action)) {
|
||||
sGpsState.onActualStateChange(context, intent);
|
||||
} else if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
|
||||
// Sadly, for lack of a "sync settings changed" intent,
|
||||
// this is where we check where sync is enabled or not.
|
||||
// It's not 100% reliable though as there are paths where
|
||||
// this doesn't fire.
|
||||
sSyncState.onActualStateChange(context, intent);
|
||||
} else if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) {
|
||||
Uri data = intent.getData();
|
||||
int buttonId = Integer.parseInt(data.getSchemeSpecificPart());
|
||||
@@ -577,9 +696,9 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
} else if (buttonId == BUTTON_BRIGHTNESS) {
|
||||
toggleBrightness(context);
|
||||
} else if (buttonId == BUTTON_SYNC) {
|
||||
toggleSync(context);
|
||||
sSyncState.toggleState(context);
|
||||
} else if (buttonId == BUTTON_GPS) {
|
||||
toggleGps(context);
|
||||
sGpsState.toggleState(context);
|
||||
} else if (buttonId == BUTTON_BLUETOOTH) {
|
||||
sBluetoothState.toggleState(context);
|
||||
}
|
||||
@@ -606,77 +725,6 @@ public class SettingsAppWidgetProvider extends AppWidgetProvider {
|
||||
return connManager.getBackgroundDataSetting();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of auto-sync.
|
||||
*
|
||||
* @param context
|
||||
* @return true if enabled
|
||||
*/
|
||||
private static boolean getSync(Context context) {
|
||||
boolean backgroundData = getBackgroundDataState(context);
|
||||
boolean sync = ContentResolver.getMasterSyncAutomatically();
|
||||
return backgroundData && sync;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle auto-sync
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
private void toggleSync(Context context) {
|
||||
ConnectivityManager connManager =
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
boolean backgroundData = getBackgroundDataState(context);
|
||||
boolean sync = ContentResolver.getMasterSyncAutomatically();
|
||||
|
||||
// four cases to handle:
|
||||
// setting toggled from off to on:
|
||||
// 1. background data was off, sync was off: turn on both
|
||||
if (!backgroundData && !sync) {
|
||||
connManager.setBackgroundDataSetting(true);
|
||||
ContentResolver.setMasterSyncAutomatically(true);
|
||||
}
|
||||
|
||||
// 2. background data was off, sync was on: turn on background data
|
||||
if (!backgroundData && sync) {
|
||||
connManager.setBackgroundDataSetting(true);
|
||||
}
|
||||
|
||||
// 3. background data was on, sync was off: turn on sync
|
||||
if (backgroundData && !sync) {
|
||||
ContentResolver.setMasterSyncAutomatically(true);
|
||||
}
|
||||
|
||||
// setting toggled from on to off:
|
||||
// 4. background data was on, sync was on: turn off sync
|
||||
if (backgroundData && sync) {
|
||||
ContentResolver.setMasterSyncAutomatically(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of GPS location.
|
||||
*
|
||||
* @param context
|
||||
* @return true if enabled.
|
||||
*/
|
||||
private static boolean getGpsState(Context context) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
return Settings.Secure.isLocationProviderEnabled(resolver, LocationManager.GPS_PROVIDER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the state of GPS.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
private void toggleGps(Context context) {
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
boolean enabled = getGpsState(context);
|
||||
Settings.Secure.setLocationProviderEnabled(resolver, LocationManager.GPS_PROVIDER,
|
||||
!enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets state of brightness.
|
||||
*
|
||||
|
Reference in New Issue
Block a user