diff options
author | Ken Shirriff <kens@google.com> | 2009-06-08 13:49:05 -0700 |
---|---|---|
committer | Ken Shirriff <kens@google.com> | 2009-06-08 13:57:26 -0700 |
commit | 03a6110b4f62e72592b451c05848cfaad8c65324 (patch) | |
tree | 3559c29c7d08000dcc6eb40423dc1e36ec238927 /src/com/android/settings/widget | |
parent | 5ed2c4ad43f2c3c85a025da04becd2eaa75927a1 (diff) | |
download | packages_apps_Settings-03a6110b4f62e72592b451c05848cfaad8c65324.zip packages_apps_Settings-03a6110b4f62e72592b451c05848cfaad8c65324.tar.gz packages_apps_Settings-03a6110b4f62e72592b451c05848cfaad8c65324.tar.bz2 |
Implement the power-control widget.
This widget allows uses to turn on/off bluetooth, wifi, gps, and sync,
and adjust brightness without going through the settings menu.
The widget provider updates the settings when the buttons are pressed.
The widget provider is also a receiver for events indicating that the
status was updated elsewhere and the buttons need to be changed.
Diffstat (limited to 'src/com/android/settings/widget')
-rw-r--r-- | src/com/android/settings/widget/SettingsAppWidgetProvider.java | 404 |
1 files changed, 404 insertions, 0 deletions
diff --git a/src/com/android/settings/widget/SettingsAppWidgetProvider.java b/src/com/android/settings/widget/SettingsAppWidgetProvider.java new file mode 100644 index 0000000..002816f --- /dev/null +++ b/src/com/android/settings/widget/SettingsAppWidgetProvider.java @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.widget; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.bluetooth.BluetoothDevice; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.IContentService; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.location.LocationManager; +import android.net.ConnectivityManager; +import android.net.Uri; +import android.net.wifi.WifiManager; +import android.os.IHardwareService; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.provider.Settings; +import android.util.Log; +import android.widget.RemoteViews; +import com.android.settings.R; +import com.android.settings.bluetooth.LocalBluetoothManager; + +/** + * Provides control of power-related settings from a widget. + */ +public class SettingsAppWidgetProvider extends AppWidgetProvider { + static final String TAG = "SettingsAppWidgetProvider"; + + static final ComponentName THIS_APPWIDGET = + new ComponentName("com.android.settings", + "com.android.settings.widget.SettingsAppWidgetProvider"); + + private static LocalBluetoothManager mLocalBluetoothManager = null; + + private static final int BUTTON_WIFI = 0; + private static final int BUTTON_BRIGHTNESS = 1; + private static final int BUTTON_SYNC = 2; + private static final int BUTTON_GPS = 3; + private static final int BUTTON_BLUETOOTH = 4; + + private static final int STATE_DISABLED = 0; + private static final int STATE_ENABLED = 1; + private static final int STATE_INTERMEDIATE = 2; + + /** + * Minimum and maximum brightnesses. Don't go to 0 since that makes the display unusable + */ + private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 10; + private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON; + private static final int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f); + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, + int[] appWidgetIds) { + // Update each requested appWidgetId + RemoteViews view = buildUpdate(context, -1); + + for (int i = 0; i < appWidgetIds.length; i++) { + appWidgetManager.updateAppWidget(appWidgetIds[i], view); + } + } + + @Override + public void onEnabled(Context context) { + PackageManager pm = context.getPackageManager(); + pm.setComponentEnabledSetting( + new ComponentName("com.android.settings", ".widget.SettingsAppWidgetProvider"), + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, + PackageManager.DONT_KILL_APP); + } + + @Override + public void onDisabled(Context context) { + Class clazz = com.android.settings.widget.SettingsAppWidgetProvider.class; + PackageManager pm = context.getPackageManager(); + pm.setComponentEnabledSetting( + new ComponentName("com.android.settings", ".widget.SettingsAppWidgetProvider"), + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + } + + /** + * Load image for given widget and build {@link RemoteViews} for it. + */ + static RemoteViews buildUpdate(Context context, int appWidgetId) { + RemoteViews views = new RemoteViews(context.getPackageName(), + R.layout.widget); + views.setOnClickPendingIntent(R.id.btn_wifi, getLaunchPendingIntent(context, appWidgetId, + BUTTON_WIFI)); + views.setOnClickPendingIntent(R.id.btn_brightness, + getLaunchPendingIntent(context, + appWidgetId, BUTTON_BRIGHTNESS)); + views.setOnClickPendingIntent(R.id.btn_sync, + getLaunchPendingIntent(context, + appWidgetId, BUTTON_SYNC)); + views.setOnClickPendingIntent(R.id.btn_gps, + getLaunchPendingIntent(context, appWidgetId, BUTTON_GPS)); + views.setOnClickPendingIntent(R.id.btn_bluetooth, + getLaunchPendingIntent(context, + appWidgetId, BUTTON_BLUETOOTH)); + + updateButtons(views, context); + return views; + } + + /** + * Updates the widget when something changes, or when a button is pushed. + * + * @param context + */ + public static void updateWidget(Context context) { + RemoteViews views = buildUpdate(context, -1); + // Update specific list of appWidgetIds if given, otherwise default to all + final AppWidgetManager gm = AppWidgetManager.getInstance(context); + gm.updateAppWidget(THIS_APPWIDGET, views); + } + + /** + * Updates the buttons based on the underlying states of wifi, etc. + * + * @param views The RemoteViews to update. + * @param context + */ + private static void updateButtons(RemoteViews views, Context context) { + switch (getWifiState(context)) { + case STATE_DISABLED: + views.setImageViewResource(R.id.btn_wifi, R.drawable.widget_btn_wifi_off); + break; + case STATE_ENABLED: + views.setImageViewResource(R.id.btn_wifi, R.drawable.widget_btn_wifi); + break; + case STATE_INTERMEDIATE: + views.setImageViewResource(R.id.btn_wifi, R.drawable.widget_btn_wifi_gray); + break; + } + if (getBrightness(context)) { + views.setImageViewResource(R.id.btn_brightness, R.drawable.widget_btn_brightness); + } else { + views.setImageViewResource(R.id.btn_brightness, R.drawable.widget_btn_brightness_off); + } + if (getBackgroundDataState(context)) { + views.setImageViewResource(R.id.btn_sync, R.drawable.widget_btn_sync); + } else { + views.setImageViewResource(R.id.btn_sync, R.drawable.widget_btn_sync_off); + } + if (getGpsState(context)) { + views.setImageViewResource(R.id.btn_gps, R.drawable.widget_btn_gps); + } else { + views.setImageViewResource(R.id.btn_gps, R.drawable.widget_btn_gps_off); + } + switch (getBluetoothState(context)) { + case STATE_DISABLED: + views.setImageViewResource(R.id.btn_bluetooth, R.drawable.widget_btn_bluetooth_off); + break; + case STATE_ENABLED: + views.setImageViewResource(R.id.btn_bluetooth, R.drawable.widget_btn_bluetooth); + break; + case STATE_INTERMEDIATE: + views.setImageViewResource(R.id.btn_bluetooth, R.drawable.widget_btn_bluetooth_gray); + break; + } + } + + /** + * Creates PendingIntent to notify the widget of a button click. + * + * @param context + * @param appWidgetId + * @return + */ + private static PendingIntent getLaunchPendingIntent(Context context, int appWidgetId, int buttonId) { + Intent launchIntent = new Intent(); + launchIntent.setClass(context, SettingsAppWidgetProvider.class); + launchIntent.addCategory(Intent.CATEGORY_ALTERNATIVE); + launchIntent.setData(Uri.parse("custom:" + buttonId)); + PendingIntent pi = PendingIntent.getBroadcast(context, 0 /* no requestCode */, + launchIntent, 0 /* no flags */); + return pi; + } + + /** + * Receives and processes a button pressed intent or state change. + * + * @param context + * @param intent Indicates the pressed button. + */ + @Override + public void onReceive(Context context, Intent intent) { + super.onReceive(context, intent); + if (intent.hasCategory(Intent.CATEGORY_ALTERNATIVE)) { + Uri data = intent.getData(); + int buttonId = Integer.parseInt(data.getSchemeSpecificPart()); + if (buttonId == BUTTON_WIFI) { + toggleWifi(context); + } else if (buttonId == BUTTON_BRIGHTNESS) { + toggleBrightness(context); + } else if (buttonId == BUTTON_SYNC) { + toggleBackgroundData(context); + } else if (buttonId == BUTTON_GPS) { + toggleGps(context); + } else if (buttonId == BUTTON_BLUETOOTH) { + toggleBluetooth(context); + } + } + // State changes fall through + updateWidget(context); + } + + /** + * Gets the state of Wi-Fi + * + * @param context + * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE + */ + private static int getWifiState(Context context) { + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + int wifiState = wifiManager.getWifiState(); + if (wifiState == WifiManager.WIFI_STATE_DISABLED) { + return STATE_DISABLED; + } else if (wifiState == WifiManager.WIFI_STATE_ENABLED) { + return STATE_ENABLED; + } else { + return STATE_INTERMEDIATE; + } + } + + /** + * Toggles the state of Wi-Fi + * + * @param context + */ + private void toggleWifi(Context context) { + WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + int wifiState = getWifiState(context); + if (wifiState == STATE_ENABLED) { + wifiManager.setWifiEnabled(false); + } else if (wifiState == STATE_DISABLED) { + wifiManager.setWifiEnabled(true); + mLocalBluetoothManager.setBluetoothEnabled(true); + } + } + + /** + * Gets the state of background data. + * + * @param context + * @return true if enabled + */ + private static boolean getBackgroundDataState(Context context) { + ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + return connManager.getBackgroundDataSetting(); + } + + /** + * Toggle background data and sync tickles. + * + * @param context + */ + private void toggleBackgroundData(Context context) { + ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + boolean sync = getBackgroundDataState(context); + connManager.setBackgroundDataSetting(!sync); + + IContentService contentService = ContentResolver.getContentService(); + try { + contentService.setListenForNetworkTickles(!sync); + } catch (RemoteException e) { + Log.d(TAG, "toggleBackgroundData: " + e); + } + } + + /** + * 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. + * + * @param context + * @return true if more than moderately bright. + */ + private static boolean getBrightness(Context context) { + try { + IHardwareService hardware = IHardwareService.Stub.asInterface( + ServiceManager.getService("hardware")); + if (hardware != null) { + int brightness = Settings.System.getInt(context.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS); + return brightness > 100; + } + } catch (Exception e) { + Log.d(TAG, "getBrightness: " + e); + } + return false; + } + + /** + * Increases or decreases the brightness. + * + * @param context + */ + private void toggleBrightness(Context context) { + try { + IHardwareService hardware = IHardwareService.Stub.asInterface( + ServiceManager.getService("hardware")); + if (hardware != null) { + ContentResolver cr = context.getContentResolver(); + int brightness = Settings.System.getInt(cr, + Settings.System.SCREEN_BRIGHTNESS); + // Rotate MINIMUM -> DEFAULT -> MAXIMUM + // Technically, not a toggle... + if (brightness < DEFAULT_BACKLIGHT) { + brightness = DEFAULT_BACKLIGHT; + } else if (brightness < MAXIMUM_BACKLIGHT) { + brightness = MAXIMUM_BACKLIGHT; + } else { + brightness = MINIMUM_BACKLIGHT; + } + hardware.setBacklights(brightness); + Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS, brightness); + brightness = Settings.System.getInt(cr, + Settings.System.SCREEN_BRIGHTNESS); + } + } catch (RemoteException e) { + Log.d(TAG, "toggleBrightness: " + e); + } catch (Settings.SettingNotFoundException e) { + Log.d(TAG, "toggleBrightness: " + e); + } + } + + /** + * Gets state of bluetooth + * + * @param context + * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE + */ + private static int getBluetoothState(Context context) { + if (mLocalBluetoothManager == null) { + mLocalBluetoothManager = LocalBluetoothManager.getInstance(context); + if (mLocalBluetoothManager == null) { + return STATE_INTERMEDIATE; // On emulator? + } + } + int state = mLocalBluetoothManager.getBluetoothState(); + if (state == BluetoothDevice.BLUETOOTH_STATE_OFF) { + return STATE_DISABLED; + } else if (state == BluetoothDevice.BLUETOOTH_STATE_ON) { + return STATE_ENABLED; + } else { + return STATE_INTERMEDIATE; + } + } + + /** + * Toggles the state of bluetooth + * + * @param context + */ + private void toggleBluetooth(Context context) { + int state = getBluetoothState(context); + if (state == STATE_ENABLED) { + mLocalBluetoothManager.setBluetoothEnabled(false); + } else if (state == STATE_DISABLED) { + mLocalBluetoothManager.setBluetoothEnabled(true); + } + } +} |