Eliminate special battery calls by WindowManager

Previous to this change the WindowManager was notifying the
BatteryDtatsService about windows that keep the screen on. WM used a
custom WakeLock tag to indicate to PowerManagerService that it had
already notified the BatteryStatsService.

This change eliminates WindowManager notifying the BatteryStatsService
and lets PowerManagerService do the job.

Fixes bug 7030326.

Change-Id: I666dc6ef8f094b8d3d109fea6876be058e057b4f
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index efdbcac..c804060 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -275,13 +275,6 @@
     public static final int USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS = 1 << 0;
 
     /**
-     * Special wake lock tag used for the wake lock in the Window Manager that handles the
-     * {@link android.view.WindowManager.LayoutParams#FLAG_KEEP_SCREEN_ON} flag.
-     * @hide
-     */
-    public static final String KEEP_SCREEN_ON_FLAG_TAG = "KEEP_SCREEN_ON_FLAG";
-
-    /**
      * Go to sleep reason code: Going to sleep due by user request.
      * @hide
      */
diff --git a/services/java/com/android/server/power/Notifier.java b/services/java/com/android/server/power/Notifier.java
index 37384d2..9d928e5 100644
--- a/services/java/com/android/server/power/Notifier.java
+++ b/services/java/com/android/server/power/Notifier.java
@@ -28,7 +28,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.WorkSource;
@@ -117,19 +116,15 @@
                     + ", workSource=" + workSource);
         }
 
-        if (!isWakeLockAlreadyReportedToBatteryStats(tag, ownerUid)) {
-            try {
-                final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
-                if (workSource != null) {
-                    mBatteryStats.noteStartWakelockFromSource(
-                            workSource, ownerPid, tag, monitorType);
-                } else {
-                    mBatteryStats.noteStartWakelock(
-                            ownerUid, ownerPid, tag, monitorType);
-                }
-            } catch (RemoteException ex) {
-                // Ignore
+        try {
+            final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+            if (workSource != null) {
+                mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, monitorType);
+            } else {
+                mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, monitorType);
             }
+        } catch (RemoteException ex) {
+            // Ignore
         }
     }
 
@@ -144,30 +139,18 @@
                     + ", workSource=" + workSource);
         }
 
-        if (!isWakeLockAlreadyReportedToBatteryStats(tag, ownerUid)) {
-            try {
-                final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
-                if (workSource != null) {
-                    mBatteryStats.noteStopWakelockFromSource(
-                            workSource, ownerPid, tag, monitorType);
-                } else {
-                    mBatteryStats.noteStopWakelock(
-                            ownerUid, ownerPid, tag, monitorType);
-                }
-            } catch (RemoteException ex) {
-                // Ignore
+        try {
+            final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+            if (workSource != null) {
+                mBatteryStats.noteStopWakelockFromSource(workSource, ownerPid, tag, monitorType);
+            } else {
+                mBatteryStats.noteStopWakelock(ownerUid, ownerPid, tag, monitorType);
             }
+        } catch (RemoteException ex) {
+            // Ignore
         }
     }
 
-    private static boolean isWakeLockAlreadyReportedToBatteryStats(String tag, int uid) {
-        // The window manager already takes care of reporting battery stats associated
-        // with the use of the KEEP_SCREEN_ON_FLAG.
-        // TODO: Use a WorkSource to handle this situation instead of hardcoding it here.
-        return uid == Process.SYSTEM_UID
-                && tag.equals(PowerManager.KEEP_SCREEN_ON_FLAG_TAG);
-    }
-
     private static int getBatteryStatsWakeLockMonitorType(int flags) {
         switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
             case PowerManager.PARTIAL_WAKE_LOCK:
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index fd90082..b0c5835 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -94,6 +94,7 @@
 import android.os.SystemProperties;
 import android.os.TokenWatcher;
 import android.os.Trace;
+import android.os.WorkSource;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -923,7 +924,7 @@
         mContext.registerReceiver(mBroadcastReceiver, filter);
 
         mHoldingScreenWakeLock = pmc.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
-                | PowerManager.ON_AFTER_RELEASE, PowerManager.KEEP_SCREEN_ON_FLAG_TAG);
+                | PowerManager.ON_AFTER_RELEASE, TAG);
         mHoldingScreenWakeLock.setReferenceCounted(false);
 
         mInputManager = new InputManagerService(context, mInputMonitor);
