am 03a6110b: Implement the power-control widget.

Merge commit '03a6110b4f62e72592b451c05848cfaad8c65324'

* commit '03a6110b4f62e72592b451c05848cfaad8c65324':
  Implement the power-control widget.
This commit is contained in:
Ken Shirriff
2009-06-08 15:36:39 -07:00
committed by The Android Open Source Project
23 changed files with 548 additions and 6 deletions

View File

@@ -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);
}
}
}