Merge "Pipe potential wakeup events from sensor service" into udc-dev
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 6d8c4a9..c2aebd7 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -450,6 +450,27 @@
     }
 
     /**
+     * Returns the {@link Sensor} object identified by the given sensor handle.
+     *
+     * The raw sensor handle integer is an implementation detail and as such this method should only
+     * be used by internal system components.
+     *
+     * @param sensorHandle The integer handle uniquely identifying the sensor.
+     * @return A Sensor object identified by the given {@code sensorHandle}, if such a sensor
+     * exists, {@code null} otherwise.
+     *
+     * @hide
+     */
+    public @Nullable Sensor getSensorByHandle(int sensorHandle) {
+        for (final Sensor sensor : getFullSensorList()) {
+            if (sensor.getHandle() == sensorHandle) {
+                return sensor;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Use this method to get a list of available dynamic sensors of a certain type.
      * Make multiple calls to get sensors of different types or use
      * {@link android.hardware.Sensor#TYPE_ALL Sensor.TYPE_ALL} to get all dynamic sensors.
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 73157e6..d8ab6f7 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -222,6 +222,12 @@
 
     /** @hide */
     @Override
+    public Sensor getSensorByHandle(int sensorHandle) {
+        return mHandleToSensor.get(sensorHandle);
+    }
+
+    /** @hide */
+    @Override
     protected List<Sensor> getFullDynamicSensorList() {
         // only set up broadcast receiver if the application tries to find dynamic sensors or
         // explicitly register a DynamicSensorCallback
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 787b594..65394bd 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -63,6 +63,7 @@
     void noteResetCamera();
     @EnforcePermission("UPDATE_DEVICE_STATS")
     void noteResetFlashlight();
+    void noteWakeupSensorEvent(long elapsedNanos, int uid, int handle);
 
     // Remaining methods are only used in Java.
     @EnforcePermission("BATTERY_STATS")
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 0744f75..c0b3a90 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -37,6 +37,8 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
 import android.hardware.power.stats.PowerEntity;
 import android.hardware.power.stats.State;
 import android.hardware.power.stats.StateResidency;
@@ -149,7 +151,6 @@
 
     private final PowerProfile mPowerProfile;
     final BatteryStatsImpl mStats;
-    @GuardedBy("mWakeupStats")
     final CpuWakeupStats mCpuWakeupStats;
     private final BatteryUsageStatsStore mBatteryUsageStatsStore;
     private final BatteryStatsImpl.UserInfoProvider mUserManagerUserInfoProvider;
@@ -1261,6 +1262,26 @@
     }
 
     @Override
+    public void noteWakeupSensorEvent(long elapsedNanos, int uid, int sensorHandle) {
+        final int callingUid = Binder.getCallingUid();
+        if (callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException("Calling uid " + callingUid + " is not system uid");
+        }
+
+        final SensorManager sm = mContext.getSystemService(SensorManager.class);
+        final Sensor sensor = sm.getSensorByHandle(sensorHandle);
+        if (sensor == null) {
+            Slog.w(TAG, "Unknown sensor handle " + sensorHandle
+                    + " received in noteWakeupSensorEvent");
+            return;
+        }
+        Slog.i(TAG, "Sensor " + sensor + " wakeup event at " + elapsedNanos + " sent to uid "
+                + uid);
+        // TODO (b/275436924): Remove log and pipe to CpuWakeupStats for wakeup attribution
+        // This method should return as quickly as possible. Use mHandler#post to do longer work.
+    }
+
+    @Override
     @EnforcePermission(UPDATE_DEVICE_STATS)
     public void noteStopSensor(final int uid, final int sensor) {
         super.noteStopSensor_enforcePermission();