am d5b94fe6: am ff2927dc: Merge "Optimize Opp Notification" into gingerbread

Merge commit 'd5b94fe6cd8144b9c6f0d6de35080f8ca49c601d'

* commit 'd5b94fe6cd8144b9c6f0d6de35080f8ca49c601d':
  Optimize Opp Notification
diff --git a/src/com/android/bluetooth/opp/BluetoothOppNotification.java b/src/com/android/bluetooth/opp/BluetoothOppNotification.java
index 310a289..0600cb5 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppNotification.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppNotification.java
@@ -43,6 +43,8 @@
 import android.net.Uri;
 import android.util.Log;
 import android.widget.RemoteViews;
+import android.os.Handler;
+import android.os.Message;
 import android.os.Process;
 import java.util.HashMap;
 
@@ -87,9 +89,7 @@
 
     private NotificationUpdateThread mUpdateNotificationThread;
 
-    private boolean mPendingUpdate = false;
-
-    private boolean mFinised = false;
+    private int mPendingUpdate = 0;
 
     private static final int NOTIFICATION_ID_OUTBOUND = -1000005;
 
@@ -127,26 +127,52 @@
         mNotifications = new HashMap<String, NotificationItem>();
     }
 
-    public void finishNotification() {
-        synchronized (BluetoothOppNotification.this) {
-            mFinised = true;
-        }
-    }
-
     /**
      * Update the notification ui.
      */
     public void updateNotification() {
         synchronized (BluetoothOppNotification.this) {
-            mPendingUpdate = true;
-            if (mUpdateNotificationThread == null) {
-                mUpdateNotificationThread = new NotificationUpdateThread();
-                mUpdateNotificationThread.start();
-                mFinised = false;
+            mPendingUpdate++;
+            if (mPendingUpdate > 1) {
+                if (V) Log.v(TAG, "update too frequent, put in queue");
+                return;
+            }
+            if (!mHandler.hasMessages(NOTIFY)) {
+                if (V) Log.v(TAG, "send message");
+                mHandler.sendMessage(mHandler.obtainMessage(NOTIFY));
             }
         }
     }
 
+    private static final int NOTIFY = 0;
+    // Use 1 second timer to limit notification frequency.
+    // 1. On the first notification, create the update thread.
+    //    Buffer other updates.
+    // 2. Update thread will clear mPendingUpdate.
+    // 3. Handler sends a delayed message to self
+    // 4. Handler checks if there are any more updates after 1 second.
+    // 5. If there is an update, update it else stop.
+    private Handler mHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case NOTIFY:
+                    synchronized (BluetoothOppNotification.this) {
+                        if (mPendingUpdate > 0 && mUpdateNotificationThread == null) {
+                            if (V) Log.v(TAG, "new notify threadi!");
+                            mUpdateNotificationThread = new NotificationUpdateThread();
+                            mUpdateNotificationThread.start();
+                            if (V) Log.v(TAG, "send delay message");
+                            mHandler.sendMessageDelayed(mHandler.obtainMessage(NOTIFY), 1000);
+                        } else if (mPendingUpdate > 0) {
+                            if (V) Log.v(TAG, "previous thread is not finished yet");
+                            mHandler.sendMessageDelayed(mHandler.obtainMessage(NOTIFY), 1000);
+                        }
+                        break;
+                    }
+              }
+         }
+    };
+
     private class NotificationUpdateThread extends Thread {
 
         public NotificationUpdateThread() {
@@ -156,21 +182,18 @@
         @Override
         public void run() {
             Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-            for (;;) {
-                synchronized (BluetoothOppNotification.this) {
-                    if (mUpdateNotificationThread != this) {
-                        throw new IllegalStateException(
-                                "multiple UpdateThreads in BluetoothOppNotification");
-                    }
-                    if (!mPendingUpdate && mFinised) {
-                        mUpdateNotificationThread = null;
-                        return;
-                    }
-                    mPendingUpdate = false;
+            synchronized (BluetoothOppNotification.this) {
+                if (mUpdateNotificationThread != this) {
+                    throw new IllegalStateException(
+                            "multiple UpdateThreads in BluetoothOppNotification");
                 }
-                updateActiveNotification();
-                updateCompletedNotification();
-                updateIncomingFileConfirmNotification();
+                mPendingUpdate = 0;
+            }
+            updateActiveNotification();
+            updateCompletedNotification();
+            updateIncomingFileConfirmNotification();
+            synchronized (BluetoothOppNotification.this) {
+                mUpdateNotificationThread = null;
             }
         }
     }
diff --git a/src/com/android/bluetooth/opp/BluetoothOppService.java b/src/com/android/bluetooth/opp/BluetoothOppService.java
index 51b282c..35a9dfb 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppService.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppService.java
@@ -158,7 +158,6 @@
         mNotifier = new BluetoothOppNotification(this);
         mNotifier.mNotificationMgr.cancelAll();
         mNotifier.updateNotification();
-        mNotifier.finishNotification();
 
         trimDatabase();
 
@@ -316,7 +315,6 @@
     public void onDestroy() {
         if (V) Log.v(TAG, "Service onDestroy");
         super.onDestroy();
-        mNotifier.finishNotification();
         getContentResolver().unregisterContentObserver(mObserver);
         unregisterReceiver(mBluetoothReceiver);
         mSocketListener.stop();
@@ -391,8 +389,6 @@
                             stopSelf();
                             break;
                         }
-                        mNotifier.updateNotification();
-                        mNotifier.finishNotification();
                         return;
                     }
                     mPendingUpdate = false;
diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java b/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java
index 1f5d9d9..accdbc0 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java
@@ -285,7 +285,6 @@
         if (!adapter.isEnabled()) {
             if (V) Log.v(TAG, "Bluetooth is not enabled, update notification manually.");
             mNotifier.updateNotification();
-            mNotifier.finishNotification();
         }
     }
 }