summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml2
-rw-r--r--core/java/android/content/ContentResolver.java5
-rw-r--r--core/java/android/content/ContentService.java1
-rwxr-xr-xcore/java/android/content/res/Resources.java14
-rw-r--r--core/java/android/database/ContentObserver.java32
-rwxr-xr-xcore/java/android/database/IContentObserver.aidl3
-rw-r--r--core/java/android/provider/Settings.java56
-rw-r--r--core/java/android/view/KeyEvent.java6
-rw-r--r--core/res/res/drawable-hdpi/stat_2g3g_off.pngbin0 -> 2787 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_2g3g_on.pngbin0 -> 2949 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_3g_on.pngbin0 -> 2704 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_airplane_off.pngbin0 -> 3202 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_airplane_on.pngbin0 -> 3165 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_bgoff.9.pngbin0 -> 1074 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_bgon.9.pngbin0 -> 1099 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_bgon_custom.9.pngbin0 -> 1085 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_bluetooth_off.pngbin0 -> 3086 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_bluetooth_on.pngbin0 -> 2859 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_brightness_auto.pngbin0 -> 3970 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_brightness_mid.pngbin0 -> 3632 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_brightness_off.pngbin0 -> 3463 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_brightness_on.pngbin0 -> 3415 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_data_off.pngbin0 -> 2721 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_data_on.pngbin0 -> 2427 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_flashlight_off.pngbin0 -> 2916 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_flashlight_on.pngbin0 -> 3092 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_gps_off.pngbin0 -> 3329 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_gps_on.pngbin0 -> 3127 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_ing_off.pngbin0 -> 3568 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_inner_focus.9.pngbin0 -> 1082 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_inner_press.9.pngbin0 -> 1080 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_lock_screen_off.pngbin0 -> 3151 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_lock_screen_on.pngbin0 -> 3078 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_orientation_off.pngbin0 -> 3456 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_orientation_on.pngbin0 -> 3349 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_power_background.9.pngbin0 -> 932 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_ring_on.pngbin0 -> 3359 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_screen_timeout_off.pngbin0 -> 3894 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_screen_timeout_on.pngbin0 -> 3841 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_silent.pngbin0 -> 2915 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_sync_off.pngbin0 -> 3464 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_sync_on.pngbin0 -> 2828 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_vibrate_off.pngbin0 -> 4165 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_vibrate_on.pngbin0 -> 4476 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_wifi_ap_off.pngbin0 -> 3798 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_wifi_ap_on.pngbin0 -> 3727 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_wifi_off.pngbin0 -> 2902 bytes
-rw-r--r--core/res/res/drawable-hdpi/stat_wifi_on.pngbin0 -> 2914 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_2g3g_off.pngbin0 -> 2189 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_2g3g_on.pngbin0 -> 2433 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_3g_on.pngbin0 -> 2168 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_airplane_off.pngbin0 -> 2365 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_airplane_on.pngbin0 -> 2166 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_bgoff.9.pngbin0 -> 1074 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_bgon.9.pngbin0 -> 1099 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_bgon_custom.9.pngbin0 -> 1085 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_bluetooth_off.pngbin0 -> 2179 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_bluetooth_on.pngbin0 -> 2239 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_brightness_auto.pngbin0 -> 2759 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_brightness_mid.pngbin0 -> 2588 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_brightness_off.pngbin0 -> 2498 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_brightness_on.pngbin0 -> 2477 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_data_off.pngbin0 -> 2193 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_data_on.pngbin0 -> 2093 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_flashlight_off.pngbin0 -> 2044 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_flashlight_on.pngbin0 -> 2124 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_gps_off.pngbin0 -> 2370 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_gps_on.pngbin0 -> 2294 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_inner_focus.9.pngbin0 -> 1082 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_inner_press.9.pngbin0 -> 1080 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_lock_screen_off.pngbin0 -> 1905 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_ock_screen_on.pngbin0 -> 1591 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_orientation_off.pngbin0 -> 2341 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_orientation_on.pngbin0 -> 2393 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_power_background.9.pngbin0 -> 932 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_power_bg.9.pngbin0 -> 245 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_ring_off.pngbin0 -> 2630 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_ring_on.pngbin0 -> 2681 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_screen_timeout_off.pngbin0 -> 2504 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_screen_timeout_on.pngbin0 -> 2592 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_silent.pngbin0 -> 2398 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sound_vibrate_on.pngbin0 -> 2835 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sync_off.pngbin0 -> 2417 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_sync_on.pngbin0 -> 2099 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_vibrate_off.pngbin0 -> 2700 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_vibrate_on.pngbin0 -> 4074 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_wifi_ap_off.pngbin0 -> 2620 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_wifi_ap_on.pngbin0 -> 2706 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_wifi_off.pngbin0 -> 2146 bytes
-rw-r--r--core/res/res/drawable-mdpi/stat_wifi_on.pngbin0 -> 2265 bytes
-rw-r--r--core/res/res/drawable/stat_power_bg.xml28
-rw-r--r--core/res/res/layout/status_bar_expanded.xml226
-rw-r--r--services/java/com/android/server/status/StatusBarService.java375
-rwxr-xr-xservices/java/com/android/server/status/widget/AirplaneButton.java63
-rwxr-xr-xservices/java/com/android/server/status/widget/AutoRotateButton.java50
-rwxr-xr-xservices/java/com/android/server/status/widget/BluetoothButton.java141
-rwxr-xr-xservices/java/com/android/server/status/widget/BrightnessButton.java253
-rw-r--r--services/java/com/android/server/status/widget/GPSButton.java50
-rwxr-xr-xservices/java/com/android/server/status/widget/LockScreenButton.java92
-rwxr-xr-xservices/java/com/android/server/status/widget/MobileDataButton.java85
-rwxr-xr-xservices/java/com/android/server/status/widget/NetworkModeButton.java195
-rw-r--r--services/java/com/android/server/status/widget/PowerButton.java135
-rwxr-xr-xservices/java/com/android/server/status/widget/ScreenTimeoutButton.java104
-rwxr-xr-xservices/java/com/android/server/status/widget/SoundButton.java220
-rw-r--r--services/java/com/android/server/status/widget/StateTracker.java160
-rwxr-xr-xservices/java/com/android/server/status/widget/SyncButton.java104
-rwxr-xr-xservices/java/com/android/server/status/widget/WifiApButton.java152
-rw-r--r--services/java/com/android/server/status/widget/WifiButton.java159
108 files changed, 2638 insertions, 73 deletions
diff --git a/api/current.xml b/api/current.xml
index a327a5c..0678df4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -74892,7 +74892,7 @@
type="float"
transient="false"
volatile="false"
- value="0.0010f"
+ value="0.001f"
static="true"
final="true"
deprecated="not deprecated"
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index b4718ab..70fe960 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -174,6 +174,11 @@ public abstract class ContentResolver {
}
/** @hide */
+ public final Context getContext() {
+ return mContext;
+ }
+
+ /** @hide */
protected abstract IContentProvider acquireProvider(Context c, String name);
/** @hide */
public abstract boolean releaseProvider(IContentProvider icp);
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java
index 377e383..9b8f349 100644
--- a/core/java/android/content/ContentService.java
+++ b/core/java/android/content/ContentService.java
@@ -139,6 +139,7 @@ public final class ContentService extends IContentService.Stub {
ObserverCall oc = calls.get(i);
try {
oc.mObserver.onChange(oc.mSelfNotify);
+ oc.mObserver.onChangeUri(uri, oc.mSelfNotify);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Notified " + oc.mObserver + " of " + "update at " + uri);
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 44e589d..61faa73 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -595,22 +595,22 @@ public class Resources {
* Various types of objects will be returned depending on the underlying
* resource -- for example, a solid color, PNG image, scalable image, etc.
* The Drawable API hides these implementation details.
- *
+ *
* mtwebster:
- * This version also applies a Porter Duff color mask onto the object before
+ * This version also applies a Porter Duff color mask onto the object before
* returning the object. Put in Resources to give reusability, I plan on
* applying this to other parts of the gui
- *
+ *
* @param id The desired resource identifier, as generated by the aapt
* tool. This integer encodes the package, type, and resource
* entry. The value 0 is an invalid identifier.
*
* @param mask The color mask to use (alpha-r-g-b)
- *
+ *
* @param masktype The Porter Duff filter mode
- *
+ *
* @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
+ *
* @return Drawable An object that can be used to draw this resource.
* @hide
*/
@@ -623,7 +623,7 @@ public class Resources {
return tmpDrawable;
}
}
-
+
/**
* Return a movie object associated with the particular resource ID.
* @param id The desired resource identifier, as generated by the aapt
diff --git a/core/java/android/database/ContentObserver.java b/core/java/android/database/ContentObserver.java
index 3b829a3..f8a9a1a 100644
--- a/core/java/android/database/ContentObserver.java
+++ b/core/java/android/database/ContentObserver.java
@@ -17,6 +17,7 @@
package android.database;
import android.os.Handler;
+import android.net.Uri;
/**
* Receives call backs for changes to content. Must be implemented by objects which are added
@@ -34,13 +35,23 @@ public abstract class ContentObserver {
private final class NotificationRunnable implements Runnable {
private boolean mSelf;
+ private Uri mUri = null;
public NotificationRunnable(boolean self) {
mSelf = self;
}
+ public NotificationRunnable(Uri uri, boolean self) {
+ mSelf = self;
+ mUri = uri;
+ }
+
public void run() {
- ContentObserver.this.onChange(mSelf);
+ if(mUri != null) {
+ ContentObserver.this.onChangeUri(mUri, mSelf);
+ } else {
+ ContentObserver.this.onChange(mSelf);
+ }
}
}
@@ -66,6 +77,13 @@ public abstract class ContentObserver {
}
}
+ public void onChangeUri(Uri uri, boolean selfChange) {
+ ContentObserver contentObserver = mContentObserver;
+ if (contentObserver != null) {
+ contentObserver.dispatchChange(uri, selfChange);
+ }
+ }
+
public void releaseContentObserver() {
mContentObserver = null;
}
@@ -127,6 +145,8 @@ public abstract class ContentObserver {
* cursor that is being observed.
*/
public void onChange(boolean selfChange) {}
+ /** @hide */
+ public void onChangeUri(Uri uri, boolean selfChange) {}
public final void dispatchChange(boolean selfChange) {
if (mHandler == null) {
@@ -135,4 +155,14 @@ public abstract class ContentObserver {
mHandler.post(new NotificationRunnable(selfChange));
}
}
+ /** @hide */
+ public final void dispatchChange(Uri uri, boolean selfChange) {
+ if (mHandler == null) {
+ onChangeUri(uri, selfChange);
+ } else {
+ mHandler.post(new NotificationRunnable(uri, selfChange));
+ }
+ }
+
+
}
diff --git a/core/java/android/database/IContentObserver.aidl b/core/java/android/database/IContentObserver.aidl
index ac2f975..f66c29d 100755
--- a/core/java/android/database/IContentObserver.aidl
+++ b/core/java/android/database/IContentObserver.aidl
@@ -17,6 +17,8 @@
package android.database;
+import android.net.Uri;
+
/**
* @hide
*/
@@ -28,4 +30,5 @@ interface IContentObserver
* commit on the cursor that is being observed.
*/
oneway void onChange(boolean selfUpdate);
+ oneway void onChangeUri(in Uri uri, boolean selfUpdate);
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 264b22b..610310c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -27,6 +27,7 @@ import android.content.ContentQueryMap;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -57,8 +58,14 @@ import java.util.Map;
* The Settings provider contains global system-level device preferences.
*/
public final class Settings {
+ /** Intent actions for Settings
+ * @hide
+ */
+ public static final String SETTINGS_CHANGED = "android.settings.SETTINGS_CHANGED_ACTION";
- // Intent actions for Settings
+ public Settings() {
+ /* Empty for API conflicts */
+ }
/**
* Activity Action: Show system settings.
@@ -2150,13 +2157,13 @@ public final class Settings {
* Trackball Notification Colors. The value is String pkg=color|pkg=color
* @hide
*/
- public static final String NOTIFICATION_PACKAGE_COLORS = "|";
+ public static final String NOTIFICATION_PACKAGE_COLORS = "pref_package_colors";
/**
* Trackball Notification List. The value is String pkg|pkg
* @hide
*/
- public static final String NOTIFICATION_PACKAGE_LIST = "|";
+ public static final String NOTIFICATION_PACKAGE_LIST = "pref_package_list";
/**
* Trackball Notification Colors Debugging. The value is boolean (1 or 0)
@@ -2214,6 +2221,36 @@ public final class Settings {
public static final String NOTIF_EXPANDED_BAR_CUSTOM = "notif_expanded_bar_custom";
/**
+ * Use the Notification Power Widget? (Who wouldn't!)
+ * @hide
+ */
+ public static final String EXPANDED_VIEW_WIDGET = "expanded_view_widget";
+
+ /**
+ * Notification Indicator Color
+ * @hide
+ */
+ public static final String EXPANDED_VIEW_WIDGET_COLOR = "expanded_widget_color";
+
+ /**
+ * Widget Buttons to Use
+ * @hide
+ */
+ public static final String WIDGET_BUTTONS = "expanded_widget_buttons";
+
+ /** @hide */
+ public static final String EXPANDED_BRIGHTNESS_MODE = "expanded_brightness_mode";
+
+ /** @hide */
+ public static final String EXPANDED_NETWORK_MODE = "expanded_network_mode";
+
+ /** @hide */
+ public static final String EXPANDED_SCREENTIMEOUT_MODE = "expanded_screentimeout_mode";
+
+ /** @hide */
+ public static final String EXPANDED_RING_MODE = "expanded_ring_mode";
+
+ /**
* Whether to keep the home app at a higher OOM adjustement
* @hide
*/
@@ -4104,12 +4141,13 @@ public final class Settings {
/**
* Thread-safe method for enabling or disabling a single location provider.
- * @param cr the content resolver to use
+ * @param cr the content resolver from the calling application
* @param provider the location provider to enable or disable
* @param enabled true if the provider should be enabled
*/
public static final void setLocationProviderEnabled(ContentResolver cr,
String provider, boolean enabled) {
+ Context context = cr.getContext();
// to ensure thread safety, we write the provider name with a '+' or '-'
// and let the SettingsProvider handle it rather than reading and modifying
// the list of enabled providers.
@@ -4119,6 +4157,16 @@ public final class Settings {
provider = "-" + provider;
}
putString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider);
+ try {
+ Intent i = new Intent();
+ i.setAction(Settings.SETTINGS_CHANGED);
+ i.putExtra("SETTING", "GPS");
+ i.putExtra("GPS_STATUS_CHANGE", enabled);
+ context.sendBroadcast(i);
+ } catch(Exception e) {
+ //This is ignored, as this try-catch is just incase this is called
+ //Before the system is read.
+ }
}
}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index b543b2c..75b0b97 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -129,10 +129,16 @@ public class KeyEvent implements Parcelable {
public static final int KEYCODE_FUNC_7 = 98;
public static final int KEYCODE_FUNC_8 = 99;
public static final int KEYCODE_QUECHAR = 100;
+
+ /** @hide */
public static final int KEYCODE_USER1 = 101;
+ /** @hide */
public static final int KEYCODE_USER2 = 102;
+ /** @hide */
public static final int KEYCODE_USER3 = 103;
+ /** @hide */
public static final int KEYCODE_USER4 = 104;
+ /** @hide */
public static final int KEYCODE_USER5 = 105;
// NOTE: If you add a new keycode here you must also add it to:
diff --git a/core/res/res/drawable-hdpi/stat_2g3g_off.png b/core/res/res/drawable-hdpi/stat_2g3g_off.png
new file mode 100644
index 0000000..3925573
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_2g3g_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_2g3g_on.png b/core/res/res/drawable-hdpi/stat_2g3g_on.png
new file mode 100644
index 0000000..027713e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_2g3g_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_3g_on.png b/core/res/res/drawable-hdpi/stat_3g_on.png
new file mode 100644
index 0000000..3e6fd22
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_3g_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_airplane_off.png b/core/res/res/drawable-hdpi/stat_airplane_off.png
new file mode 100644
index 0000000..0c73ad3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_airplane_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_airplane_on.png b/core/res/res/drawable-hdpi/stat_airplane_on.png
new file mode 100644
index 0000000..4439a92
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_airplane_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_bgoff.9.png b/core/res/res/drawable-hdpi/stat_bgoff.9.png
new file mode 100644
index 0000000..e288cb2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_bgoff.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_bgon.9.png b/core/res/res/drawable-hdpi/stat_bgon.9.png
new file mode 100644
index 0000000..b27a5cb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_bgon.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_bgon_custom.9.png b/core/res/res/drawable-hdpi/stat_bgon_custom.9.png
new file mode 100644
index 0000000..3c1439b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_bgon_custom.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_bluetooth_off.png b/core/res/res/drawable-hdpi/stat_bluetooth_off.png
new file mode 100644
index 0000000..6f0aecd
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_bluetooth_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_bluetooth_on.png b/core/res/res/drawable-hdpi/stat_bluetooth_on.png
new file mode 100644
index 0000000..72c38f4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_bluetooth_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_brightness_auto.png b/core/res/res/drawable-hdpi/stat_brightness_auto.png
new file mode 100644
index 0000000..89836c1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_brightness_auto.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_brightness_mid.png b/core/res/res/drawable-hdpi/stat_brightness_mid.png
new file mode 100644
index 0000000..b464c17
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_brightness_mid.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_brightness_off.png b/core/res/res/drawable-hdpi/stat_brightness_off.png
new file mode 100644
index 0000000..3568bd3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_brightness_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_brightness_on.png b/core/res/res/drawable-hdpi/stat_brightness_on.png
new file mode 100644
index 0000000..03d6ef2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_brightness_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_data_off.png b/core/res/res/drawable-hdpi/stat_data_off.png
new file mode 100644
index 0000000..2ce8743
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_data_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_data_on.png b/core/res/res/drawable-hdpi/stat_data_on.png
new file mode 100644
index 0000000..8a6b0bc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_data_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_flashlight_off.png b/core/res/res/drawable-hdpi/stat_flashlight_off.png
new file mode 100644
index 0000000..ce1cfc6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_flashlight_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_flashlight_on.png b/core/res/res/drawable-hdpi/stat_flashlight_on.png
new file mode 100644
index 0000000..562e86c
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_flashlight_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_gps_off.png b/core/res/res/drawable-hdpi/stat_gps_off.png
new file mode 100644
index 0000000..b23e94d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_gps_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_gps_on.png b/core/res/res/drawable-hdpi/stat_gps_on.png
new file mode 100644
index 0000000..ff4ce31
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_ing_off.png b/core/res/res/drawable-hdpi/stat_ing_off.png
new file mode 100644
index 0000000..1e856a8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_ing_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_inner_focus.9.png b/core/res/res/drawable-hdpi/stat_inner_focus.9.png
new file mode 100644
index 0000000..ed79969
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_inner_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_inner_press.9.png b/core/res/res/drawable-hdpi/stat_inner_press.9.png
new file mode 100644
index 0000000..b1b6cab
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_inner_press.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_lock_screen_off.png b/core/res/res/drawable-hdpi/stat_lock_screen_off.png
new file mode 100644
index 0000000..9dc91a2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_lock_screen_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_lock_screen_on.png b/core/res/res/drawable-hdpi/stat_lock_screen_on.png
new file mode 100644
index 0000000..1a63f37
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_lock_screen_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_orientation_off.png b/core/res/res/drawable-hdpi/stat_orientation_off.png
new file mode 100644
index 0000000..d2d2740
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_orientation_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_orientation_on.png b/core/res/res/drawable-hdpi/stat_orientation_on.png
new file mode 100644
index 0000000..9595f10
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_orientation_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_power_background.9.png b/core/res/res/drawable-hdpi/stat_power_background.9.png
new file mode 100644
index 0000000..3204d1d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_power_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_ring_on.png b/core/res/res/drawable-hdpi/stat_ring_on.png
new file mode 100644
index 0000000..ad227af
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_ring_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_screen_timeout_off.png b/core/res/res/drawable-hdpi/stat_screen_timeout_off.png
new file mode 100644
index 0000000..a1381a3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_screen_timeout_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_screen_timeout_on.png b/core/res/res/drawable-hdpi/stat_screen_timeout_on.png
new file mode 100644
index 0000000..09113f5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_screen_timeout_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_silent.png b/core/res/res/drawable-hdpi/stat_silent.png
new file mode 100644
index 0000000..f8db8e6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_silent.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sync_off.png b/core/res/res/drawable-hdpi/stat_sync_off.png
new file mode 100644
index 0000000..2c40fc3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sync_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sync_on.png b/core/res/res/drawable-hdpi/stat_sync_on.png
new file mode 100644
index 0000000..f1f0152
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sync_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_vibrate_off.png b/core/res/res/drawable-hdpi/stat_vibrate_off.png
new file mode 100644
index 0000000..999a62d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_vibrate_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_vibrate_on.png b/core/res/res/drawable-hdpi/stat_vibrate_on.png
new file mode 100644
index 0000000..263b1a8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_vibrate_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_wifi_ap_off.png b/core/res/res/drawable-hdpi/stat_wifi_ap_off.png
new file mode 100644
index 0000000..67ceff7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_wifi_ap_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_wifi_ap_on.png b/core/res/res/drawable-hdpi/stat_wifi_ap_on.png
new file mode 100644
index 0000000..0f2da2b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_wifi_ap_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_wifi_off.png b/core/res/res/drawable-hdpi/stat_wifi_off.png
new file mode 100644
index 0000000..ffe7e42
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_wifi_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_wifi_on.png b/core/res/res/drawable-hdpi/stat_wifi_on.png
new file mode 100644
index 0000000..1e30e4e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_wifi_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_2g3g_off.png b/core/res/res/drawable-mdpi/stat_2g3g_off.png
new file mode 100644
index 0000000..66a0d18
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_2g3g_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_2g3g_on.png b/core/res/res/drawable-mdpi/stat_2g3g_on.png
new file mode 100644
index 0000000..028d228
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_2g3g_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_3g_on.png b/core/res/res/drawable-mdpi/stat_3g_on.png
new file mode 100644
index 0000000..88ce5d4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_3g_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_airplane_off.png b/core/res/res/drawable-mdpi/stat_airplane_off.png
new file mode 100644
index 0000000..ba6d41d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_airplane_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_airplane_on.png b/core/res/res/drawable-mdpi/stat_airplane_on.png
new file mode 100644
index 0000000..73cdb50
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_airplane_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_bgoff.9.png b/core/res/res/drawable-mdpi/stat_bgoff.9.png
new file mode 100644
index 0000000..e288cb2
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_bgoff.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_bgon.9.png b/core/res/res/drawable-mdpi/stat_bgon.9.png
new file mode 100644
index 0000000..b27a5cb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_bgon.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_bgon_custom.9.png b/core/res/res/drawable-mdpi/stat_bgon_custom.9.png
new file mode 100644
index 0000000..3c1439b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_bgon_custom.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_bluetooth_off.png b/core/res/res/drawable-mdpi/stat_bluetooth_off.png
new file mode 100644
index 0000000..658afc4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_bluetooth_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_bluetooth_on.png b/core/res/res/drawable-mdpi/stat_bluetooth_on.png
new file mode 100644
index 0000000..1b59eac
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_bluetooth_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_brightness_auto.png b/core/res/res/drawable-mdpi/stat_brightness_auto.png
new file mode 100644
index 0000000..ca6d92e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_brightness_auto.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_brightness_mid.png b/core/res/res/drawable-mdpi/stat_brightness_mid.png
new file mode 100644
index 0000000..147681b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_brightness_mid.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_brightness_off.png b/core/res/res/drawable-mdpi/stat_brightness_off.png
new file mode 100644
index 0000000..c6f9120
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_brightness_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_brightness_on.png b/core/res/res/drawable-mdpi/stat_brightness_on.png
new file mode 100644
index 0000000..eb77b7f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_brightness_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_data_off.png b/core/res/res/drawable-mdpi/stat_data_off.png
new file mode 100644
index 0000000..178a1a7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_data_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_data_on.png b/core/res/res/drawable-mdpi/stat_data_on.png
new file mode 100644
index 0000000..bd7b32c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_data_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_flashlight_off.png b/core/res/res/drawable-mdpi/stat_flashlight_off.png
new file mode 100644
index 0000000..1d80e45
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_flashlight_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_flashlight_on.png b/core/res/res/drawable-mdpi/stat_flashlight_on.png
new file mode 100644
index 0000000..bcc9296
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_flashlight_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_gps_off.png b/core/res/res/drawable-mdpi/stat_gps_off.png
new file mode 100644
index 0000000..5720a78
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_gps_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_gps_on.png b/core/res/res/drawable-mdpi/stat_gps_on.png
new file mode 100644
index 0000000..385e3ac
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_inner_focus.9.png b/core/res/res/drawable-mdpi/stat_inner_focus.9.png
new file mode 100644
index 0000000..ed79969
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_inner_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_inner_press.9.png b/core/res/res/drawable-mdpi/stat_inner_press.9.png
new file mode 100644
index 0000000..b1b6cab
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_inner_press.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_lock_screen_off.png b/core/res/res/drawable-mdpi/stat_lock_screen_off.png
new file mode 100644
index 0000000..1c77ff3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_lock_screen_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_ock_screen_on.png b/core/res/res/drawable-mdpi/stat_ock_screen_on.png
new file mode 100644
index 0000000..3ac6448
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_ock_screen_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_orientation_off.png b/core/res/res/drawable-mdpi/stat_orientation_off.png
new file mode 100644
index 0000000..fd5c9d0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_orientation_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_orientation_on.png b/core/res/res/drawable-mdpi/stat_orientation_on.png
new file mode 100644
index 0000000..b98fc38
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_orientation_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_power_background.9.png b/core/res/res/drawable-mdpi/stat_power_background.9.png
new file mode 100644
index 0000000..3204d1d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_power_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_power_bg.9.png b/core/res/res/drawable-mdpi/stat_power_bg.9.png
new file mode 100644
index 0000000..b54a91c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_power_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_ring_off.png b/core/res/res/drawable-mdpi/stat_ring_off.png
new file mode 100644
index 0000000..090b132
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_ring_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_ring_on.png b/core/res/res/drawable-mdpi/stat_ring_on.png
new file mode 100644
index 0000000..5bd3ffa
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_ring_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_screen_timeout_off.png b/core/res/res/drawable-mdpi/stat_screen_timeout_off.png
new file mode 100644
index 0000000..d3f8fb2
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_screen_timeout_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_screen_timeout_on.png b/core/res/res/drawable-mdpi/stat_screen_timeout_on.png
new file mode 100644
index 0000000..fe18abe
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_screen_timeout_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_silent.png b/core/res/res/drawable-mdpi/stat_silent.png
new file mode 100644
index 0000000..ce206e8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_silent.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sound_vibrate_on.png b/core/res/res/drawable-mdpi/stat_sound_vibrate_on.png
new file mode 100644
index 0000000..bbc9edc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sound_vibrate_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sync_off.png b/core/res/res/drawable-mdpi/stat_sync_off.png
new file mode 100644
index 0000000..2f7ffbd
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sync_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sync_on.png b/core/res/res/drawable-mdpi/stat_sync_on.png
new file mode 100644
index 0000000..aa56b82
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sync_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_vibrate_off.png b/core/res/res/drawable-mdpi/stat_vibrate_off.png
new file mode 100644
index 0000000..17773de
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_vibrate_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_vibrate_on.png b/core/res/res/drawable-mdpi/stat_vibrate_on.png
new file mode 100644
index 0000000..3723c38
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_vibrate_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_wifi_ap_off.png b/core/res/res/drawable-mdpi/stat_wifi_ap_off.png
new file mode 100644
index 0000000..cc1ff46
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_wifi_ap_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_wifi_ap_on.png b/core/res/res/drawable-mdpi/stat_wifi_ap_on.png
new file mode 100644
index 0000000..667363c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_wifi_ap_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_wifi_off.png b/core/res/res/drawable-mdpi/stat_wifi_off.png
new file mode 100644
index 0000000..de981cb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_wifi_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_wifi_on.png b/core/res/res/drawable-mdpi/stat_wifi_on.png
new file mode 100644
index 0000000..5b11ae8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_wifi_on.png
Binary files differ
diff --git a/core/res/res/drawable/stat_power_bg.xml b/core/res/res/drawable/stat_power_bg.xml
new file mode 100644
index 0000000..a21b510
--- /dev/null
+++ b/core/res/res/drawable/stat_power_bg.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:state_pressed="true"
+ android:drawable="@drawable/stat_inner_press" />
+
+ <item android:state_focused="true" android:state_enabled="true"
+ android:state_window_focused="true"
+ android:drawable="@drawable/stat_inner_focus" />
+
+ <item
+ android:drawable="@drawable/stat_power_background" />
+</selector>
diff --git a/core/res/res/layout/status_bar_expanded.xml b/core/res/res/layout/status_bar_expanded.xml
index b20492a..2dac3a6 100644
--- a/core/res/res/layout/status_bar_expanded.xml
+++ b/core/res/res/layout/status_bar_expanded.xml
@@ -23,57 +23,205 @@
android:focusable="true"
android:descendantFocusability="afterDescendants"
>
-
<LinearLayout android:id="@+id/exp_view_lin_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
+ android:orientation="vertical"
android:paddingTop="3dp"
android:paddingBottom="5dp"
android:paddingRight="3dp"
android:background="@drawable/status_bar_header_background"
>
- <LinearLayout
- android:layout_width="0dp"
+ <!-- Begin Power Widget -->
+ <LinearLayout android:id="@+id/exp_power_stat"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_marginTop="1dp"
- android:layout_marginLeft="5dp"
- android:layout_gravity="center_vertical"
- android:paddingBottom="1dp"
- android:orientation="vertical"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ >
+ <LinearLayout android:id="@+id/exp_power_stat_1"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true"
+ android:visibility="gone"
+ android:background="@drawable/stat_power_bg"
>
- <TextView android:id="@+id/plmnLabel"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textColor="?android:attr/textColorSecondaryInverse"
- android:paddingLeft="4dp"
- />
- <TextView android:id="@+id/spnLabel"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textColor="?android:attr/textColorSecondaryInverse"
- android:paddingLeft="4dp"
- />
+ <ImageView android:id="@+id/exp_power_image_1"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:scaleType="center"
+ />
+ <ImageView android:id="@+id/exp_power_indic_1"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ />
+ </LinearLayout>
+ <LinearLayout android:id="@+id/exp_power_stat_2"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true"
+ android:visibility="gone"
+ android:background="@drawable/stat_power_bg"
+ >
+ <ImageView android:id="@+id/exp_power_image_2"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:scaleType="center"
+ />
+ <ImageView android:id="@+id/exp_power_indic_2"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ />
+ </LinearLayout>
+ <LinearLayout android:id="@+id/exp_power_stat_3"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true"
+ android:visibility="gone"
+ android:background="@drawable/stat_power_bg"
+ >
+ <ImageView android:id="@+id/exp_power_image_3"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:scaleType="center"
+ />
+ <ImageView android:id="@+id/exp_power_indic_3"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ />
+ </LinearLayout>
+ <LinearLayout android:id="@+id/exp_power_stat_4"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true"
+ android:visibility="gone"
+ android:background="@drawable/stat_power_bg"
+ >
+ <ImageView android:id="@+id/exp_power_image_4"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:scaleType="center"
+ />
+ <ImageView android:id="@+id/exp_power_indic_4"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ />
+ </LinearLayout>
+ <LinearLayout android:id="@+id/exp_power_stat_5"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true"
+ android:visibility="gone"
+ android:background="@drawable/stat_power_bg"
+ >
+ <ImageView android:id="@+id/exp_power_image_5"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:scaleType="center"
+ />
+ <ImageView android:id="@+id/exp_power_indic_5"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ />
+ </LinearLayout>
+ <LinearLayout android:id="@+id/exp_power_stat_6"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true"
+ android:visibility="gone"
+ android:background="@drawable/stat_power_bg"
+ >
+ <ImageView android:id="@+id/exp_power_image_6"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:scaleType="center"
+ />
+ <ImageView android:id="@+id/exp_power_indic_6"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ />
+ </LinearLayout>
</LinearLayout>
- <TextView android:id="@+id/clear_all_button"
- android:layout_width="wrap_content"
+ <!-- End Power Widget -->
+
+ <LinearLayout
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginTop="4dp"
- android:layout_marginBottom="1dp"
- android:textSize="14sp"
- android:textColor="#ff000000"
- android:text="@string/status_bar_clear_all_button"
- style="?android:attr/buttonStyle"
- android:paddingLeft="15dp"
- android:paddingRight="15dp"
- android:background="@drawable/btn_default_small"
- />
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ >
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginTop="1dp"
+ android:layout_marginLeft="5dp"
+ android:layout_gravity="center_vertical"
+ android:paddingBottom="1dp"
+ android:orientation="vertical"
+ >
+ <TextView android:id="@+id/plmnLabel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textColor="?android:attr/textColorSecondaryInverse"
+ android:paddingLeft="4dp"
+ />
+ <TextView android:id="@+id/spnLabel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textColor="?android:attr/textColorSecondaryInverse"
+ android:paddingLeft="4dp"
+ />
+ </LinearLayout>
+ <TextView android:id="@+id/clear_all_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:layout_marginTop="4dp"
+ android:layout_marginBottom="1dp"
+ android:textSize="14sp"
+ android:textColor="#ff000000"
+ android:text="@string/status_bar_clear_all_button"
+ style="?android:attr/buttonStyle"
+ android:paddingLeft="15dp"
+ android:paddingRight="15dp"
+ android:background="@drawable/btn_default_small"
+ />
+ </LinearLayout>
</LinearLayout>
<FrameLayout
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index 3c31368..7c99b84 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -24,22 +24,30 @@ import android.app.Dialog;
import android.app.IStatusBar;
import android.app.PendingIntent;
import android.app.StatusBarManager;
+import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.location.LocationManager;
+import android.media.AudioManager;
import android.net.Uri;
+import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.Binder;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
+import android.provider.Settings;
import android.provider.Telephony;
import android.util.Log;
import android.util.Slog;
@@ -66,6 +74,8 @@ import android.widget.FrameLayout;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.List;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;
@@ -75,6 +85,20 @@ import java.lang.reflect.Field;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.StateListDrawable;
+import com.android.server.status.widget.PowerButton;
+import com.android.server.status.widget.GPSButton;
+import com.android.server.status.widget.WifiButton;
+import com.android.server.status.widget.BluetoothButton;
+import com.android.server.status.widget.BrightnessButton;
+import com.android.server.status.widget.SoundButton;
+import com.android.server.status.widget.SyncButton;
+import com.android.server.status.widget.WifiApButton;
+import com.android.server.status.widget.ScreenTimeoutButton;
+import com.android.server.status.widget.MobileDataButton;
+import com.android.server.status.widget.NetworkModeButton;
+import com.android.server.status.widget.LockScreenButton;
+import com.android.server.status.widget.AutoRotateButton;
+import com.android.server.status.widget.AirplaneButton;
/**
* The public (ok, semi-public) service for the status bar.
@@ -112,7 +136,7 @@ public class StatusBarService extends IStatusBar.Stub
private static final int OP_EXPAND = 5;
private static final int OP_TOGGLE = 6;
private static final int OP_DISABLE = 7;
-
+
private class PendingOp {
IBinder key;
int code;
@@ -165,7 +189,7 @@ public class StatusBarService extends IStatusBar.Stub
final Display mDisplay;
StatusBarView mStatusBarView;
int mPixelFormat;
- H mHandler = new H();
+ H mHandler;
Object mQueueLock = new Object();
ArrayList<PendingOp> mQueue = new ArrayList<PendingOp>();
NotificationCallbacks mNotificationCallbacks;
@@ -255,6 +279,8 @@ public class StatusBarService extends IStatusBar.Stub
Drawable expBarNotifTitleDrawable;
+ private WifiManager mWifiManager = null;
+ private BluetoothAdapter mBluetoothAdapter = null;
// for disabling the status bar
ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
int mDisabled = 0;
@@ -264,6 +290,7 @@ public class StatusBarService extends IStatusBar.Stub
*/
public StatusBarService(Context context) {
mContext = context;
+ mHandler = new H();
notificationTitleColor = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NOTIF_ITEM_TITLE_COLOR, blackColor);
notificationTextColor = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NOTIF_ITEM_TEXT_COLOR, blackColor);
notificationTimeColor = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NOTIF_ITEM_TIME_COLOR, blackColor);
@@ -272,6 +299,8 @@ public class StatusBarService extends IStatusBar.Stub
makeStatusBarView(context);
updateColors();
mUninstallReceiver = new UninstallReceiver();
+ SettingsObserver observer = new SettingsObserver(mHandler);
+ observer.observe();
}
public void setNotificationCallbacks(NotificationCallbacks listener) {
@@ -332,15 +361,15 @@ public class StatusBarService extends IStatusBar.Stub
mScrollView = (ScrollView)expanded.findViewById(R.id.scroll);
mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout);
if (custExpBar) {
- mExpandedView.findViewById(R.id.exp_view_lin_layout).
- setBackgroundDrawable(expBarHeadDrawable);
- mNoNotificationsTitle.setBackgroundDrawable(expBarNotifTitleDrawable);
- mOngoingTitle.setBackgroundDrawable(expBarNotifTitleDrawable);
- mLatestTitle.setBackgroundDrawable(expBarNotifTitleDrawable);
- }
+ mExpandedView.findViewById(R.id.exp_view_lin_layout).
+ setBackgroundDrawable(expBarHeadDrawable);
+ mNoNotificationsTitle.setBackgroundDrawable(expBarNotifTitleDrawable);
+ mOngoingTitle.setBackgroundDrawable(expBarNotifTitleDrawable);
+ mLatestTitle.setBackgroundDrawable(expBarNotifTitleDrawable);
+ }
mOngoingTitle.setVisibility(View.GONE);
mLatestTitle.setVisibility(View.GONE);
-
+
mTicker = new MyTicker(context, sb);
tickerView = (TickerView)sb.findViewById(R.id.tickerText);
@@ -384,6 +413,12 @@ public class StatusBarService extends IStatusBar.Stub
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Telephony.Intents.SPN_STRINGS_UPDATED_ACTION);
+ filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+ filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
+ filter.addAction(Settings.SETTINGS_CHANGED);
+ filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
+ filter.addAction(NetworkModeButton.NETWORK_MODE_CHANGED);
context.registerReceiver(mBroadcastReceiver, filter);
}
@@ -400,10 +435,13 @@ public class StatusBarService extends IStatusBar.Stub
lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
lp.setTitle("StatusBar");
lp.windowAnimations = R.style.Animation_StatusBar;
-
WindowManagerImpl.getDefault().addView(view, lp);
+
+ mWifiManager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ setupPowerWidget();
}
-
+
// ================================================================================
// From IStatusBar
// ================================================================================
@@ -1848,7 +1886,7 @@ public class StatusBarService extends IStatusBar.Stub
}
}
}
-
+
private void updateColors() {
mDateView.setTextColor(Settings.System.getInt(mContext.getContentResolver(), Settings.System.DATE_COLOR, blackColor));
mNoNotificationsTitle.setTextColor(Settings.System.getInt(mContext.getContentResolver(), Settings.System.NO_NOTIF_COLOR, whiteColor));
@@ -1866,7 +1904,156 @@ public class StatusBarService extends IStatusBar.Stub
addPendingOp(OP_EXPAND, null, false);
}
};
-
+
+ /** Power Widget **/
+
+ private View.OnClickListener mPowerListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ LinearLayout layout = (LinearLayout)v;
+ String type = (String)layout.getTag();
+ if(PowerButton.TOGGLE_WIFI.equals(type)) {
+ WifiButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_GPS.equals(type)) {
+ GPSButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_BLUETOOTH.equals(type)) {
+ BluetoothButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_BRIGHTNESS.equals(type)) {
+ BrightnessButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_SOUND.equals(type)) {
+ SoundButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_SYNC.equals(type)) {
+ SyncButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_WIFIAP.equals(type)) {
+ WifiApButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_SCREENTIMEOUT.equals(type)) {
+ ScreenTimeoutButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_MOBILEDATA.equals(type)) {
+ MobileDataButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_LOCKSCREEN.equals(type)) {
+ LockScreenButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_NETWORKMODE.equals(type)) {
+ NetworkModeButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_AUTOROTATE.equals(type)) {
+ AutoRotateButton.getInstance().toggleState(mContext);
+ } else if(PowerButton.TOGGLE_AIRPLANE.equals(type)) {
+ AirplaneButton.getInstance().toggleState(mContext);
+ }
+ updateWidget();
+ }
+ };
+
+ private void setupPowerWidget() {
+ LinearLayout layout;
+ String lists = Settings.System.getString(mContext.getContentResolver(),
+ Settings.System.WIDGET_BUTTONS);
+ Log.i("setupPowerWidget", "List: "+lists);
+ if(lists == null) {
+ lists = "toggleWifi|toggleBluetooth|toggleGPS|toggleSound";
+ }
+ List<String> list = Arrays.asList(lists.split("\\|"));
+ clearWidget();
+
+ int posi;
+ for(posi = 0; posi < list.size(); posi++) {
+ layout = (LinearLayout)mExpandedView.findViewById(PowerButton.getLayoutID(posi + 1));
+ String buttonType = list.get(posi);
+ layout.setVisibility(View.VISIBLE);
+ layout.setTag(list.get(posi));
+ layout.setOnClickListener(mPowerListener);
+ setupWidget(buttonType, posi + 1);
+ }
+ updateWidget();
+ }
+
+ private void setupWidget(String buttonType, int position) {
+
+ if(PowerButton.TOGGLE_WIFI.equals(buttonType)) {
+ WifiButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_GPS.equals(buttonType)) {
+ GPSButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_BLUETOOTH.equals(buttonType)) {
+ BluetoothButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_BRIGHTNESS.equals(buttonType)) {
+ BrightnessButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_SOUND.equals(buttonType)) {
+ SoundButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_SYNC.equals(buttonType)) {
+ SyncButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_WIFIAP.equals(buttonType)) {
+ WifiApButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_SCREENTIMEOUT.equals(buttonType)) {
+ ScreenTimeoutButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_MOBILEDATA.equals(buttonType)) {
+ MobileDataButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_LOCKSCREEN.equals(buttonType)) {
+ LockScreenButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_NETWORKMODE.equals(buttonType)) {
+ NetworkModeButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_AUTOROTATE.equals(buttonType)) {
+ AutoRotateButton.getInstance().setupButton(position);
+ } else if(PowerButton.TOGGLE_AIRPLANE.equals(buttonType)) {
+ AirplaneButton.getInstance().setupButton(position);
+ }
+
+ }
+
+ private void clearWidget() {
+ for(int posi = 0; posi < 6; posi++) {
+ LinearLayout layout = (LinearLayout)mExpandedView.findViewById(PowerButton.getLayoutID(posi + 1));
+ layout.setVisibility(View.GONE);
+ layout.setTag("");
+ }
+ WifiButton.getInstance().setupButton(0);
+ GPSButton.getInstance().setupButton(0);
+ BluetoothButton.getInstance().setupButton(0);
+ BrightnessButton.getInstance().setupButton(0);
+ SoundButton.getInstance().setupButton(0);
+ SyncButton.getInstance().setupButton(0);
+ WifiApButton.getInstance().setupButton(0);
+ ScreenTimeoutButton.getInstance().setupButton(0);
+ MobileDataButton.getInstance().setupButton(0);
+ LockScreenButton.getInstance().setupButton(0);
+ NetworkModeButton.getInstance().setupButton(0);
+ AutoRotateButton.getInstance().setupButton(0);
+ AirplaneButton.getInstance().setupButton(0);
+ }
+
+ private void updateStates() {
+ GPSButton.getInstance().updateState(mContext);
+ WifiButton.getInstance().updateState(mContext);
+ BluetoothButton.getInstance().updateState(mContext);
+ BrightnessButton.getInstance().updateState(mContext);
+ SoundButton.getInstance().updateState(mContext);
+ SyncButton.getInstance().updateState(mContext);
+ WifiApButton.getInstance().updateState(mContext);
+ ScreenTimeoutButton.getInstance().updateState(mContext);
+ MobileDataButton.getInstance().updateState(mContext);
+ LockScreenButton.getInstance().updateState(mContext);
+ NetworkModeButton.getInstance().updateState(mContext);
+ AutoRotateButton.getInstance().updateState(mContext);
+ AirplaneButton.getInstance().updateState(mContext);
+ }
+ private void updateViews() {
+ GPSButton.getInstance().updateView(mContext, mExpandedView);
+ WifiButton.getInstance().updateView(mContext, mExpandedView);
+ BluetoothButton.getInstance().updateView(mContext, mExpandedView);
+ BrightnessButton.getInstance().updateView(mContext, mExpandedView);
+ SoundButton.getInstance().updateView(mContext, mExpandedView);
+ SyncButton.getInstance().updateView(mContext, mExpandedView);
+ WifiApButton.getInstance().updateView(mContext, mExpandedView);
+ ScreenTimeoutButton.getInstance().updateView(mContext, mExpandedView);
+ MobileDataButton.getInstance().updateView(mContext, mExpandedView);
+ LockScreenButton.getInstance().updateView(mContext, mExpandedView);
+ NetworkModeButton.getInstance().updateView(mContext, mExpandedView);
+ AutoRotateButton.getInstance().updateView(mContext, mExpandedView);
+ AirplaneButton.getInstance().updateView(mContext, mExpandedView);
+ }
+
+ private void updateWidget() {
+ updateStates();
+ updateViews();
+ }
+
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -1883,6 +2070,16 @@ public class StatusBarService extends IStatusBar.Stub
else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
updateResources();
}
+ else if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
+ WifiButton.getInstance().onReceive(context, intent);
+ } else if (WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent.getAction())) {
+ WifiApButton.getInstance().onReceive(context, intent);
+ } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
+ BluetoothButton.getInstance().onReceive(context, intent);
+ } else if (NetworkModeButton.NETWORK_MODE_CHANGED.equals(intent.getAction())) {
+ NetworkModeButton.getInstance().onReceive(context, intent);
+ }
+ updateWidget();
}
};
@@ -1920,7 +2117,7 @@ public class StatusBarService extends IStatusBar.Stub
/**
* Reload some of our resources when the configuration changes.
- *
+ *
* We don't reload everything when the configuration changes -- we probably
* should, but getting that smooth is tough. Someday we'll fix that. In the
* meantime, just update the things that we know change.
@@ -1969,7 +2166,7 @@ public class StatusBarService extends IStatusBar.Stub
vibrate();
}
};
-
+
class UninstallReceiver extends BroadcastReceiver {
public UninstallReceiver() {
IntentFilter filter = new IntentFilter();
@@ -1980,7 +2177,7 @@ public class StatusBarService extends IStatusBar.Stub
IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(this, sdFilter);
}
-
+
@Override
public void onReceive(Context context, Intent intent) {
String pkgList[] = null;
@@ -2003,7 +2200,7 @@ public class StatusBarService extends IStatusBar.Stub
}
}
}
-
+
if (list != null) {
final int N = list.size();
for (int i=0; i<N; i++) {
@@ -2012,7 +2209,7 @@ public class StatusBarService extends IStatusBar.Stub
}
}
}
-
+
private void getNotBarConfig() {
Resources res = mContext.getResources();
/*
@@ -2034,7 +2231,7 @@ public class StatusBarService extends IStatusBar.Stub
Settings.System.NOTIF_EXPANDED_BAR_CUSTOM, 0) == 1;
expBarColorMask = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.NOTIF_EXPANDED_BAR_COLOR, whiteColor);
- int noalpha = expBarColorMask | 0xFF000000;
+ int noalpha = expBarColorMask | 0xFF000000;
if (useCustomExp) {
closerDrawable = res.getDrawable(com.android.internal.R.drawable.status_bar_close_on_cust);
expBarHeadDrawable = res.getDrawable(com.android.internal.R.drawable.status_bar_header_background_cust,
@@ -2043,7 +2240,143 @@ public class StatusBarService extends IStatusBar.Stub
noalpha, expPDMode); // always solid
custExpBar = true;
} else {
- custExpBar = false;
- }
+ custExpBar = false;
+ }
+ }
+
+ public class SettingsObserver extends ContentObserver {
+ public SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ public void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.NOTIF_EXPANDED_BAR_CUSTOM),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.NOTIF_EXPANDED_BAR_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.NOTIF_BAR_CUSTOM),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.NOTIF_BAR_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.NOTIF_ITEM_TITLE_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.NOTIF_ITEM_TEXT_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.NOTIF_ITEM_TIME_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.DATE_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.NO_NOTIF_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.LATEST_NOTIF_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.ONGOING_NOTIF_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.SPN_LABEL_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.PLMN_LABEL_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.CLEAR_BUTTON_LABEL_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.NEW_NOTIF_TICKER_COLOR),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.EXPANDED_VIEW_WIDGET),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.AIRPLANE_MODE_ON),
+ false, this);
+
+ resolver.registerContentObserver(
+ Settings.System.getUriFor(Settings.System.WIDGET_BUTTONS),
+ false, this);
+ }
+
+ @Override
+ public void onChangeUri(Uri uri, boolean selfChange) {
+ update(uri);
+ }
+
+ public void update(Uri uri) {
+ ContentResolver resolver = mContext.getContentResolver();
+ Resources res = mContext.getResources();
+ updateColors();
+ if(uri.equals(Settings.System.getUriFor(Settings.System.NOTIF_EXPANDED_BAR_CUSTOM)) ||
+ uri.equals(Settings.System.getUriFor(Settings.System.NOTIF_EXPANDED_BAR_COLOR)) ||
+ uri.equals(Settings.System.getUriFor(Settings.System.NOTIF_BAR_CUSTOM)) ||
+ uri.equals(Settings.System.getUriFor(Settings.System.NOTIF_BAR_COLOR))) {
+
+ getNotBarConfig();
+ if (custExpBar) {
+ mExpandedView.findViewById(R.id.exp_view_lin_layout).
+ setBackgroundDrawable(expBarHeadDrawable);
+ mNoNotificationsTitle.setBackgroundDrawable(expBarNotifTitleDrawable);
+ mOngoingTitle.setBackgroundDrawable(expBarNotifTitleDrawable);
+ mLatestTitle.setBackgroundDrawable(expBarNotifTitleDrawable);
+ }
+ if (custNotBar) {
+ mStatusBarView.setBackgroundDrawable(
+ res.getDrawable(com.android.internal.R.drawable.statusbar_background_sq,
+ notifBarColorMask, notifPDMode));
+ mDateView.setBackgroundDrawable(
+ res.getDrawable(com.android.internal.R.drawable.statusbar_background_sq,
+ notifBarColorMask, notifPDMode));
+ mDateView.setPadding(6, 0, 6, 0);
+ }
+ } else if(uri.equals(Settings.System.getUriFor(Settings.System.WIDGET_BUTTONS))) {
+ setupPowerWidget();
+ }
+
+ boolean powerWidget = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_VIEW_WIDGET, 0) == 1;
+ if(!powerWidget) {
+ mExpandedView.findViewById(R.id.exp_power_stat).
+ setVisibility(View.GONE);
+ } else {
+ mExpandedView.findViewById(R.id.exp_power_stat).
+ setVisibility(View.VISIBLE);
+ }
+ updateWidget();
+ }
}
}
diff --git a/services/java/com/android/server/status/widget/AirplaneButton.java b/services/java/com/android/server/status/widget/AirplaneButton.java
new file mode 100755
index 0000000..c7a4df7
--- /dev/null
+++ b/services/java/com/android/server/status/widget/AirplaneButton.java
@@ -0,0 +1,63 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.provider.Settings;
+
+public class AirplaneButton extends PowerButton {
+
+ static AirplaneButton ownButton=null;
+
+ public void updateState(Context context) {
+ if (getState(context)) {
+ currentIcon = R.drawable.stat_airplane_on;
+ currentState = PowerButton.STATE_ENABLED;
+ } else {
+ currentIcon = R.drawable.stat_airplane_off;
+ currentState = PowerButton.STATE_DISABLED;
+ }
+
+ }
+
+ /**
+ * Toggles the state of Airplane
+ *
+ * @param context
+ */
+ public void toggleState(Context context) {
+ boolean state = getState(context);
+ Settings.System.putInt(context.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON, state ? 0 : 1);
+ // notify change
+ Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.putExtra("state", state);
+ context.sendBroadcast(intent);
+ }
+
+ /**
+ * Gets the state of Airplane.
+ *
+ * @param context
+ * @return true if enabled.
+ */
+ private static boolean getState(Context context) {
+ return Settings.System.getInt(context.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON,0) == 1;
+ }
+
+
+ public static AirplaneButton getInstance() {
+ if (ownButton==null) ownButton = new AirplaneButton();
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int poisition) {
+ }
+
+}
+
diff --git a/services/java/com/android/server/status/widget/AutoRotateButton.java b/services/java/com/android/server/status/widget/AutoRotateButton.java
new file mode 100755
index 0000000..501404a
--- /dev/null
+++ b/services/java/com/android/server/status/widget/AutoRotateButton.java
@@ -0,0 +1,50 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+
+import android.content.Context;
+import android.provider.Settings;
+
+public class AutoRotateButton extends PowerButton {
+
+ static AutoRotateButton ownButton = null;
+
+ @Override
+ public void toggleState(Context context) {
+ if(getOrientationState(context) == 0) {
+ Settings.System.putInt(
+ context.getContentResolver(),
+ Settings.System.ACCELEROMETER_ROTATION, 1);
+ } else {
+ Settings.System.putInt(
+ context.getContentResolver(),
+ Settings.System.ACCELEROMETER_ROTATION, 0);
+ } }
+
+ @Override
+ public void updateState(Context context) {
+ if (getOrientationState(context) == 1) {
+ currentIcon = R.drawable.stat_orientation_on;
+ currentState = PowerButton.STATE_ENABLED;
+ } else {
+ currentIcon = R.drawable.stat_orientation_off;
+ currentState = PowerButton.STATE_DISABLED;
+ }
+ }
+
+ public static int getOrientationState(Context context) {
+ return Settings.System.getInt(
+ context.getContentResolver(),
+ Settings.System.ACCELEROMETER_ROTATION, 0);
+ }
+
+ public static AutoRotateButton getInstance() {
+ if (ownButton == null) ownButton = new AutoRotateButton();
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+}
diff --git a/services/java/com/android/server/status/widget/BluetoothButton.java b/services/java/com/android/server/status/widget/BluetoothButton.java
new file mode 100755
index 0000000..4461a54
--- /dev/null
+++ b/services/java/com/android/server/status/widget/BluetoothButton.java
@@ -0,0 +1,141 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+import com.android.server.status.widget.StateTracker;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class BluetoothButton extends PowerButton{
+
+ private static final StateTracker sBluetoothState = new BluetoothStateTracker();
+
+ static BluetoothButton ownButton = null;
+
+
+ /**
+ * Subclass of StateTracker to get/set Bluetooth state.
+ */
+ private static final class BluetoothStateTracker extends StateTracker {
+
+ @Override
+ public int getActualState(Context context) {
+ BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (mBluetoothAdapter == null) {
+ return PowerButton.STATE_UNKNOWN; // On emulator?
+ }
+ return bluetoothStateToFiveState(mBluetoothAdapter
+ .getState());
+ }
+
+ @Override
+ protected void requestStateChange(Context context,
+ final boolean desiredState) {
+ // Actually request the Bluetooth change and persistent
+ // settings write off the UI thread, as it can take a
+ // user-noticeable amount of time, especially if there's
+ // disk contention.
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... args) {
+ BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if(mBluetoothAdapter.isEnabled()) {
+ mBluetoothAdapter.disable();
+ } else {
+ mBluetoothAdapter.enable();
+ }
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onActualStateChange(Context context, Intent intent) {
+ if (!BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent
+ .getAction())) {
+ return;
+ }
+ int bluetoothState = intent.getIntExtra(
+ BluetoothAdapter.EXTRA_STATE, -1);
+ setCurrentState(context, bluetoothStateToFiveState(bluetoothState));
+ }
+
+ /**
+ * Converts BluetoothAdapter's state values into our
+ * Wifi/Bluetooth-common state values.
+ */
+ private static int bluetoothStateToFiveState(int bluetoothState) {
+ switch (bluetoothState) {
+ case BluetoothAdapter.STATE_OFF:
+ return PowerButton.STATE_DISABLED;
+ case BluetoothAdapter.STATE_ON:
+ return PowerButton.STATE_ENABLED;
+ case BluetoothAdapter.STATE_TURNING_ON:
+ return PowerButton.STATE_TURNING_ON;
+ case BluetoothAdapter.STATE_TURNING_OFF:
+ return PowerButton.STATE_TURNING_OFF;
+ default:
+ return PowerButton.STATE_UNKNOWN;
+ }
+ }
+ }
+
+
+
+ public static BluetoothButton getInstance() {
+ if (ownButton == null) ownButton = new BluetoothButton();
+
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+
+ @Override
+ public void toggleState(Context context) {
+ sBluetoothState.toggleState(context);
+ }
+
+ @Override
+ public void updateState(Context context) {
+ currentState = sBluetoothState.getTriState(context);
+ switch (currentState) {
+ case PowerButton.STATE_DISABLED:
+ currentIcon = R.drawable.stat_bluetooth_off;
+ break;
+ case PowerButton.STATE_ENABLED:
+ currentIcon = R.drawable.stat_bluetooth_on;
+ break;
+ case PowerButton.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()) {
+ currentIcon = R.drawable.stat_bluetooth_on;
+ } else {
+ currentIcon = R.drawable.stat_bluetooth_off;
+ }
+ break;
+ }
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ sBluetoothState.onActualStateChange(context, intent);
+ }
+
+ public void toggleState(Context context, int newState) {
+ int curState = sBluetoothState.getTriState(context);
+ if (curState != PowerButton.STATE_INTERMEDIATE &&
+ curState != newState) {
+ toggleState(context);
+ }
+ }
+}
diff --git a/services/java/com/android/server/status/widget/BrightnessButton.java b/services/java/com/android/server/status/widget/BrightnessButton.java
new file mode 100755
index 0000000..9a4e098
--- /dev/null
+++ b/services/java/com/android/server/status/widget/BrightnessButton.java
@@ -0,0 +1,253 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.IPowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.util.Log;
+
+public class BrightnessButton extends PowerButton {
+
+ /**
+ * 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 int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f);
+
+ private static int LOW_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.25f);
+ private static int MID_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.5f);
+ private static int HIGH_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.75f);
+
+ private static final int AUTO_BACKLIGHT = -1;
+
+ private static final int MODE_AUTO_MIN_DEF_MAX=0;
+ private static final int MODE_AUTO_MIN_LOW_MID_HIGH_MAX=1;
+ private static final int MODE_AUTO_LOW_MAX=2;
+ private static final int MODE_MIN_MAX=3;
+
+ private static final int DEFAULT_SETTING = 0;
+
+ private static Boolean supportsAutomaticMode=null;
+
+ static BrightnessButton ownButton=null;
+
+ private static int currentMode;
+
+
+ /*
+ *
+Auto_Min_Low_Max
+Auto_Min . Max
+Auto. Min . Low High. Max
+Auto_Low / High
+Auto_Low / High / Max
+
+
+Min / Max
+Min Low Max
+Min Low High Max
+Low High
+Low High Max
+
+
+ */
+
+ public static int getMinBacklight(Context context) {
+ if (Settings.System.getInt(context.getContentResolver(),
+ Settings.System.LIGHT_SENSOR_CUSTOM, 0) != 0) {
+ return Settings.System.getInt(context.getContentResolver(),
+ Settings.System.LIGHT_SCREEN_DIM, MINIMUM_BACKLIGHT);
+ } else {
+ return MINIMUM_BACKLIGHT;
+ }
+ }
+
+
+ private static boolean isAutomaticModeSupported(Context context) {
+ if (supportsAutomaticMode == null) {
+ if (context
+ .getResources()
+ .getBoolean(
+ com.android.internal.R.bool.config_automatic_brightness_available)) {
+ supportsAutomaticMode=true;
+ } else {
+ supportsAutomaticMode=false;
+ }
+ }
+ return supportsAutomaticMode;
+ }
+
+ /**
+ * Gets state of brightness mode.
+ *
+ * @param context
+ * @return true if auto brightness is on.
+ */
+ private static boolean isBrightnessSetToAutomatic(Context context) {
+ try {
+ IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager
+ .getService("power"));
+ if (power != null) {
+ int brightnessMode = Settings.System.getInt(context
+ .getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS_MODE);
+ return brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
+ }
+ } catch (Exception e) {
+ Log.d("PowerWidget", "getBrightnessMode: " + e);
+ }
+ return false;
+ }
+
+
+
+ private int getNextBrightnessValue(Context context) {
+ int brightness = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS,0);
+
+ if (isAutomaticModeSupported(context) && isBrightnessSetToAutomatic(context)) {
+ if (currentMode == MODE_AUTO_LOW_MAX) {
+ return LOW_BACKLIGHT;
+ } else {
+ return getMinBacklight(context);
+ }
+ } else if (brightness < LOW_BACKLIGHT) {
+ if (currentMode == MODE_AUTO_LOW_MAX) {
+ return LOW_BACKLIGHT;
+ } else if (currentMode == MODE_MIN_MAX) {
+ return MAXIMUM_BACKLIGHT;
+ } else {
+ return DEFAULT_BACKLIGHT;
+ }
+ } else if (brightness < DEFAULT_BACKLIGHT) {
+ if (currentMode == MODE_AUTO_MIN_DEF_MAX) {
+ return DEFAULT_BACKLIGHT;
+ } else if (currentMode == MODE_AUTO_LOW_MAX || currentMode == MODE_MIN_MAX) {
+ return MAXIMUM_BACKLIGHT;
+ } else {
+ return MID_BACKLIGHT;
+ }
+ } else if (brightness < MID_BACKLIGHT) {
+ if (currentMode == MODE_AUTO_MIN_LOW_MID_HIGH_MAX) {
+ return MID_BACKLIGHT;
+ } else {
+ return MAXIMUM_BACKLIGHT;
+ }
+ } else if (brightness < HIGH_BACKLIGHT) {
+ if (currentMode == MODE_AUTO_MIN_LOW_MID_HIGH_MAX) {
+ return HIGH_BACKLIGHT;
+ } else {
+ return MAXIMUM_BACKLIGHT;
+ }
+ } else if (brightness < MAXIMUM_BACKLIGHT) {
+ return MAXIMUM_BACKLIGHT;
+ } else if (isAutomaticModeSupported(context) && currentMode!=MODE_MIN_MAX) {
+ return AUTO_BACKLIGHT;
+ } else if(currentMode == MODE_AUTO_LOW_MAX){
+ return LOW_BACKLIGHT;
+ } else {
+ return getMinBacklight(context);
+ }
+ }
+
+ /**
+ * Increases or decreases the brightness.
+ *
+ * @param context
+ */
+ public void toggleState(Context context) {
+ try {
+ IPowerManager power = IPowerManager.Stub.asInterface(ServiceManager
+ .getService("power"));
+ if (power != null) {
+ int brightness = getNextBrightnessValue(context);
+ ContentResolver contentResolver = context.getContentResolver();
+ if (brightness == AUTO_BACKLIGHT) {
+ Settings.System.putInt(contentResolver,
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
+ } else {
+ if (isAutomaticModeSupported(context)) {
+ Settings.System.putInt(contentResolver,
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
+ }
+ power.setBacklightBrightness(brightness);
+ Settings.System.putInt(contentResolver,
+ Settings.System.SCREEN_BRIGHTNESS, brightness);
+ }
+ }
+ } catch (RemoteException e) {
+ Log.d("PowerWidget", "toggleBrightness: " + e);
+ }
+ }
+
+
+ public static BrightnessButton getInstance() {
+ if (ownButton == null) ownButton = new BrightnessButton();
+
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+
+ @Override
+ public void updateState(Context context) {
+ currentMode = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.EXPANDED_BRIGHTNESS_MODE, DEFAULT_SETTING);
+
+ if (isBrightnessSetToAutomatic(context)) {
+ currentIcon = R.drawable.stat_brightness_auto;
+ currentState = PowerButton.STATE_ENABLED;
+ } else if (getBrightnessState(context) == PowerButton.STATE_ENABLED) {
+ currentIcon = R.drawable.stat_brightness_on;
+ currentState = PowerButton.STATE_ENABLED;
+ } else if (getBrightnessState(context) == PowerButton.STATE_TURNING_ON) {
+ currentIcon = R.drawable.stat_brightness_on;
+ currentState = PowerButton.STATE_INTERMEDIATE;
+ } else if (getBrightnessState(context) == PowerButton.STATE_TURNING_OFF) {
+ currentIcon = R.drawable.stat_brightness_off;
+ currentState = PowerButton.STATE_INTERMEDIATE;
+ } else {
+ currentIcon = R.drawable.stat_brightness_off;
+ currentState = PowerButton.STATE_DISABLED;
+ }
+ }
+
+ private int getBrightnessState(Context context) {
+ int brightness = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS,0);
+
+ if (brightness < LOW_BACKLIGHT) {
+ return PowerButton.STATE_DISABLED;
+ } else if (brightness < DEFAULT_BACKLIGHT) {
+ return PowerButton.STATE_DISABLED;
+ } else if (brightness < MID_BACKLIGHT) {
+ if (currentMode == MODE_AUTO_MIN_LOW_MID_HIGH_MAX) {
+ return PowerButton.STATE_DISABLED;
+ } else {
+ return PowerButton.STATE_TURNING_OFF;
+ }
+ } else if (brightness < HIGH_BACKLIGHT) {
+ if (currentMode == MODE_AUTO_MIN_LOW_MID_HIGH_MAX) {
+ return PowerButton.STATE_TURNING_OFF;
+ } else {
+ return PowerButton.STATE_TURNING_ON;
+ }
+ } else if (brightness < MAXIMUM_BACKLIGHT) {
+ return PowerButton.STATE_TURNING_ON;
+ } else {
+ return PowerButton.STATE_ENABLED;
+ }
+ }
+}
diff --git a/services/java/com/android/server/status/widget/GPSButton.java b/services/java/com/android/server/status/widget/GPSButton.java
new file mode 100644
index 0000000..0251745
--- /dev/null
+++ b/services/java/com/android/server/status/widget/GPSButton.java
@@ -0,0 +1,50 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.location.LocationManager;
+import android.provider.Settings;
+import android.util.Log;
+
+public class GPSButton extends PowerButton {
+ static GPSButton ownButton;
+
+ public void updateState(Context context) {
+ Log.i("GPSButton", "Update State");
+ if(getGpsState(context)) {
+ currentIcon = com.android.internal.R.drawable.stat_gps_on;
+ currentState = STATE_ENABLED;
+ } else {
+ currentIcon = com.android.internal.R.drawable.stat_gps_off;
+ currentState = STATE_DISABLED;
+ }
+ }
+
+ public void toggleState(Context context) {
+ Log.i("GPSButton", "ToggleState");
+ ContentResolver resolver = context.getContentResolver();
+ boolean enabled = getGpsState(context);
+ Settings.Secure.setLocationProviderEnabled(resolver,
+ LocationManager.GPS_PROVIDER, !enabled);
+ }
+
+ private static boolean getGpsState(Context context) {
+ ContentResolver resolver = context.getContentResolver();
+ return Settings.Secure.isLocationProviderEnabled(resolver,
+ LocationManager.GPS_PROVIDER);
+ }
+
+ public static GPSButton getInstance() {
+ if (ownButton==null) ownButton = new GPSButton();
+
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+
+}
diff --git a/services/java/com/android/server/status/widget/LockScreenButton.java b/services/java/com/android/server/status/widget/LockScreenButton.java
new file mode 100755
index 0000000..e1b205d
--- /dev/null
+++ b/services/java/com/android/server/status/widget/LockScreenButton.java
@@ -0,0 +1,92 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.app.KeyguardManager.KeyguardLock;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.view.Gravity;
+import android.widget.Toast;
+
+public class LockScreenButton extends PowerButton {
+
+ static Boolean lockScreen = null;
+
+ public static final String LOCK_SCREEN = "lockScreen";
+ static LockScreenButton ownButton = null;
+ KeyguardLock lock;
+
+ private KeyguardLock getLock(Context context) {
+ if (lock == null) {
+ KeyguardManager keyguardManager = (KeyguardManager)context.
+ getSystemService(Activity.KEYGUARD_SERVICE);
+ lock = keyguardManager.newKeyguardLock(Context.KEYGUARD_SERVICE);
+ }
+ return lock;
+ }
+
+ public void updateState(Context context) {
+ getState(context);
+ if (lockScreen == null) {
+ currentIcon = R.drawable.stat_lock_screen_off;
+ currentState = PowerButton.STATE_INTERMEDIATE;
+ } else if (lockScreen) {
+ currentIcon = R.drawable.stat_lock_screen_on;
+ currentState = PowerButton.STATE_ENABLED;
+ } else {
+ currentIcon = R.drawable.stat_lock_screen_off;
+ currentState = PowerButton.STATE_DISABLED;
+ }
+ }
+
+ /**
+ * Toggles the state of GPS.
+ *
+ * @param context
+ */
+ public void toggleState(Context context) {
+ getState(context);
+ if(lockScreen == null) {
+ Toast msg = Toast.makeText(context, "Not yet initialized", Toast.LENGTH_LONG);
+ msg.setGravity(Gravity.CENTER, msg.getXOffset() / 2, msg.getYOffset() / 2);
+ msg.show();
+ } else {
+ getLock(context);
+ if (lockScreen && lock != null) {
+ lock.disableKeyguard();
+ lockScreen = false;
+ } else if (lock != null) {
+ lock.reenableKeyguard();
+ lockScreen = true;
+ }
+ }
+ }
+
+ /**
+ * Gets the state of GPS location.
+ *
+ * @param context
+ * @return true if enabled.
+ */
+ private static boolean getState(Context context) {
+ if (lockScreen == null) {
+ lockScreen = true;
+ }
+ return lockScreen;
+ }
+
+
+ public static LockScreenButton getInstance() {
+ if (ownButton==null) ownButton = new LockScreenButton();
+
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+}
+
diff --git a/services/java/com/android/server/status/widget/MobileDataButton.java b/services/java/com/android/server/status/widget/MobileDataButton.java
new file mode 100755
index 0000000..69aa304
--- /dev/null
+++ b/services/java/com/android/server/status/widget/MobileDataButton.java
@@ -0,0 +1,85 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.provider.Settings;
+
+public class MobileDataButton extends PowerButton {
+
+ public static final String MOBILE_DATA_CHANGED = "com.android.internal.telephony.MOBILE_DATA_CHANGED";
+
+ static MobileDataButton ownButton = null;
+
+ static boolean stateChangeRequest = false;
+
+ public static boolean getDataRomingEnabled(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.DATA_ROAMING,0) > 0;
+ }
+
+ /**
+ * Gets the state of data
+ *
+ * @return true if enabled.
+ */
+ private static boolean getDataState(Context context) {
+ ConnectivityManager cm = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ return cm.getMobileDataEnabled();
+ }
+
+ /**
+ * Toggles the state of data.
+ *
+ */
+ @Override
+ public void toggleState(Context context) {
+ boolean enabled = getDataState(context);
+
+ ConnectivityManager cm = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ if (enabled) {
+ cm.setMobileDataEnabled(false);
+ } else {
+ cm.setMobileDataEnabled(true);
+ }
+ }
+
+ @Override
+ public void updateState(Context context) {
+ if (stateChangeRequest) {
+ currentIcon = R.drawable.stat_data_on;
+ currentState = PowerButton.STATE_INTERMEDIATE;
+ } else if (getDataState(context)) {
+ currentIcon = R.drawable.stat_data_on;
+ currentState = PowerButton.STATE_ENABLED;
+ } else {
+ currentIcon = R.drawable.stat_data_off;
+ currentState = PowerButton.STATE_DISABLED;
+ }
+ }
+
+ public static MobileDataButton getInstance() {
+ if (ownButton == null) ownButton = new MobileDataButton();
+
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+
+ public void networkModeChanged(Context context, int networkMode) {
+ if (stateChangeRequest) {
+ ConnectivityManager cm = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ cm.setMobileDataEnabled(true);
+ stateChangeRequest=false;
+ }
+ }
+
+}
diff --git a/services/java/com/android/server/status/widget/NetworkModeButton.java b/services/java/com/android/server/status/widget/NetworkModeButton.java
new file mode 100755
index 0000000..b735448
--- /dev/null
+++ b/services/java/com/android/server/status/widget/NetworkModeButton.java
@@ -0,0 +1,195 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+
+import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings.SettingNotFoundException;
+import android.widget.Toast;
+import android.provider.Settings;
+
+import com.android.internal.telephony.Phone;
+
+public class NetworkModeButton extends PowerButton{
+
+ public static final String NETWORK_MODE_CHANGED = "com.android.internal.telephony.NETWORK_MODE_CHANGED";
+ public static final String REQUEST_NETWORK_MODE = "com.android.internal.telephony.REQUEST_NETWORK_MODE";
+ public static final String MODIFY_NETWORK_MODE = "com.android.internal.telephony.MODIFY_NETWORK_MODE";
+
+ public static final String NETWORK_MODE = "networkMode";
+
+ private static final int NO_NETWORK_MODE_YET = -99;
+ private static final int NETWORK_MODE_UNKNOWN = -100;
+
+ private static final int MODE_3G2G = 0;
+ private static final int MODE_3GONLY = 1;
+ private static final int MODE_BOTH = 2;
+
+ private static final int DEFAULT_SETTING = 0;
+
+ static NetworkModeButton ownButton = null;
+
+ private static int networkMode = NO_NETWORK_MODE_YET;
+ private static int intendedNetworkMode = NO_NETWORK_MODE_YET;
+ private static int currentInternalState = PowerButton.STATE_INTERMEDIATE;
+ private int currentMode;
+
+
+ private int networkModeToState(Context context) {
+ if (currentInternalState == PowerButton.STATE_TURNING_ON ||
+ currentInternalState == PowerButton.STATE_TURNING_OFF)
+ return PowerButton.STATE_INTERMEDIATE;
+
+ switch(networkMode) {
+ case Phone.NT_MODE_WCDMA_PREF:
+ case Phone.NT_MODE_WCDMA_ONLY:
+ return PowerButton.STATE_ENABLED;
+ case Phone.NT_MODE_GSM_ONLY:
+ return PowerButton.STATE_DISABLED;
+ }
+ return PowerButton.STATE_INTERMEDIATE;
+ }
+
+
+ /**
+ * Gets the state of 2G3g // NOT working
+ *
+ * @param context
+ * @return true if enabled.
+ */
+
+ private int get2G3G(Context context) {
+ int state = 99;
+ try {
+ state = android.provider.Settings.Secure.getInt(context
+ .getContentResolver(),
+ android.provider.Settings.Secure.PREFERRED_NETWORK_MODE);
+ } catch (SettingNotFoundException e) {
+ }
+ return state;
+ }
+
+
+ public static NetworkModeButton getInstance() {
+ if (ownButton == null) ownButton = new NetworkModeButton();
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+
+ @Override
+ public void toggleState(Context context) {
+ toggleState(context, false);
+ }
+
+ public void toggleState(Context context, int newState) {
+ if (currentState != PowerButton.STATE_INTERMEDIATE && currentState != newState) {
+ toggleState(context,true);
+ } else if (currentState == PowerButton.STATE_INTERMEDIATE){
+ Toast toast = Toast.makeText(context, "Network mode state unknown. Please change it manually!",Toast.LENGTH_SHORT);
+ toast.show();
+ }
+ }
+
+ public void toggleState(Context context, boolean switchModes) {
+ Intent intent = new Intent(MODIFY_NETWORK_MODE);
+ switch (networkMode ) {
+ case Phone.NT_MODE_WCDMA_PREF:
+ intent.putExtra(NETWORK_MODE, Phone.NT_MODE_GSM_ONLY);
+ currentInternalState = PowerButton.STATE_TURNING_OFF;
+ intendedNetworkMode=Phone.NT_MODE_GSM_ONLY;
+ break;
+ case Phone.NT_MODE_WCDMA_ONLY:
+ if (currentMode == MODE_3GONLY || switchModes) {
+ intent.putExtra(NETWORK_MODE, Phone.NT_MODE_GSM_ONLY);
+ currentInternalState = PowerButton.STATE_TURNING_OFF;
+ intendedNetworkMode=Phone.NT_MODE_GSM_ONLY;
+ } else {
+ intent.putExtra(NETWORK_MODE, Phone.NT_MODE_WCDMA_PREF);
+ currentInternalState = PowerButton.STATE_TURNING_ON;
+ intendedNetworkMode = Phone.NT_MODE_WCDMA_PREF;
+ }
+ break;
+ case Phone.NT_MODE_GSM_ONLY:
+ if (currentMode == MODE_3GONLY || currentMode == MODE_BOTH ) {
+ intent.putExtra(NETWORK_MODE, Phone.NT_MODE_WCDMA_ONLY);
+ currentInternalState = PowerButton.STATE_TURNING_ON;
+ intendedNetworkMode = Phone.NT_MODE_WCDMA_ONLY;
+ } else {
+ intent.putExtra(NETWORK_MODE, Phone.NT_MODE_WCDMA_PREF);
+ currentInternalState = PowerButton.STATE_TURNING_ON;
+ intendedNetworkMode = Phone.NT_MODE_WCDMA_PREF;
+ }
+ break;
+ }
+
+ networkMode = NETWORK_MODE_UNKNOWN;
+ context.sendBroadcast(intent);
+ }
+
+
+
+
+ @Override
+ public void updateState(Context context) {
+ currentMode = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.EXPANDED_NETWORK_MODE, DEFAULT_SETTING);
+ networkMode = get2G3G(context);
+ currentState = networkModeToState(context);
+
+ switch (currentState) {
+ case PowerButton.STATE_DISABLED:
+ currentIcon = R.drawable.stat_2g3g_off;
+ break;
+ case PowerButton.STATE_ENABLED:
+ if (networkMode == Phone.NT_MODE_WCDMA_ONLY) {
+ currentIcon = R.drawable.stat_3g_on;
+ } else {
+ currentIcon = R.drawable.stat_2g3g_on;
+ }
+ break;
+ case PowerButton.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 (currentInternalState == PowerButton.STATE_TURNING_ON) {
+ if (intendedNetworkMode == Phone.NT_MODE_WCDMA_ONLY) {
+ currentIcon = R.drawable.stat_3g_on;
+ } else {
+ currentIcon = R.drawable.stat_2g3g_on;
+ }
+ } else {
+ currentIcon = R.drawable.stat_2g3g_off;
+ }
+ break;
+ }
+ }
+
+
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getExtras() != null) {
+ networkMode = intent.getExtras().getInt(NETWORK_MODE);
+ //Update to actual state
+ intendedNetworkMode=networkMode;
+ }
+
+ //need to clear intermediate states
+ currentInternalState=PowerButton.STATE_ENABLED;
+
+ int widgetState = networkModeToState(context);
+ currentInternalState = widgetState;
+ if (widgetState == PowerButton.STATE_ENABLED) {
+ MobileDataButton.getInstance().networkModeChanged(context, networkMode);
+ }
+ }
+
+ public boolean isDisabled(Context context) {
+ return networkModeToState(context)==PowerButton.STATE_DISABLED;
+ }
+
+}
diff --git a/services/java/com/android/server/status/widget/PowerButton.java b/services/java/com/android/server/status/widget/PowerButton.java
new file mode 100644
index 0000000..0e61bda
--- /dev/null
+++ b/services/java/com/android/server/status/widget/PowerButton.java
@@ -0,0 +1,135 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.graphics.PorterDuff.Mode;
+import android.widget.ImageView;
+import android.widget.RemoteViews;
+import android.widget.LinearLayout;
+import android.util.Log;
+import android.provider.Settings;
+import android.view.View;
+
+import com.android.server.status.ExpandedView;
+
+public abstract class PowerButton {
+ public static final String TOGGLE_WIFI = "toggleWifi";
+ public static final String TOGGLE_GPS = "toggleGPS";
+ public static final String TOGGLE_BLUETOOTH = "toggleBluetooth";
+ public static final String TOGGLE_BRIGHTNESS = "toggleBrightness";
+ public static final String TOGGLE_SOUND = "toggleSound";
+ public static final String TOGGLE_SYNC = "toggleSync";
+ public static final String TOGGLE_WIFIAP = "toggleWifiAp";
+ public static final String TOGGLE_SCREENTIMEOUT = "toggleScreenTimeout";
+ public static final String TOGGLE_MOBILEDATA = "toggleMobileData";
+ public static final String TOGGLE_LOCKSCREEN = "toggleLockScreen";
+ public static final String TOGGLE_NETWORKMODE = "toggleNetworkMode";
+ public static final String TOGGLE_AUTOROTATE = "toggleAutoRotate";
+ public static final String TOGGLE_FLASHLIGHT = "toggleFlashlight";
+ public static final String TOGGLE_AIRPLANE = "toggleAirplane";
+
+ private Mode expPDMode = Mode.SCREEN;
+ public static final int STATE_ENABLED = 1;
+ public static final int STATE_DISABLED = 2;
+ public static final int STATE_TURNING_ON = 3;
+ public static final int STATE_TURNING_OFF = 4;
+ public static final int STATE_INTERMEDIATE = 5;
+ public static final int STATE_UNKNOWN = 6;
+
+ public int currentIcon;
+ public int currentState;
+ public int currentPosition;
+
+ abstract void initButton(int position);
+ abstract public void toggleState(Context context);
+ public abstract void updateState(Context context);
+
+ public void setupButton(int position) {
+ currentPosition = position;
+ }
+
+ public void updateView(Context context, ExpandedView views) {
+ if(currentPosition > 0) {
+ Resources res = context.getResources();
+ int buttonLayer = getLayoutID(currentPosition);
+ int buttonIcon = getImageID(currentPosition);
+ int buttonState = getStatusInd(currentPosition);
+
+ views.findViewById(buttonLayer).setVisibility(View.VISIBLE);
+
+ updateImageView(views, buttonIcon, currentIcon);
+
+ /* Button State */
+ int sColorMaskBase = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.EXPANDED_VIEW_WIDGET_COLOR, 0xFF00EFFF);
+ int sColorMaskOn = (sColorMaskBase & 0x00FFFFFF) | 0xA0000000;
+ int sColorMaskOff = (sColorMaskBase & 0x00FFFFFF) | 0x33000000;
+ int sColorMaskInter = (sColorMaskBase & 0x00FFFFFF) | 0x60000000;
+
+ switch(currentState) {
+ case STATE_ENABLED:
+ updateImageView(views, buttonState,
+ res.getDrawable(com.android.internal.R.drawable.stat_bgon_custom, sColorMaskOn, expPDMode));
+ break;
+ case STATE_DISABLED:
+ updateImageView(views, buttonState,
+ res.getDrawable(com.android.internal.R.drawable.stat_bgon_custom, sColorMaskOff, expPDMode));
+ break;
+ default:
+ updateImageView(views, buttonState,
+ res.getDrawable(com.android.internal.R.drawable.stat_bgon_custom, sColorMaskInter, expPDMode));
+ break;
+ }
+ }
+ }
+
+ private void updateImageView(ExpandedView view, int id, int resId) {
+ ImageView imageIcon = (ImageView)view.findViewById(id);
+ imageIcon.setImageResource(resId);
+ }
+ private void updateImageView(ExpandedView view, int id, Drawable resDraw) {
+ ImageView statusInd = (ImageView)view.findViewById(id);
+ statusInd.setImageResource(com.android.internal.R.drawable.stat_bgon_custom);
+ statusInd.setImageDrawable(resDraw);
+ }
+
+ public static int getLayoutID(int posi) {
+ switch(posi) {
+ case 1: return R.id.exp_power_stat_1;
+ case 2: return R.id.exp_power_stat_2;
+ case 3: return R.id.exp_power_stat_3;
+ case 4: return R.id.exp_power_stat_4;
+ case 5: return R.id.exp_power_stat_5;
+ case 6: return R.id.exp_power_stat_6;
+ }
+ return 0;
+ }
+
+ private int getImageID(int posi) {
+ switch(posi) {
+ case 1: return R.id.exp_power_image_1;
+ case 2: return R.id.exp_power_image_2;
+ case 3: return R.id.exp_power_image_3;
+ case 4: return R.id.exp_power_image_4;
+ case 5: return R.id.exp_power_image_5;
+ case 6: return R.id.exp_power_image_6;
+ }
+ return 0;
+ }
+
+ private int getStatusInd(int posi) {
+ switch(posi) {
+ case 1: return R.id.exp_power_indic_1;
+ case 2: return R.id.exp_power_indic_2;
+ case 3: return R.id.exp_power_indic_3;
+ case 4: return R.id.exp_power_indic_4;
+ case 5: return R.id.exp_power_indic_5;
+ case 6: return R.id.exp_power_indic_6;
+ }
+ return 0;
+ }
+}
diff --git a/services/java/com/android/server/status/widget/ScreenTimeoutButton.java b/services/java/com/android/server/status/widget/ScreenTimeoutButton.java
new file mode 100755
index 0000000..c64e4fb
--- /dev/null
+++ b/services/java/com/android/server/status/widget/ScreenTimeoutButton.java
@@ -0,0 +1,104 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+import com.android.server.status.widget.StateTracker;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.provider.Settings;
+
+public class ScreenTimeoutButton extends PowerButton {
+
+ public static final int SCREEN_MINIMUM_TIMEOUT = 15000;
+ public static final int SCREEN_LOW_TIMEOUT = 30000;
+ public static final int SCREEN_NORMAL_TIMEOUT = 60000;
+ public static final int SCREEN_HI_TIMEOUT = 120000;
+ public static final int SCREEN_MAX_TIMEOUT = 300000;
+
+
+ private static final int MODE_15_60_300 = 0;
+ private static final int MODE_30_120_300 = 1;
+
+ private static final int DEFAULT_SETTING = 0;
+
+ static ScreenTimeoutButton ownButton = null;
+
+ private int currentMode;
+
+ public static int getScreenTtimeout(Context context) {
+ return Settings.System.getInt(
+ context.getContentResolver(),
+ Settings.System.SCREEN_OFF_TIMEOUT, 0);
+ }
+
+
+ public void toggleState(Context context) {
+ int screentimeout = getScreenTtimeout(context);
+ if (screentimeout < SCREEN_MINIMUM_TIMEOUT) {
+ if (currentMode == MODE_15_60_300) {
+ screentimeout = SCREEN_MINIMUM_TIMEOUT;
+ } else {
+ screentimeout = SCREEN_LOW_TIMEOUT;
+ }
+ } else if (screentimeout < SCREEN_LOW_TIMEOUT) {
+ if (currentMode == MODE_15_60_300) {
+ screentimeout = SCREEN_NORMAL_TIMEOUT;
+ } else {
+ screentimeout = SCREEN_LOW_TIMEOUT;
+ }
+ } else if (screentimeout < SCREEN_NORMAL_TIMEOUT) {
+ if (currentMode == MODE_15_60_300) {
+ screentimeout = SCREEN_NORMAL_TIMEOUT;
+ } else {
+ screentimeout = SCREEN_HI_TIMEOUT;
+ }
+ } else if (screentimeout < SCREEN_HI_TIMEOUT) {
+ if (currentMode == MODE_15_60_300) {
+ screentimeout = SCREEN_MAX_TIMEOUT;
+ } else {
+ screentimeout=SCREEN_HI_TIMEOUT;
+ }
+ } else if (screentimeout < SCREEN_MAX_TIMEOUT) {
+ screentimeout = SCREEN_MAX_TIMEOUT;
+ } else if (currentMode == MODE_30_120_300) {
+ screentimeout = SCREEN_LOW_TIMEOUT;
+ } else {
+ screentimeout = SCREEN_MINIMUM_TIMEOUT;
+ }
+ Settings.System.putInt(
+ context.getContentResolver(),
+ Settings.System.SCREEN_OFF_TIMEOUT, screentimeout);
+ }
+
+ public static ScreenTimeoutButton getInstance() {
+ if (ownButton == null) ownButton = new ScreenTimeoutButton();
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+
+ @Override
+ public void updateState(Context context) {
+
+ currentMode = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.EXPANDED_SCREENTIMEOUT_MODE, DEFAULT_SETTING);
+
+ int timeout=getScreenTtimeout(context);
+ //TODO: ADD support for the possible values
+ if (timeout <= SCREEN_LOW_TIMEOUT) {
+ currentIcon = R.drawable.stat_screen_timeout_off;
+ currentState = PowerButton.STATE_DISABLED;
+ } else if (timeout <= SCREEN_HI_TIMEOUT) {
+ currentIcon = R.drawable.stat_screen_timeout_off;
+ currentState = PowerButton.STATE_INTERMEDIATE;
+ } else {
+ currentIcon = R.drawable.stat_screen_timeout_on;
+ currentState = PowerButton.STATE_ENABLED;
+ }
+ }
+}
+
+
diff --git a/services/java/com/android/server/status/widget/SoundButton.java b/services/java/com/android/server/status/widget/SoundButton.java
new file mode 100755
index 0000000..bd96bd7
--- /dev/null
+++ b/services/java/com/android/server/status/widget/SoundButton.java
@@ -0,0 +1,220 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.media.AudioManager;
+import android.provider.Settings;
+
+public class SoundButton extends PowerButton {
+
+ static SoundButton ownButton = null;
+
+ public static final int RINGER_MODE_UNKNOWN = 0;
+ public static final int RINGER_MODE_SILENT = 1;
+ public static final int RINGER_MODE_VIBRATE_ONLY = 2;
+ public static final int RINGER_MODE_SOUND_ONLY = 3;
+ public static final int RINGER_MODE_SOUND_AND_VIBRATE = 4;
+
+ public static final int MODE_SOUNDVIB_VIB = 0;
+ public static final int MODE_SOUND_VIB = 1;
+ public static final int MODE_SOUND_SILENT = 2;
+ public static final int MODE_SOUNDVIB_VIB_SILENT = 3;
+ public static final int MODE_SOUND_VIB_SILENT = 4;
+
+ private static final int DEFAULT_SETTING = 0;
+ private static int currentMode;
+
+ private static int getSoundState(Context context) {
+ AudioManager mAudioManager = (AudioManager) context
+ .getSystemService(Context.AUDIO_SERVICE);
+
+ int ringMode = mAudioManager.getRingerMode();
+ int vibrateMode = mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
+
+ if (ringMode == AudioManager.RINGER_MODE_NORMAL && vibrateMode == AudioManager.VIBRATE_SETTING_ON) {
+ return RINGER_MODE_SOUND_AND_VIBRATE;
+ } else if (ringMode == AudioManager.RINGER_MODE_NORMAL) {
+ return RINGER_MODE_SOUND_ONLY;
+ } else if (ringMode == AudioManager.RINGER_MODE_VIBRATE) {
+ return RINGER_MODE_VIBRATE_ONLY;
+ } else if (ringMode == AudioManager.RINGER_MODE_SILENT) {
+ return RINGER_MODE_SILENT;
+ }
+ return RINGER_MODE_UNKNOWN;
+ }
+
+ /**
+ * Toggles the state of 2G3G.
+ *
+ * @param context
+ */
+ public void toggleState(Context context) {
+ int currentMode = getSoundState(context);
+ AudioManager mAudioManager = (AudioManager) context
+ .getSystemService(Context.AUDIO_SERVICE);
+
+ switch (currentMode) {
+ case RINGER_MODE_SOUND_AND_VIBRATE:
+ if(supports(RINGER_MODE_SOUND_ONLY)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.
+ setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ } else if(supports(RINGER_MODE_VIBRATE_ONLY)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.
+ setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
+ } else if(supports(RINGER_MODE_SILENT)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,0);
+ mAudioManager.
+ setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
+ } else { //Fall Back
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.
+ setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
+ }
+ break;
+ case RINGER_MODE_SOUND_ONLY:
+ if(supports(RINGER_MODE_VIBRATE_ONLY)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.
+ setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
+ } else if(supports(RINGER_MODE_SILENT)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,0);
+ mAudioManager.
+ setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
+ } else if(supports(RINGER_MODE_SOUND_AND_VIBRATE)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.
+ setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ } else { //Fall back
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.
+ setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON);
+ }
+ break;
+
+ case RINGER_MODE_VIBRATE_ONLY:
+ if(supports(RINGER_MODE_SILENT)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,0);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF);
+ } else if(supports(RINGER_MODE_SOUND_AND_VIBRATE)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON);
+ } else if(supports(RINGER_MODE_SOUND_ONLY)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT);
+ } else { //Fall Back
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON);
+ }
+ break;
+ case RINGER_MODE_SILENT:
+ if(supports(RINGER_MODE_SOUND_AND_VIBRATE)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON);
+ } else if(supports(RINGER_MODE_SOUND_ONLY)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT);
+ } else if(supports(RINGER_MODE_VIBRATE_ONLY)) {
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ONLY_SILENT);
+ } else { //Fall Back
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON);
+ }
+ break;
+ default:
+ Settings.System.putInt(context.getContentResolver(),Settings.System.VIBRATE_IN_SILENT,1);
+ mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
+ mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON);
+
+ }
+ }
+
+ private boolean supports(int ringerMode) {
+ switch (ringerMode) {
+ case RINGER_MODE_SILENT:
+ if (currentMode == MODE_SOUND_SILENT ||
+ currentMode == MODE_SOUNDVIB_VIB_SILENT ||
+ currentMode == MODE_SOUND_VIB_SILENT)
+ return true;
+ break;
+ case RINGER_MODE_VIBRATE_ONLY:
+ if (currentMode == MODE_SOUND_VIB ||
+ currentMode == MODE_SOUNDVIB_VIB ||
+ currentMode == MODE_SOUNDVIB_VIB_SILENT ||
+ currentMode == MODE_SOUND_VIB_SILENT)
+ return true;
+ break;
+ case RINGER_MODE_SOUND_ONLY:
+ if (currentMode == MODE_SOUND_VIB ||
+ currentMode == MODE_SOUND_SILENT ||
+ currentMode == MODE_SOUND_VIB_SILENT)
+ return true;
+ break;
+ case RINGER_MODE_SOUND_AND_VIBRATE:
+ if (currentMode == MODE_SOUNDVIB_VIB ||
+ currentMode == MODE_SOUNDVIB_VIB_SILENT)
+ return true;
+ }
+
+ return false;
+ }
+
+ public static SoundButton getInstance() {
+ if (ownButton == null)
+ ownButton = new SoundButton();
+
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+
+ @Override
+ public void updateState(Context context) {
+ int soundState = getSoundState(context);
+ currentMode = Settings.System.getInt(context.getContentResolver(),
+ Settings.System.EXPANDED_RING_MODE, DEFAULT_SETTING);
+
+ switch (soundState) {
+ case RINGER_MODE_SOUND_AND_VIBRATE:
+ currentIcon = R.drawable.stat_ring_on;
+ currentState = PowerButton.STATE_ENABLED;
+ break;
+ case RINGER_MODE_SOUND_ONLY:
+ currentIcon = R.drawable.stat_ring_on;
+ currentState = PowerButton.STATE_INTERMEDIATE;
+ break;
+ case RINGER_MODE_VIBRATE_ONLY:
+ currentIcon = R.drawable.stat_vibrate_off;
+ currentState = PowerButton.STATE_DISABLED;
+ break;
+ case RINGER_MODE_SILENT:
+ currentIcon = R.drawable.stat_silent;
+ currentState = PowerButton.STATE_DISABLED;
+ break;
+
+ }
+ }
+}
diff --git a/services/java/com/android/server/status/widget/StateTracker.java b/services/java/com/android/server/status/widget/StateTracker.java
new file mode 100644
index 0000000..fd476b6
--- /dev/null
+++ b/services/java/com/android/server/status/widget/StateTracker.java
@@ -0,0 +1,160 @@
+package com.android.server.status.widget;
+
+import com.android.server.status.widget.PowerButton;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+
+/**
+ * The state machine for Wifi and Bluetooth toggling, tracking reality
+ * versus the user's intent.
+ *
+ * This is necessary because reality moves relatively slowly (turning on
+ * &amp; off radio drivers), compared to user's expectations.
+ */
+public abstract class StateTracker {
+ // Is the state in the process of changing?
+ private boolean mInTransition = false;
+ private Boolean mActualState = null; // initially not set
+ private Boolean mIntendedState = null; // initially not set
+
+ // Did a toggle request arrive while a state update was
+ // already in-flight? If so, the mIntendedState needs to be
+ // requested when the other one is done, unless we happened to
+ // arrive at that state already.
+ private boolean mDeferredStateChangeRequestNeeded = false;
+
+ /**
+ * User pressed a button to change the state. Something should
+ * immediately appear to the user afterwards, even if we effectively do
+ * nothing. Their press must be heard.
+ */
+ public final void toggleState(Context context) {
+ int currentState = getTriState(context);
+ boolean newState = false;
+ switch (currentState) {
+ case PowerButton.STATE_ENABLED:
+ newState = false;
+ break;
+ case PowerButton.STATE_DISABLED:
+ newState = true;
+ break;
+ case PowerButton.STATE_INTERMEDIATE:
+ if (mIntendedState != null) {
+ newState = !mIntendedState;
+ }
+ break;
+ }
+ mIntendedState = newState;
+ if (mInTransition) {
+ // We don't send off a transition request if we're
+ // already transitioning. Makes our state tracking
+ // easier, and is probably nicer on lower levels.
+ // (even though they should be able to take it...)
+ mDeferredStateChangeRequestNeeded = true;
+ } else {
+ mInTransition = true;
+ requestStateChange(context, newState);
+ }
+ }
+
+ /**
+ * Update internal state from a broadcast state change.
+ */
+ public abstract void onActualStateChange(Context context, Intent intent);
+
+ /**
+ * Sets the value that we're now in. To be called from
+ * onActualStateChange.
+ *
+ * @param newState
+ * one of STATE_DISABLED, STATE_ENABLED, STATE_TURNING_ON,
+ * STATE_TURNING_OFF, STATE_UNKNOWN
+ */
+ protected final void setCurrentState(Context context, int newState) {
+ final boolean wasInTransition = mInTransition;
+ switch (newState) {
+ case PowerButton.STATE_DISABLED:
+ mInTransition = false;
+ mActualState = false;
+ break;
+ case PowerButton.STATE_ENABLED:
+ mInTransition = false;
+ mActualState = true;
+ break;
+ case PowerButton.STATE_TURNING_ON:
+ mInTransition = true;
+ mActualState = false;
+ break;
+ case PowerButton.STATE_TURNING_OFF:
+ mInTransition = true;
+ mActualState = true;
+ break;
+ }
+
+ if (wasInTransition && !mInTransition) {
+ if (mDeferredStateChangeRequestNeeded) {
+ Log.v("StateTracker", "processing deferred state change");
+ if (mActualState != null && mIntendedState != null
+ && mIntendedState.equals(mActualState)) {
+ Log.v("StateTracker", "... but intended state matches, so no changes.");
+ } else if (mIntendedState != null) {
+ mInTransition = true;
+ requestStateChange(context, mIntendedState);
+ }
+ mDeferredStateChangeRequestNeeded = false;
+ }
+ }
+ }
+
+ /**
+ * If we're in a transition mode, this returns true if we're
+ * transitioning towards being enabled.
+ */
+ public final boolean isTurningOn() {
+ return mIntendedState != null && mIntendedState;
+ }
+
+ /**
+ * Returns simplified 3-state value from underlying 5-state.
+ *
+ * @param context
+ * @return STATE_ENABLED, STATE_DISABLED, or STATE_INTERMEDIATE
+ */
+ public final int getTriState(Context context) {
+ /*if (mInTransition) {
+ // If we know we just got a toggle request recently
+ // (which set mInTransition), don't even ask the
+ // underlying interface for its state. We know we're
+ // changing. This avoids blocking the UI thread
+ // during UI refresh post-toggle if the underlying
+ // service state accessor has coarse locking on its
+ // state (to be fixed separately).
+ return PowerButton.STATE_INTERMEDIATE;
+ }*/
+ switch (getActualState(context)) {
+ case PowerButton.STATE_DISABLED:
+ return PowerButton.STATE_DISABLED;
+ case PowerButton.STATE_ENABLED:
+ return PowerButton.STATE_ENABLED;
+ default:
+ return PowerButton.STATE_INTERMEDIATE;
+ }
+ }
+
+ /**
+ * Gets underlying actual state.
+ *
+ * @param context
+ * @return STATE_ENABLED, STATE_DISABLED, STATE_ENABLING,
+ * STATE_DISABLING, or or STATE_UNKNOWN.
+ */
+ public abstract int getActualState(Context context);
+
+ /**
+ * Actually make the desired change to the underlying radio API.
+ */
+ protected abstract void requestStateChange(Context context,
+ boolean desiredState);
+}
diff --git a/services/java/com/android/server/status/widget/SyncButton.java b/services/java/com/android/server/status/widget/SyncButton.java
new file mode 100755
index 0000000..f7de226
--- /dev/null
+++ b/services/java/com/android/server/status/widget/SyncButton.java
@@ -0,0 +1,104 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+
+public class SyncButton extends PowerButton {
+
+ static SyncButton ownButton=null;
+
+ /**
+ * Toggle auto-sync
+ *
+ * @param context
+ */
+ public void toggleState(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);
+ }
+ }
+
+ public void toggleState(Context context, int newState) {
+ if(getSync(context) && newState==PowerButton.STATE_DISABLED) {
+ toggleState(context);
+ } else if(!getSync(context) && newState==PowerButton.STATE_ENABLED) {
+ toggleState(context);
+ }
+ }
+
+ /**
+ * 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();
+ }
+
+ /**
+ * 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;
+ }
+
+
+
+ public void updateState(Context context) {
+ if (getSync(context)) {
+ currentIcon = R.drawable.stat_sync_on;
+ currentState = PowerButton.STATE_ENABLED;
+ } else {
+ currentIcon = R.drawable.stat_sync_off;
+ currentState = PowerButton.STATE_DISABLED;
+ }
+ }
+
+ public static SyncButton getInstance() {
+ if (ownButton == null) ownButton = new SyncButton();
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int poisition) {
+ }
+
+}
diff --git a/services/java/com/android/server/status/widget/WifiApButton.java b/services/java/com/android/server/status/widget/WifiApButton.java
new file mode 100755
index 0000000..d0b7394
--- /dev/null
+++ b/services/java/com/android/server/status/widget/WifiApButton.java
@@ -0,0 +1,152 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+import com.android.server.status.widget.StateTracker;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class WifiApButton extends PowerButton {
+
+ static WifiApButton ownButton = null;
+
+
+ private static final StateTracker sWifiApState = new WifiApStateTracker();
+
+ /**
+ * Subclass of StateTracker to get/set Wifi AP state.
+ */
+ private static final class WifiApStateTracker extends StateTracker {
+ @Override
+ public int getActualState(Context context) {
+ WifiManager wifiManager = (WifiManager) context
+ .getSystemService(Context.WIFI_SERVICE);
+ if (wifiManager != null) {
+ return wifiApStateToFiveState(wifiManager.getWifiApState());
+ }
+ return PowerButton.STATE_UNKNOWN;
+ }
+
+ @Override
+ protected void requestStateChange(Context context,
+ final boolean desiredState) {
+
+ final WifiManager wifiManager = (WifiManager) context
+ .getSystemService(Context.WIFI_SERVICE);
+ if (wifiManager == null) {
+ Log.d("WifiAPManager", "No wifiManager.");
+ return;
+ }
+ Log.i("WifiAp", "Setting: " + desiredState);
+
+ // Actually request the Wi-Fi AP change and persistent
+ // settings write off the UI thread, as it can take a
+ // user-noticeable amount of time, especially if there's
+ // disk contention.
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... args) {
+ /**
+ * Disable Wif if enabling tethering
+ */
+ int wifiState = wifiManager.getWifiState();
+ if (desiredState
+ && ((wifiState == WifiManager.WIFI_STATE_ENABLING) || (wifiState == WifiManager.WIFI_STATE_ENABLED))) {
+ wifiManager.setWifiEnabled(false);
+ }
+
+ wifiManager.setWifiApEnabled(null, desiredState);
+ Log.i("WifiAp", "Async Setting: " + desiredState);
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onActualStateChange(Context context, Intent intent) {
+
+ if (!WifiManager.WIFI_AP_STATE_CHANGED_ACTION.equals(intent
+ .getAction())) {
+ return;
+ }
+ int wifiState = intent
+ .getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, -1);
+ int widgetState=wifiApStateToFiveState(wifiState);
+ setCurrentState(context, widgetState);
+ }
+
+ /**
+ * Converts WifiManager's state values into our Wifi/WifiAP/Bluetooth-common
+ * state values.
+ */
+ private static int wifiApStateToFiveState(int wifiState) {
+ switch (wifiState) {
+ case WifiManager.WIFI_AP_STATE_DISABLED:
+ return PowerButton.STATE_DISABLED;
+ case WifiManager.WIFI_AP_STATE_ENABLED:
+ return PowerButton.STATE_ENABLED;
+ case WifiManager.WIFI_AP_STATE_DISABLING:
+ return PowerButton.STATE_TURNING_OFF;
+ case WifiManager.WIFI_AP_STATE_ENABLING:
+ return PowerButton.STATE_TURNING_ON;
+ default:
+ return PowerButton.STATE_UNKNOWN;
+ }
+ }
+ }
+
+
+
+ public void updateState(Context context) {
+
+ currentState = sWifiApState.getTriState(context);
+ switch (currentState) {
+ case PowerButton.STATE_DISABLED:
+ currentIcon = R.drawable.stat_wifi_ap_off;
+ break;
+ case PowerButton.STATE_ENABLED:
+ currentIcon = R.drawable.stat_wifi_ap_on;
+ break;
+ case PowerButton.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 (sWifiApState.isTurningOn()) {
+ currentIcon = R.drawable.stat_wifi_ap_on;
+ } else {
+ currentIcon = R.drawable.stat_wifi_ap_off;
+ }
+ break;
+ }
+ }
+
+
+ public void onReceive(Context context, Intent intent) {
+ sWifiApState.onActualStateChange(context, intent);
+ }
+
+
+ public void toggleState(Context context) {
+ sWifiApState.toggleState(context);
+ }
+
+
+ public static WifiApButton getInstance() {
+ if (ownButton == null) {
+ ownButton = new WifiApButton();
+ }
+
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+}
diff --git a/services/java/com/android/server/status/widget/WifiButton.java b/services/java/com/android/server/status/widget/WifiButton.java
new file mode 100644
index 0000000..bb89b6a
--- /dev/null
+++ b/services/java/com/android/server/status/widget/WifiButton.java
@@ -0,0 +1,159 @@
+package com.android.server.status.widget;
+
+import com.android.internal.R;
+import com.android.server.status.widget.PowerButton;
+import com.android.server.status.widget.StateTracker;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.WifiManager;
+import android.os.AsyncTask;
+import android.util.Log;
+
+public class WifiButton extends PowerButton{
+
+ static WifiButton ownButton = null;
+
+ private static final StateTracker sWifiState = new WifiStateTracker();
+
+ public void setupButton(Context context, int position) {
+ currentPosition = position;
+ }
+
+ /**
+ * Subclass of StateTracker to get/set Wifi state.
+ */
+ private static final class WifiStateTracker extends StateTracker {
+ @Override
+ public int getActualState(Context context) {
+ WifiManager wifiManager = (WifiManager) context
+ .getSystemService(Context.WIFI_SERVICE);
+ if (wifiManager != null) {
+ return wifiStateToFiveState(wifiManager.getWifiState());
+ }
+ return STATE_UNKNOWN;
+ }
+
+ @Override
+ protected void requestStateChange(Context context,
+ final boolean desiredState) {
+ final WifiManager wifiManager = (WifiManager) context
+ .getSystemService(Context.WIFI_SERVICE);
+ if (wifiManager == null) {
+ Log.d("WifiButton", "No wifiManager.");
+ return;
+ }
+
+ // Actually request the wifi change and persistent
+ // settings write off the UI thread, as it can take a
+ // user-noticeable amount of time, especially if there's
+ // disk contention.
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... args) {
+ /**
+ * Disable tethering if enabling Wifi
+ */
+ int wifiApState = wifiManager.getWifiApState();
+ if (desiredState
+ && ((wifiApState == WifiManager.WIFI_AP_STATE_ENABLING) || (wifiApState == WifiManager.WIFI_AP_STATE_ENABLED))) {
+ wifiManager.setWifiApEnabled(null, false);
+ }
+
+ wifiManager.setWifiEnabled(desiredState);
+ return null;
+ }
+ }.execute();
+ }
+
+ @Override
+ public void onActualStateChange(Context context, Intent intent) {
+ if (!WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent
+ .getAction())) {
+ return;
+ }
+ int wifiState = intent
+ .getIntExtra(WifiManager.EXTRA_WIFI_STATE, -1);
+ int widgetState=wifiStateToFiveState(wifiState);
+ setCurrentState(context, widgetState);
+ }
+
+ /**
+ * Converts WifiManager's state values into our Wifi/Bluetooth-common
+ * state values.
+ */
+ private static int wifiStateToFiveState(int wifiState) {
+ switch (wifiState) {
+ case WifiManager.WIFI_STATE_DISABLED:
+ return STATE_DISABLED;
+ case WifiManager.WIFI_STATE_ENABLED:
+ return STATE_ENABLED;
+ case WifiManager.WIFI_STATE_DISABLING:
+ return STATE_TURNING_OFF;
+ case WifiManager.WIFI_STATE_ENABLING:
+ return STATE_TURNING_ON;
+ default:
+ return STATE_UNKNOWN;
+ }
+ }
+ }
+
+
+
+ public void updateState(Context context) {
+ currentState = sWifiState.getTriState(context);
+ switch (currentState) {
+ case STATE_DISABLED:
+ currentIcon = com.android.internal.R.drawable.stat_wifi_off;
+ break;
+ case STATE_ENABLED:
+ currentIcon = com.android.internal.R.drawable.stat_wifi_on;
+ 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()) {
+ currentIcon = com.android.internal.R.drawable.stat_wifi_on;
+ } else {
+ currentIcon = com.android.internal.R.drawable.stat_wifi_off;
+ }
+ break;
+ }
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ sWifiState.onActualStateChange(context, intent);
+ }
+
+ public void toggleState(Context context) {
+ int realstate = sWifiState.getActualState(context);
+ sWifiState.toggleState(context);
+ }
+
+
+ public static WifiButton getInstance() {
+ if (ownButton == null) {
+ ownButton = new WifiButton();
+ }
+
+ return ownButton;
+ }
+
+ @Override
+ void initButton(int position) {
+ }
+
+ public void toggleState(Context context, int newState) {
+ int curState = sWifiState.getTriState(context);
+ if (curState != STATE_INTERMEDIATE &&
+ curState != newState) {
+ toggleState(context);
+ }
+ }
+}