BluetoothManager: Make requestControllerActivityInfo one call

Instead of making multiple calls into the Bluetooth service,
make one call that can timeout. This helps prevent cases
when the Bluetooth process hangs and the system_server is calling into
it and causes a WATCHDOG restart.

Bug:28658141

Change-Id: I84d2c025f4ffb452975444e794a64c82569deb0a
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index e64eb7c..bc8d16c 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -139,6 +139,8 @@
       "DUAL"
     };
 
+    private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30;
+
     static {
         classInitNative();
     }
@@ -1410,12 +1412,6 @@
              return service.isActivityAndEnergyReportingSupported();
          }
 
-         public void getActivityEnergyInfoFromController() {
-             AdapterService service = getService();
-             if (service == null) return;
-             service.getActivityEnergyInfoFromController();
-         }
-
          public BluetoothActivityEnergyInfo reportActivityInfo() {
              AdapterService service = getService();
              if (service == null) return null;
@@ -2160,16 +2156,24 @@
           return mAdapterProperties.isActivityAndEnergyReportingSupported();
     }
 
-    private void getActivityEnergyInfoFromController() {
-        enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission");
-        if (isActivityAndEnergyReportingSupported()) {
-            readEnergyInfo();
-        }
-    }
-
     private BluetoothActivityEnergyInfo reportActivityInfo() {
         enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission");
+        if (mAdapterProperties.getState() != BluetoothAdapter.STATE_ON ||
+                !mAdapterProperties.isActivityAndEnergyReportingSupported()) {
+            return null;
+        }
+
+        // Pull the data. The callback will notify mEnergyInfoLock.
+        readEnergyInfo();
+
         synchronized (mEnergyInfoLock) {
+            try {
+                mEnergyInfoLock.wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS);
+            } catch (InterruptedException e) {
+                // Just continue, the energy data may be stale but we won't miss anything next time
+                // we query.
+            }
+
             final BluetoothActivityEnergyInfo info = new BluetoothActivityEnergyInfo(
                     SystemClock.elapsedRealtime(),
                     mStackReportedState,
@@ -2336,6 +2340,7 @@
                         existingTraffic.addTxBytes(traffic.getTxBytes());
                     }
                 }
+                mEnergyInfoLock.notifyAll();
             }
         }