Fix lack of dim layer behind "Power off" window.

This enables dim behind functionality for both tasks and stacks and
groups it inside a controller that manages the dim layers (including
shared dim layers for full screen tasks/stacks).

Bug: 24331704

Change-Id: I0d1ba996d9e00d05e0203166b82268da00fbb35e
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6b5ecdc..f13f350 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -115,6 +115,8 @@
 
     final DockedStackDividerController mDividerControllerLocked;
 
+    final DimBehindController mDimBehindController;
+
     /**
      * @param display May not be null.
      * @param service You know.
@@ -128,6 +130,7 @@
         mService = service;
         initializeDisplayBaseInfo();
         mDividerControllerLocked = new DockedStackDividerController(service.mContext, this);
+        mDimBehindController = new DimBehindController(this);
     }
 
     int getDisplayId() {
@@ -246,6 +249,7 @@
     }
 
     void detachStack(TaskStack stack) {
+        mDimBehindController.removeDimLayerUser(stack);
         mStacks.remove(stack);
     }
 
@@ -382,54 +386,23 @@
     }
 
     boolean animateDimLayers() {
-        boolean result = false;
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
-            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
-                final Task task = tasks.get(taskNdx);
-                result |= task.animateDimLayers();
-                if (task.isFullscreen()) {
-                    // No point in continuing as this task covers the entire screen.
-                    // Also, fullscreen tasks all share the same dim layer, so we don't want
-                    // processing of fullscreen task below this one affecting the dim layer state.
-                    return result;
-                }
-            }
-        }
-        return result;
+        return mDimBehindController.animateDimLayers();
     }
 
     void resetDimming() {
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
-            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
-                tasks.get(taskNdx).clearContinueDimming();
-            }
-        }
+        mDimBehindController.resetDimming();
     }
 
     boolean isDimming() {
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
-            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
-                if (tasks.get(taskNdx).isDimming()) {
-                    return true;
-                }
-            }
-        }
-        return false;
+        return mDimBehindController.isDimming();
     }
 
     void stopDimmingIfNeeded() {
-        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
-            final ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks();
-            for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
-                tasks.get(taskNdx).stopDimmingIfNeeded();
-            }
-        }
+        mDimBehindController.stopDimmingIfNeeded();
     }
 
     void close() {
+        mDimBehindController.close();
         for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
             mStacks.get(stackNdx).close();
         }
@@ -576,6 +549,7 @@
             }
         }
         pw.println();
+        mDimBehindController.dump(prefix + "  ", pw);
     }
 
     @Override