Merge commit '1dac277f' into manualmerge

Required rewriting the okay battery broadcast stuff.

Conflicts:
	services/java/com/android/server/status/StatusBarPolicy.java
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 596053d..5cdce5b 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -92,6 +92,7 @@
     // This should probably be exposed in the API, though it's not critical
     private static final int BATTERY_PLUGGED_NONE = 0;
 
+    private static final int BATTERY_LEVEL_CLOSE_WARNING = 20;
     private static final int BATTERY_LEVEL_WARNING = 15;
 
     private final Context mContext;
@@ -122,6 +123,7 @@
     private long mDischargeStartTime;
     private int mDischargeStartLevel;
     
+    private boolean mSentLowBatteryBroadcast = false;
     
     public BatteryService(Context context) {
         mContext = context;
@@ -286,7 +288,11 @@
 
             sendIntent();
             if (sendBatteryLow) {
+                mSentLowBatteryBroadcast = true;
                 mContext.sendBroadcast(new Intent(Intent.ACTION_BATTERY_LOW));
+            } else if (mSentLowBatteryBroadcast && mLastBatteryLevel >= BATTERY_LEVEL_CLOSE_WARNING) {
+                mSentLowBatteryBroadcast = false;
+                mContext.sendBroadcast(new Intent(Intent.ACTION_BATTERY_OKAY));
             }
             
             // This needs to be done after sendIntent() so that we get the lastest battery stats.
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.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 @@
     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 @@
                     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 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 @@
         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 @@
         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 059dc7b..c8db95b 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -76,12 +76,8 @@
     private static StatusBarPolicy sInstance;
 
     // message codes for the handler
-    private static final int EVENT_DATA_CONN_STATE_CHANGED = 2;
-    private static final int EVENT_DATA_ACTIVITY = 3;
     private static final int EVENT_BATTERY_CLOSE = 4;
 
-    private static final int BATTERY_LEVEL_CLOSE_WARNING = 20;
-
     private final Context mContext;
     private final StatusBarService mService;
     private final Handler mHandler = new StatusBarHandler();
@@ -357,6 +353,9 @@
             else if (action.equals(Intent.ACTION_TIME_CHANGED)) {
                 updateClock();
             }
+            else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+                updateBattery(intent);
+            }
             else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
                 updateClock();
             }
@@ -371,12 +370,12 @@
             else if (action.equals(Intent.ACTION_SYNC_STATE_CHANGED)) {
                 updateSyncState(intent);
             }
-            else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
-                updateBattery(intent);
-            }
             else if (action.equals(Intent.ACTION_BATTERY_LOW)) {
                 onBatteryLow(intent);
             }
+            else if (action.equals(Intent.ACTION_BATTERY_OKAY)) {
+                onBatteryOkay(intent);
+            }
             else if (action.equals(BluetoothIntent.BLUETOOTH_STATE_CHANGED_ACTION) ||
                     action.equals(BluetoothIntent.HEADSET_STATE_CHANGED_ACTION) ||
                     action.equals(BluetoothA2dp.SINK_STATE_CHANGED_ACTION)) {
@@ -519,6 +518,7 @@
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
         filter.addAction(Intent.ACTION_BATTERY_LOW);
+        filter.addAction(Intent.ACTION_BATTERY_OKAY);
         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
         filter.addAction(Intent.ACTION_ALARM_CHANGED);
         filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
@@ -601,13 +601,6 @@
         if (false) {
             Log.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level);
         }
-
-        if (mLowBatteryDialog != null
-            && mBatteryLevel >= BATTERY_LEVEL_CLOSE_WARNING
-            && SHOW_LOW_BATTERY_WARNING) {
-            mLowBatteryDialog.dismiss();
-            mBatteryShowLowOnEndCall = false;
-        }
     }
 
     private void onBatteryLow(Intent intent) {
@@ -626,6 +619,14 @@
         }
     }
 
+    private void onBatteryOkay(Intent intent) {
+        if (mLowBatteryDialog != null
+                && SHOW_LOW_BATTERY_WARNING) {
+            mLowBatteryDialog.dismiss();
+            mBatteryShowLowOnEndCall = false;
+        }
+    }
+
     private void showBatteryView() {    
         closeLastBatteryView();
         if (mLowBatteryDialog != null) {