summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml11
-rw-r--r--core/java/android/content/Intent.java7
-rw-r--r--core/res/res/values/strings.xml5
-rw-r--r--services/java/com/android/server/NotificationManagerService.java98
-rw-r--r--services/java/com/android/server/status/StatusBarPolicy.java20
5 files changed, 134 insertions, 7 deletions
diff --git a/api/current.xml b/api/current.xml
index 787fcb4..1287f59 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -31346,6 +31346,17 @@
visibility="public"
>
</field>
+<field name="ACTION_BATTERY_OKAY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.action.BATTERY_OKAY&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ACTION_BOOT_COMPLETED"
type="java.lang.String"
transient="false"
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 6fe5506..6b723bc 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1290,6 +1290,13 @@ public class Intent implements Parcelable {
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
/**
+ * Broadcast Action: Indicates the battery is now okay after being low.
+ * This will be sent after {@link #ACTION_BATTERY_LOW} once the battery has
+ * gone back up to an okay state.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
+ /**
* Broadcast Action: External power has been connected to the device.
* This is intended for applications that wish to register specifically to this notification.
* Unlike ACTION_BATTERY_CHANGED, applications will be woken for this and so do not have to
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9f1ed40..1ce9c76 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1786,6 +1786,11 @@
<!-- See EXTMEDIA_FORMAT. This is the button text to format the sd card. -->
<string name="extmedia_format_button_format">Format</string>
+ <!-- Title of notification shown when ADB is actively connected to the phone. -->
+ <string name="adb_active_notification_title">USB debugging connected</string>
+ <!-- Message of notification shown when ADB is actively connected to the phone. -->
+ <string name="adb_active_notification_message">A computer is connected to your phone.</string>
+
<!-- Used to replace %s in urls retreived from the signin server with locales. For Some -->
<!-- devices we don't support all the locales we ship to and need to replace the '%s' with a -->
<!-- locale string based on mcc values. By default (0-length string) we don't replace the %s -->
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 4a2808b..854138c 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -25,15 +25,20 @@ import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.ITransientNotification;
import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentQueryMap;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.media.AsyncPlayer;
import android.media.AudioManager;
import android.net.Uri;
@@ -88,6 +93,12 @@ class NotificationManagerService extends INotificationManager.Stub
private NotificationRecord mVibrateNotification;
private Vibrator mVibrator = new Vibrator();
+ // adb
+ private int mBatteryPlugged;
+ private boolean mAdbEnabled = false;
+ private boolean mAdbNotificationShown = false;
+ private Notification mAdbNotification;
+
private ArrayList<NotificationRecord> mNotificationList;
private ArrayList<ToastRecord> mToastQueue;
@@ -297,6 +308,9 @@ class NotificationManagerService extends INotificationManager.Stub
mBatteryFull = batteryFull;
updateLights();
}
+
+ mBatteryPlugged = intent.getIntExtra("plugged", 0);
+ updateAdbNotification();
} else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
|| action.equals(Intent.ACTION_PACKAGE_RESTARTED)) {
Uri uri = intent.getData();
@@ -312,6 +326,31 @@ class NotificationManagerService extends INotificationManager.Stub
}
};
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.ADB_ENABLED), false, this);
+ update();
+ }
+
+ @Override public void onChange(boolean selfChange) {
+ update();
+ }
+
+ public void update() {
+ ContentResolver resolver = mContext.getContentResolver();
+ mAdbEnabled = Settings.Secure.getInt(resolver,
+ Settings.Secure.ADB_ENABLED, 0) != 0;
+ updateAdbNotification();
+ }
+ }
+ private final SettingsObserver mSettingsObserver;
+
NotificationManagerService(Context context, StatusBarService statusBar,
HardwareService hardware)
{
@@ -333,6 +372,9 @@ class NotificationManagerService extends INotificationManager.Stub
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
mContext.registerReceiver(mIntentReceiver, filter);
+
+ mSettingsObserver = new SettingsObserver(mHandler);
+ mSettingsObserver.observe();
}
// Toasts
@@ -892,6 +934,62 @@ class NotificationManagerService extends INotificationManager.Stub
return -1;
}
+ // This is here instead of StatusBarPolicy because it is an important
+ // security feature that we don't want people customizing the platform
+ // to accidentally lose.
+ private void updateAdbNotification() {
+ if (mAdbEnabled && mBatteryPlugged == BatteryManager.BATTERY_PLUGGED_USB) {
+ if (!mAdbNotificationShown) {
+ NotificationManager notificationManager = (NotificationManager) mContext
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ if (notificationManager != null) {
+ Resources r = mContext.getResources();
+ CharSequence title = r.getText(
+ com.android.internal.R.string.adb_active_notification_title);
+ CharSequence message = r.getText(
+ com.android.internal.R.string.adb_active_notification_message);
+
+ if (mAdbNotification == null) {
+ mAdbNotification = new Notification();
+ mAdbNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
+ mAdbNotification.when = 0;
+ mAdbNotification.flags = Notification.FLAG_ONGOING_EVENT;
+ mAdbNotification.tickerText = title;
+ mAdbNotification.defaults |= Notification.DEFAULT_SOUND;
+ }
+
+ Intent intent = new Intent(
+ Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ // Note: we are hard-coding the component because this is
+ // an important security UI that we don't want anyone
+ // intercepting.
+ intent.setComponent(new ComponentName("com.android.settings",
+ "com.android.settings.DevelopmentSettings"));
+ PendingIntent pi = PendingIntent.getActivity(mContext, 0,
+ intent, 0);
+
+ mAdbNotification.setLatestEventInfo(mContext, title, message, pi);
+
+ mAdbNotificationShown = true;
+ notificationManager.notify(
+ com.android.internal.R.string.adb_active_notification_title,
+ mAdbNotification);
+ }
+ }
+
+ } else if (mAdbNotificationShown) {
+ NotificationManager notificationManager = (NotificationManager) mContext
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ if (notificationManager != null) {
+ mAdbNotificationShown = false;
+ notificationManager.cancel(
+ com.android.internal.R.string.adb_active_notification_title);
+ }
+ }
+ }
+
// ======================================================================
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index dd3d38c..7a8d4e5 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -99,7 +99,7 @@ public class StatusBarPolicy {
private IBinder mBatteryIcon;
private IconData mBatteryData;
private boolean mBatteryFirst = true;
- private boolean mBatteryPlugged;
+ private int mBatteryPlugged;
private int mBatteryLevel;
private int mBatteryThreshold = 0; // index into mBatteryThresholds
private int[] mBatteryThresholds = new int[] { 20, 15, -1 };
@@ -108,6 +108,7 @@ public class StatusBarPolicy {
private View mBatteryView;
private int mBatteryViewSequence;
private boolean mBatteryShowLowOnEndCall = false;
+ private boolean mSentLowBatteryBroadcast = false;
private static final boolean SHOW_LOW_BATTERY_WARNING = true;
// phone
@@ -581,7 +582,7 @@ public class StatusBarPolicy {
mBatteryData.iconLevel = intent.getIntExtra("level", 0);
mService.updateIcon(mBatteryIcon, mBatteryData, null);
- boolean plugged = intent.getIntExtra("plugged", 0) != 0;
+ int plugged = intent.getIntExtra("plugged", 0);
int level = intent.getIntExtra("level", -1);
if (false) {
Log.d(TAG, "updateBattery level=" + level
@@ -592,7 +593,7 @@ public class StatusBarPolicy {
+ " mBatteryFirst=" + mBatteryFirst);
}
- boolean oldPlugged = mBatteryPlugged;
+ int oldPlugged = mBatteryPlugged;
int oldThreshold = mBatteryThreshold;
pickNextBatteryLevel(level);
@@ -619,11 +620,12 @@ public class StatusBarPolicy {
Log.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level
+ " mBatteryThreshold=" + mBatteryThreshold + " oldThreshold=" + oldThreshold);
}
- if (!plugged
- && ((oldPlugged && level < mBatteryThresholds[BATTERY_THRESHOLD_WARNING])
+ if (plugged == 0
+ && ((oldPlugged != 0 && level < mBatteryThresholds[BATTERY_THRESHOLD_WARNING])
|| (mBatteryThreshold > oldThreshold
&& mBatteryThreshold > BATTERY_THRESHOLD_WARNING))) {
// Broadcast the low battery warning
+ mSentLowBatteryBroadcast = true;
mContext.sendBroadcast(new Intent(Intent.ACTION_BATTERY_LOW));
if (SHOW_LOW_BATTERY_WARNING) {
@@ -639,7 +641,11 @@ public class StatusBarPolicy {
mBatteryShowLowOnEndCall = true;
}
}
- } else if (mBatteryThreshold == BATTERY_THRESHOLD_CLOSE_WARNING) {
+ } else if (mBatteryThreshold < BATTERY_THRESHOLD_WARNING) {
+ if (mSentLowBatteryBroadcast == true) {
+ mSentLowBatteryBroadcast = false;
+ mContext.sendBroadcast(new Intent(Intent.ACTION_BATTERY_OKAY));
+ }
if (SHOW_LOW_BATTERY_WARNING) {
if (mLowBatteryDialog != null) {
mLowBatteryDialog.dismiss();
@@ -763,7 +769,7 @@ public class StatusBarPolicy {
}
if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
if (mBatteryShowLowOnEndCall) {
- if (!mBatteryPlugged) {
+ if (mBatteryPlugged == 0) {
showLowBatteryWarning();
}
mBatteryShowLowOnEndCall = false;