Switch WindowContainer to use ConfigurationContainer

To reduce implementation dupication.
This also involved moving ConfigurationContainer to the wm package.

Test: bit FrameworksServicesTests:com.android.server.wm.ConfigurationContainerTests
Test: bit FrameworksServicesTests:com.android.server.wm.WindowContainerTests
Test: go/wm-smoke
Change-Id: Ibeca7e2ad2685f0984fccc66852d53ed9af0925f
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 3c84941..889bb9b 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -167,6 +167,7 @@
 import com.android.server.am.ActivityStack.ActivityState;
 import com.android.server.wm.AppWindowContainerController;
 import com.android.server.wm.AppWindowContainerListener;
+import com.android.server.wm.ConfigurationContainer;
 import com.android.server.wm.TaskWindowContainerController;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -2223,7 +2224,7 @@
     }
 
     @Override
-    void onOverrideConfigurationChanged(Configuration newConfig) {
+    public void onOverrideConfigurationChanged(Configuration newConfig) {
         final Configuration currentConfig = getOverrideConfiguration();
         if (currentConfig.equals(newConfig)) {
             return;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 9925ba0..45e8fc3 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -125,6 +125,7 @@
 import com.android.internal.os.BatteryStatsImpl;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerService.ItemMatcher;
+import com.android.server.wm.ConfigurationContainer;
 import com.android.server.wm.StackWindowController;
 import com.android.server.wm.StackWindowListener;
 import com.android.server.wm.WindowManagerService;
@@ -209,7 +210,7 @@
     }
 
     @Override
-    void onParentChanged() {
+    protected void onParentChanged() {
         super.onParentChanged();
         mStackSupervisor.updateUIDsPresentOnDisplay();
     }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 5f42cdb..590cc7c 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -134,7 +134,6 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.ParcelFileDescriptor;
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
@@ -167,6 +166,7 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
 import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.wm.ConfigurationContainer;
 import com.android.server.wm.PinnedStackWindowController;
 import com.android.server.wm.WindowManagerService;
 
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 5753fbc..64ce1b9 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -53,6 +53,7 @@
 import com.android.internal.util.XmlUtils;
 
 import com.android.server.wm.AppWindowContainerController;
+import com.android.server.wm.ConfigurationContainer;
 import com.android.server.wm.StackWindowController;
 import com.android.server.wm.TaskWindowContainerController;
 import com.android.server.wm.TaskWindowContainerListener;
@@ -971,7 +972,7 @@
     }
 
     @Override
-    void onParentChanged() {
+    protected void onParentChanged() {
         super.onParentChanged();
         mService.mStackSupervisor.updateUIDsPresentOnDisplay();
     }
diff --git a/services/core/java/com/android/server/am/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
similarity index 87%
rename from services/core/java/com/android/server/am/ConfigurationContainer.java
rename to services/core/java/com/android/server/wm/ConfigurationContainer.java
index 3d60681..64bfbd0 100644
--- a/services/core/java/com/android/server/am/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.server.am;
+package com.android.server.wm;
 
 import android.content.res.Configuration;
 
@@ -22,9 +22,7 @@
  * Contains common logic for classes that have override configurations and are organized in a
  * hierarchy.
  */
-// TODO(b/36505427): Move to wm package and have WindowContainer use this instead of having its own
-// implementation for merging configuration.
-abstract class ConfigurationContainer<E extends ConfigurationContainer> {
+public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
 
     /** Contains override configuration settings applied to this configuration container. */
     private Configuration mOverrideConfiguration = new Configuration();
@@ -47,7 +45,7 @@
      * This method should be used for getting settings applied in each particular level of the
      * hierarchy.
      */
-    Configuration getConfiguration() {
+    public Configuration getConfiguration() {
         return mFullConfiguration;
     }
 
@@ -55,7 +53,7 @@
      * Notify that parent config changed and we need to update full configuration.
      * @see #mFullConfiguration
      */
-    void onConfigurationChanged(Configuration newParentConfig) {
+    public void onConfigurationChanged(Configuration newParentConfig) {
         mFullConfiguration.setTo(newParentConfig);
         mFullConfiguration.updateFrom(mOverrideConfiguration);
         for (int i = getChildCount() - 1; i >= 0; --i) {
@@ -65,7 +63,7 @@
     }
 
     /** Returns override configuration applied to this configuration container. */
-    Configuration getOverrideConfiguration() {
+    public Configuration getOverrideConfiguration() {
         return mOverrideConfiguration;
     }
 
@@ -74,7 +72,7 @@
      * @see #mOverrideConfiguration
      * @see #mFullConfiguration
      */
-    void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
+    public void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
         mOverrideConfiguration.setTo(overrideConfiguration);
         // Update full configuration of this container and all its children.
         final ConfigurationContainer parent = getParent();
@@ -87,7 +85,7 @@
      * Get merged override configuration from the top of the hierarchy down to this particular
      * instance. This should be reported to client as override config.
      */
-    Configuration getMergedOverrideConfiguration() {
+    public Configuration getMergedOverrideConfiguration() {
         return mMergedOverrideConfiguration;
     }
 
@@ -97,7 +95,7 @@
      * override config.
      * @see #mMergedOverrideConfiguration
      */
-    private void onMergedOverrideConfigurationChanged() {
+    void onMergedOverrideConfigurationChanged() {
         final ConfigurationContainer parent = getParent();
         if (parent != null) {
             mMergedOverrideConfiguration.setTo(parent.getMergedOverrideConfiguration());
@@ -114,7 +112,7 @@
     /**
      * Must be called when new parent for the container was set.
      */
-    void onParentChanged() {
+    protected void onParentChanged() {
         final ConfigurationContainer parent = getParent();
         // Removing parent usually means that we've detached this entity to destroy it or to attach
         // to another parent. In both cases we don't need to update the configuration now.
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a37b2e5..dff963a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1446,7 +1446,7 @@
     }
 
     @VisibleForTesting
-    int getStaskPosById(int stackId) {
+    int getStackPosById(int stackId) {
         for (int i = mTaskStackContainers.size() - 1; i >= 0; --i) {
             final TaskStack stack = mTaskStackContainers.get(i);
             if (stack.mStackId == stackId) {
@@ -1457,7 +1457,7 @@
     }
 
     @Override
-    void onConfigurationChanged(Configuration newParentConfig) {
+    public void onConfigurationChanged(Configuration newParentConfig) {
         super.onConfigurationChanged(newParentConfig);
 
         // The display size information is heavily dependent on the resources in the current
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 233e75b..0d6c7e3 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -359,7 +359,7 @@
     }
 
     @Override
-    void onConfigurationChanged(Configuration newParentConfig) {
+    public void onConfigurationChanged(Configuration newParentConfig) {
         prepareFreezingTaskBounds();
         super.onConfigurationChanged(newParentConfig);
 
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 600bc5c..018f738 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -38,7 +38,8 @@
  * The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime
  * changes are made to this class.
  */
-class WindowContainer<E extends WindowContainer> implements Comparable<WindowContainer> {
+class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
+        implements Comparable<WindowContainer> {
 
     static final int POSITION_TOP = Integer.MAX_VALUE;
     static final int POSITION_BOTTOM = Integer.MIN_VALUE;
@@ -54,22 +55,6 @@
     // screen with the top-most window container at the tail of the list.
     protected final WindowList<E> mChildren = new WindowList<E>();
 
-    /** Contains override configuration settings applied to this window container. */
-    private Configuration mOverrideConfiguration = new Configuration();
-
-    /**
-     * Contains full configuration applied to this window container. Corresponds to full parent's
-     * config with applied {@link #mOverrideConfiguration}.
-     */
-    private Configuration mFullConfiguration = new Configuration();
-
-    /**
-     * Contains merged override configuration settings from the top of the hierarchy down to this
-     * particular instance. It is different from {@link #mFullConfiguration} because it starts from
-     * topmost container's override config instead of global config.
-     */
-    private Configuration mMergedOverrideConfiguration = new Configuration();
-
     // The specified orientation for this window container.
     protected int mOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
 
@@ -79,17 +64,29 @@
     // The owner/creator for this container. No controller if null.
     private WindowContainerController mController;
 
+    @Override
     final protected WindowContainer getParent() {
         return mParent;
     }
 
+
+    @Override
+    final protected int getChildCount() {
+        return mChildren.size();
+    }
+
+    @Override
+    final protected E getChildAt(int index) {
+        return mChildren.get(index);
+    }
+
     final protected void setParent(WindowContainer parent) {
         mParent = parent;
         // Removing parent usually means that we've detached this entity to destroy it or to attach
         // to another parent. In both cases we don't need to update the configuration now.
         if (mParent != null) {
             // Update full configuration of this container and all its children.
-            onConfigurationChanged(mParent.mFullConfiguration);
+            onConfigurationChanged(mParent.getConfiguration());
             // Update merged override configuration of this container and all its children.
             onMergedOverrideConfigurationChanged();
         }
@@ -282,44 +279,13 @@
     }
 
     /**
-     * Returns full configuration applied to this window container.
-     * This method should be used for getting settings applied in each particular level of the
-     * hierarchy.
-     */
-    Configuration getConfiguration() {
-        return mFullConfiguration;
-    }
-
-    /**
-     * Notify that parent config changed and we need to update full configuration.
-     * @see #mFullConfiguration
-     */
-    void onConfigurationChanged(Configuration newParentConfig) {
-        mFullConfiguration.setTo(newParentConfig);
-        mFullConfiguration.updateFrom(mOverrideConfiguration);
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowContainer child = mChildren.get(i);
-            child.onConfigurationChanged(mFullConfiguration);
-        }
-    }
-
-    /** Returns override configuration applied to this window container. */
-    Configuration getOverrideConfiguration() {
-        return mOverrideConfiguration;
-    }
-
-    /**
      * Update override configuration and recalculate full config.
      * @see #mOverrideConfiguration
      * @see #mFullConfiguration
      */
-    void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
-        mOverrideConfiguration.setTo(overrideConfiguration);
-        // Update full configuration of this container and all its children.
-        onConfigurationChanged(mParent != null ? mParent.getConfiguration() : EMPTY);
-        // Update merged override config of this container and all its children.
-        onMergedOverrideConfigurationChanged();
-
+    @Override
+    final public void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
+        super.onOverrideConfigurationChanged(overrideConfiguration);
         if (mParent != null) {
             mParent.onDescendantOverrideConfigurationChanged();
         }
@@ -335,33 +301,6 @@
     }
 
     /**
-     * Get merged override configuration from the top of the hierarchy down to this
-     * particular instance. This should be reported to client as override config.
-     */
-    Configuration getMergedOverrideConfiguration() {
-        return mMergedOverrideConfiguration;
-    }
-
-    /**
-     * Update merged override configuration based on corresponding parent's config and notify all
-     * its children. If there is no parent, merged override configuration will set equal to current
-     * override config.
-     * @see #mMergedOverrideConfiguration
-     */
-    private void onMergedOverrideConfigurationChanged() {
-        if (mParent != null) {
-            mMergedOverrideConfiguration.setTo(mParent.getMergedOverrideConfiguration());
-            mMergedOverrideConfiguration.updateFrom(mOverrideConfiguration);
-        } else {
-            mMergedOverrideConfiguration.setTo(mOverrideConfiguration);
-        }
-        for (int i = mChildren.size() - 1; i >= 0; --i) {
-            final WindowContainer child = mChildren.get(i);
-            child.onMergedOverrideConfigurationChanged();
-        }
-    }
-
-    /**
      * Notify that the display this container is on has changed.
      * @param dc The new display this container is on.
      */