@@ -7020,7 +7021,7 @@
         public static final int REPORT_APPLICATION_TOKEN_WINDOWS = 8;
         public static final int REPORT_APPLICATION_TOKEN_DRAWN = 9;
         public static final int WINDOW_FREEZE_TIMEOUT = 11;
-        public static final int HOLD_SCREEN_CHANGED = 12;
+
         public static final int APP_TRANSITION_TIMEOUT = 13;
         public static final int PERSIST_ANIMATION_SCALE = 14;
         public static final int FORCE_GC = 15;
@@ -7041,8 +7042,6 @@
         public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
         public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2;
 
-        private Session mLastReportedHold;
-
         public H() {
         }
 
@@ -7294,33 +7293,6 @@
                     break;
                 }
 
-                case HOLD_SCREEN_CHANGED: {
-                    Session oldHold;
-                    Session newHold;
-                    synchronized (mWindowMap) {
-                        oldHold = mLastReportedHold;
-                        newHold = (Session)msg.obj;
-                        mLastReportedHold = newHold;
-                    }
-
-                    if (oldHold != newHold) {
-                        try {
-                            if (oldHold != null) {
-                                mBatteryStats.noteStopWakelock(oldHold.mUid, -1,
-                                        "window",
-                                        BatteryStats.WAKE_TYPE_WINDOW);
-                            }
-                            if (newHold != null) {
-                                mBatteryStats.noteStartWakelock(newHold.mUid, -1,
-                                        "window",
-                                        BatteryStats.WAKE_TYPE_WINDOW);
-                            }
-                        } catch (RemoteException e) {
-                        }
-                    }
-                    break;
-                }
-
                 case APP_TRANSITION_TIMEOUT: {
                     synchronized (mWindowMap) {
                         if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
@@ -9134,7 +9106,7 @@
         // Finally update all input windows now that the window changes have stabilized.
         mInputMonitor.updateInputWindowsLw(true /*force*/);
 
-        setHoldScreenLocked(mInnerFields.mHoldScreen != null);
+        setHoldScreenLocked(mInnerFields.mHoldScreen);
         if (!mDisplayFrozen) {
             if (mInnerFields.mScreenBrightness < 0 || mInnerFields.mScreenBrightness > 1.0f) {
                 mPowerManager.setScreenBrightnessOverrideFromWindowManager(-1);
@@ -9149,11 +9121,6 @@
                         toBrightnessOverride(mInnerFields.mButtonBrightness));
             }
         }
-        if (mInnerFields.mHoldScreen != mHoldingScreenOn) {
-            mHoldingScreenOn = mInnerFields.mHoldScreen;
-            Message m = mH.obtainMessage(H.HOLD_SCREEN_CHANGED, mInnerFields.mHoldScreen);
-            mH.sendMessage(m);
-        }
 
         if (mTurnOnScreen) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!");
@@ -9237,13 +9204,17 @@
         }
     }
 
-    /**
-     * Must be called with the main window manager lock held.
-     */
-    void setHoldScreenLocked(boolean holding) {
-        boolean state = mHoldingScreenWakeLock.isHeld();
-        if (holding != state) {
-            if (holding) {
+    void setHoldScreenLocked(final Session newHoldScreen) {
+        final boolean hold = newHoldScreen != null;
+
+        if (hold && mHoldingScreenOn != newHoldScreen) {
+            mHoldingScreenWakeLock.setWorkSource(new WorkSource(newHoldScreen.mUid));
+        }
+        mHoldingScreenOn = newHoldScreen;
+
+        final boolean state = mHoldingScreenWakeLock.isHeld();
+        if (hold != state) {
+            if (hold) {
                 mPolicy.screenOnStartedLw();
                 mHoldingScreenWakeLock.acquire();
             } else {