OSDN Git Service

DO NOT MERGE Move wake alarm setting and releasing into AdapterService's handler
authorMatthew Xie <mattx@google.com>
Tue, 25 Nov 2014 23:19:51 +0000 (15:19 -0800)
committerSimon Wilson <simonwilson@google.com>
Wed, 26 Nov 2014 00:11:27 +0000 (16:11 -0800)
The setting and firing of the alarm wake lock came from different thread
and cause deadlock.

Note: not merging down into MR1 so that further testing can be done.

Bug: 18511282
Change-Id: I32b18cb21d503f10a8e49b1e86c949ebe96b3482

src/com/android/bluetooth/btservice/AdapterService.java

index 9141d3e..22bd1de 100644 (file)
@@ -495,6 +495,8 @@ public class AdapterService extends Service {
     private static final int MESSAGE_PROFILE_CONNECTION_STATE_CHANGED=20;
     private static final int MESSAGE_CONNECT_OTHER_PROFILES = 30;
     private static final int MESSAGE_PROFILE_INIT_PRIORITIES=40;
+    private static final int MESSAGE_SET_WAKE_ALARM = 100;
+    private static final int MESSAGE_RELEASE_WAKE_ALARM = 110;
     private static final int CONNECT_OTHER_PROFILES_TIMEOUT= 6000;
 
     private final Handler mHandler = new Handler() {
@@ -528,6 +530,17 @@ public class AdapterService extends Service {
                     processConnectOtherProfiles((BluetoothDevice) msg.obj,msg.arg1);
                 }
                     break;
+                case MESSAGE_SET_WAKE_ALARM: {
+                    debugLog( "handleMessage() - MESSAGE_SET_WAKE_ALARM");
+                    processSetWakeAlarm((Long) msg.obj, msg.arg1);
+                }
+                    break;
+                case MESSAGE_RELEASE_WAKE_ALARM: {
+                    debugLog( "handleMessage() - MESSAGE_RELEASE_WAKE_ALARM");
+                    mPendingAlarm = null;
+                    alarmFiredNative();
+                }
+                    break;
             }
         }
     };
@@ -1723,24 +1736,30 @@ public class AdapterService extends Service {
     }
 
     // This function is called from JNI. It allows native code to set a single wake
-    // alarm. If an alarm is already pending and a new request comes in, the alarm
-    // will be rescheduled (i.e. the previously set alarm will be cancelled).
+    // alarm.
     private boolean setWakeAlarm(long delayMillis, boolean shouldWake) {
-        synchronized (this) {
-            if (mPendingAlarm != null) {
-                mAlarmManager.cancel(mPendingAlarm);
-            }
+        Message m = mHandler.obtainMessage(MESSAGE_SET_WAKE_ALARM);
+        m.obj = new Long(delayMillis);
+        // alarm type
+        m.arg1 = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP
+            : AlarmManager.ELAPSED_REALTIME;
+        mHandler.sendMessage(m);
 
-            long wakeupTime = SystemClock.elapsedRealtime() + delayMillis;
-            int type = shouldWake
-                ? AlarmManager.ELAPSED_REALTIME_WAKEUP
-                : AlarmManager.ELAPSED_REALTIME;
+        return true;
+    }
 
-            Intent intent = new Intent(ACTION_ALARM_WAKEUP);
-            mPendingAlarm = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
-            mAlarmManager.setExact(type, wakeupTime, mPendingAlarm);
-            return true;
+    // If an alarm is already pending and a new request comes in, the alarm
+    // will be rescheduled (i.e. the previously set alarm will be cancelled).
+    private void processSetWakeAlarm(long delayMillis, int alarmType) {
+        if (mPendingAlarm != null) {
+            mAlarmManager.cancel(mPendingAlarm);
         }
+
+        long wakeupTime = SystemClock.elapsedRealtime() + delayMillis;
+
+        Intent intent = new Intent(ACTION_ALARM_WAKEUP);
+        mPendingAlarm = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+        mAlarmManager.setExact(alarmType, wakeupTime, mPendingAlarm);
     }
 
     // This function is called from JNI. It allows native code to acquire a single wake lock.
@@ -1818,10 +1837,7 @@ public class AdapterService extends Service {
     private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            synchronized (AdapterService.this) {
-                mPendingAlarm = null;
-                alarmFiredNative();
-            }
+            mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_RELEASE_WAKE_ALARM));
         }
     };