diff options
Diffstat (limited to 'src')
-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); + } + } +} |