Introducing ConfigurationContainerListener

Class provides a structured way for window containers on the window
manager side to listener for configuration changes happening in the
window controllers on the activity manager side so things stay in
sync and they don't miss anything.

Test: bit FrameworksServicesTests:com.android.server.wm.WindowContainerControllerTests
Test: bit FrameworksServicesTests:com.android.server.wm.ConfigurationContainerTests
Test: go/wm-smoke
Change-Id: I6a6bc98a35bda89b3aaa7a29a9814905f0c3a9ee
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 651d3a6..0ccb45f 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -191,10 +191,8 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_AM;
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
     private static final String TAG_SAVED_STATE = TAG + POSTFIX_SAVED_STATE;
-    private static final String TAG_SCREENSHOTS = TAG + POSTFIX_SCREENSHOTS;
     private static final String TAG_STATES = TAG + POSTFIX_STATES;
     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
-    private static final String TAG_THUMBNAILS = TAG + POSTFIX_THUMBNAILS;
     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
 
     private static final boolean SHOW_ACTIVITY_START_TIME = true;
@@ -937,8 +935,7 @@
                 (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, info.configChanges,
                 task.voiceSession != null, mLaunchTaskBehind, isAlwaysFocusable(),
                 appInfo.targetSdkVersion, mRotationAnimationHint,
-                ActivityManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L,
-                new Configuration(getOverrideConfiguration()), mBounds);
+                ActivityManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L, mBounds);
 
         task.addActivityToTop(this);
 
@@ -1122,7 +1119,7 @@
      * @return whether this activity supports PiP multi-window and can be put in the pinned stack.
      */
     boolean supportsPictureInPicture() {
-        return service.mSupportsPictureInPicture && isActivityTypeStandard()
+        return service.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
                 && info.supportsPictureInPicture();
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index cc45e02..84bf18a0 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -466,15 +466,13 @@
         mTmpRect2.setEmpty();
         updateOverrideConfiguration();
         mWindowContainerController = createStackWindowController(display.mDisplayId, onTop,
-                mTmpRect2, getOverrideConfiguration());
+                mTmpRect2);
         mStackSupervisor.mStacks.put(mStackId, this);
         postAddToDisplay(display, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
     }
 
-    T createStackWindowController(int displayId, boolean onTop, Rect outBounds,
-            Configuration overrideConfig) {
-        return (T) new StackWindowController(mStackId, this, displayId, onTop, outBounds,
-                overrideConfig);
+    T createStackWindowController(int displayId, boolean onTop, Rect outBounds) {
+        return (T) new StackWindowController(mStackId, this, displayId, onTop, outBounds);
     }
 
     T getWindowContainerController() {
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index 86ee3f4..a601ee1 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -39,9 +39,8 @@
 
     @Override
     PinnedStackWindowController createStackWindowController(int displayId, boolean onTop,
-            Rect outBounds, Configuration overrideConfig) {
-        return new PinnedStackWindowController(mStackId, this, displayId, onTop, outBounds,
-                overrideConfig);
+            Rect outBounds) {
+        return new PinnedStackWindowController(mStackId, this, displayId, onTop, outBounds);
     }
 
     Rect getDefaultPictureInPictureBounds(float aspectRatio) {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index fc1c02f..62afcd2 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -430,9 +430,8 @@
         }
 
         final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
-        final Configuration overrideConfig = getOverrideConfiguration();
         setWindowContainerController(new TaskWindowContainerController(taskId, this,
-                getStack().getWindowContainerController(), userId, bounds, overrideConfig,
+                getStack().getWindowContainerController(), userId, bounds,
                 mResizeMode, mSupportsPictureInPicture, onTop,
                 showForAllUsers, lastTaskDescription));
     }
@@ -1175,9 +1174,6 @@
         }
         // Only set this based on the first activity
         if (mActivities.isEmpty()) {
-            // TODO: propagating this change to the WM side...Should probably be done by having
-            // ConfigurationContainer change listener that the WindowContainerController registers
-            // for.
             if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
                 // Normally non-standard activity type for the activity record will be set when the
                 // object is created, however we delay setting the standard application type until
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 66e0a15..769ceac78 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -181,12 +181,12 @@
             int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int configChanges,
             boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
             int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos,
-            Configuration overrideConfig, Rect bounds) {
+            Rect bounds) {
         this(taskController, token, listener, index, requestedOrientation, fullscreen,
                 showForAllUsers,
                 configChanges, voiceInteraction, launchTaskBehind, alwaysFocusable,
                 targetSdkVersion, rotationAnimationHint, inputDispatchingTimeoutNanos,
-                WindowManagerService.getInstance(), overrideConfig, bounds);
+                WindowManagerService.getInstance(), bounds);
     }
 
     public AppWindowContainerController(TaskWindowContainerController taskController,
@@ -194,7 +194,7 @@
             int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int configChanges,
             boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
             int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos,
-            WindowManagerService service, Configuration overrideConfig, Rect bounds) {
+            WindowManagerService service, Rect bounds) {
         super(listener, service);
         mHandler = new H(service.mH.getLooper());
         mToken = token;
@@ -215,7 +215,7 @@
             atoken = createAppWindow(mService, token, voiceInteraction, task.getDisplayContent(),
                     inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdkVersion,
                     requestedOrientation, rotationAnimationHint, configChanges, launchTaskBehind,
-                    alwaysFocusable, this, overrideConfig, bounds);
+                    alwaysFocusable, this, bounds);
             if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken
                     + " controller=" + taskController + " at " + index);
             task.addChild(atoken, index);
@@ -227,12 +227,11 @@
             boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
             boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
             int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
-            boolean alwaysFocusable, AppWindowContainerController controller,
-            Configuration overrideConfig, Rect bounds) {
+            boolean alwaysFocusable, AppWindowContainerController controller, Rect bounds) {
         return new AppWindowToken(service, token, voiceInteraction, dc,
                 inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
                 rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
-                controller, overrideConfig, bounds);
+                controller, bounds);
     }
 
     public void removeContainer(int displayId) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index f70035c..ea2f305 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -187,7 +187,7 @@
 
     private boolean mDisablePreviewScreenshots;
 
-    Task mLastParent;
+    private Task mLastParent;
 
     /**
      * See {@link #canTurnScreenOn()}
@@ -198,8 +198,8 @@
             DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
             boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
             int configChanges, boolean launchTaskBehind, boolean alwaysFocusable,
-            AppWindowContainerController controller, Configuration overrideConfig, Rect bounds) {
-        this(service, token, voiceInteraction, dc, fullscreen, overrideConfig, bounds);
+            AppWindowContainerController controller, Rect bounds) {
+        this(service, token, voiceInteraction, dc, fullscreen, bounds);
         setController(controller);
         mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
         mShowForAllUsers = showForAllUsers;
@@ -216,7 +216,7 @@
     }
 
     AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
-            DisplayContent dc, boolean fillsParent, Configuration overrideConfig, Rect bounds) {
+            DisplayContent dc, boolean fillsParent, Rect bounds) {
         super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
                 false /* ownerCanManageAppTokens */);
         appToken = token;
@@ -224,9 +224,6 @@
         mFillsParent = fillsParent;
         mInputApplicationHandle = new InputApplicationHandle(this);
         mAppAnimator = new AppWindowAnimator(this, service);
-        if (overrideConfig != null) {
-            onOverrideConfigurationChanged(overrideConfig);
-        }
         if (bounds != null) {
             mBounds.set(bounds);
         }
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 21b67f1..cbf4fc0 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -26,6 +26,8 @@
 import android.app.WindowConfiguration;
 import android.content.res.Configuration;
 
+import java.util.ArrayList;
+
 /**
  * Contains common logic for classes that have override configurations and are organized in a
  * hierarchy.
@@ -48,6 +50,8 @@
      */
     private Configuration mMergedOverrideConfiguration = new Configuration();
 
+    private ArrayList<ConfigurationContainerListener> mChangeListeners = new ArrayList<>();
+
     // TODO: Can't have ag/2592611 soon enough!
     private final Configuration mTmpConfig = new Configuration();
 
@@ -90,6 +94,11 @@
         onConfigurationChanged(parent != null ? parent.getConfiguration() : Configuration.EMPTY);
         // Update merged override config of this container and all its children.
         onMergedOverrideConfigurationChanged();
+
+        // Inform listeners of the change.
+        for (int i = mChangeListeners.size() - 1; i >=0; --i) {
+            mChangeListeners.get(i).onOverrideConfigurationChanged(overrideConfiguration);
+        }
     }
 
     /**
@@ -173,6 +182,11 @@
         return getActivityType() == ACTIVITY_TYPE_STANDARD;
     }
 
+    public boolean isActivityTypeStandardOrUndefined() {
+        /*@WindowConfiguration.ActivityType*/ final int activityType = getActivityType();
+        return activityType == ACTIVITY_TYPE_STANDARD || activityType == ACTIVITY_TYPE_UNDEFINED;
+    }
+
     public boolean hasCompatibleActivityType(ConfigurationContainer other) {
         /*@WindowConfiguration.ActivityType*/ int thisType = getActivityType();
         /*@WindowConfiguration.ActivityType*/ int otherType = other.getActivityType();
@@ -182,6 +196,18 @@
                 || otherType == ACTIVITY_TYPE_UNDEFINED;
     }
 
+    public void registerConfigurationChangeListener(ConfigurationContainerListener listener) {
+        if (mChangeListeners.contains(listener)) {
+            return;
+        }
+        mChangeListeners.add(listener);
+        listener.onOverrideConfigurationChanged(mOverrideConfiguration);
+    }
+
+    public void unregisterConfigurationChangeListener(ConfigurationContainerListener listener) {
+        mChangeListeners.remove(listener);
+    }
+
     /**
      * Must be called when new parent for the container was set.
      */
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainerListener.java b/services/core/java/com/android/server/wm/ConfigurationContainerListener.java
new file mode 100644
index 0000000..ff14d97
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ConfigurationContainerListener.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.content.res.Configuration;
+
+/**
+ * Interface for listening to changes in a {@link ConfigurationContainer}.
+ */
+public interface ConfigurationContainerListener {
+
+    void onOverrideConfigurationChanged(Configuration overrideConfiguration);
+}
diff --git a/services/core/java/com/android/server/wm/PinnedStackWindowController.java b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
index b5c9b99..590ac6e 100644
--- a/services/core/java/com/android/server/wm/PinnedStackWindowController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackWindowController.java
@@ -40,9 +40,8 @@
     private Rect mTmpToBounds = new Rect();
 
     public PinnedStackWindowController(int stackId, PinnedStackWindowListener listener,
-            int displayId, boolean onTop, Rect outBounds, Configuration overrideConfig) {
-        super(stackId, listener, displayId, onTop, outBounds, overrideConfig,
-                WindowManagerService.getInstance());
+            int displayId, boolean onTop, Rect outBounds) {
+        super(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance());
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index aaacef5..a50ed71 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -57,16 +57,14 @@
     private final Rect mTmpNonDecorInsets = new Rect();
     private final Rect mTmpDisplayBounds = new Rect();
 
-    public StackWindowController(int stackId, StackWindowListener listener,
-            int displayId, boolean onTop, Rect outBounds, Configuration overriderConfig) {
-        this(stackId, listener, displayId, onTop, outBounds, overriderConfig,
-                WindowManagerService.getInstance());
+    public StackWindowController(int stackId, StackWindowListener listener, int displayId,
+            boolean onTop, Rect outBounds) {
+        this(stackId, listener, displayId, onTop, outBounds, WindowManagerService.getInstance());
     }
 
     @VisibleForTesting
     public StackWindowController(int stackId, StackWindowListener listener,
-            int displayId, boolean onTop, Rect outBounds, Configuration overrideConfig,
-            WindowManagerService service) {
+            int displayId, boolean onTop, Rect outBounds, WindowManagerService service) {
         super(listener, service);
         mStackId = stackId;
         mHandler = new H(new WeakReference<>(this), service.mH.getLooper());
@@ -79,9 +77,6 @@
             }
 
             final TaskStack stack = dc.addStackToDisplay(stackId, onTop);
-            if (overrideConfig != null) {
-                stack.onOverrideConfigurationChanged(overrideConfig);
-            }
             stack.setController(this);
             getRawBounds(outBounds);
         }
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index f57238e..e9f8457 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -106,8 +106,8 @@
     private boolean mPreserveNonFloatingState = false;
 
     Task(int taskId, TaskStack stack, int userId, WindowManagerService service, Rect bounds,
-            Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            TaskDescription taskDescription, TaskWindowContainerController controller) {
+            int resizeMode, boolean supportsPictureInPicture, TaskDescription taskDescription,
+            TaskWindowContainerController controller) {
         mTaskId = taskId;
         mStack = stack;
         mUserId = userId;
@@ -115,7 +115,7 @@
         mResizeMode = resizeMode;
         mSupportsPictureInPicture = supportsPictureInPicture;
         setController(controller);
-        setBounds(bounds, overrideConfig);
+        setBounds(bounds, getOverrideConfiguration());
         mTaskDescription = taskDescription;
 
         // Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
@@ -273,6 +273,9 @@
     }
 
     /** Set the task bounds. Passing in null sets the bounds to fullscreen. */
+    // TODO: There is probably not a need to pass in overrideConfig anymore since any change to it
+    // will be automatically propagated from the AM. Also, mBound is going to be in
+    // WindowConfiguration long term.
     private int setBounds(Rect bounds, Configuration overrideConfig) {
         if (overrideConfig == null) {
             overrideConfig = Configuration.EMPTY;
diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
index d8929c9..65f8cdf 100644
--- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
@@ -49,19 +49,18 @@
     private final H mHandler;
 
     public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
-            StackWindowController stackController, int userId, Rect bounds,
-            Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            boolean toTop, boolean showForAllUsers, TaskDescription taskDescription) {
-        this(taskId, listener, stackController, userId, bounds, overrideConfig, resizeMode,
+            StackWindowController stackController, int userId, Rect bounds, int resizeMode,
+            boolean supportsPictureInPicture, boolean toTop, boolean showForAllUsers,
+            TaskDescription taskDescription) {
+        this(taskId, listener, stackController, userId, bounds, resizeMode,
                 supportsPictureInPicture, toTop, showForAllUsers, taskDescription,
                 WindowManagerService.getInstance());
     }
 
     public TaskWindowContainerController(int taskId, TaskWindowContainerListener listener,
-            StackWindowController stackController, int userId, Rect bounds,
-            Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            boolean toTop, boolean showForAllUsers, TaskDescription taskDescription,
-            WindowManagerService service) {
+            StackWindowController stackController, int userId, Rect bounds, int resizeMode,
+            boolean supportsPictureInPicture, boolean toTop, boolean showForAllUsers,
+            TaskDescription taskDescription, WindowManagerService service) {
         super(listener, service);
         mTaskId = taskId;
         mHandler = new H(new WeakReference<>(this), service.mH.getLooper());
@@ -76,7 +75,7 @@
                         + stackController);
             }
             EventLog.writeEvent(WM_TASK_CREATED, taskId, stack.mStackId);
-            final Task task = createTask(taskId, stack, userId, bounds, overrideConfig, resizeMode,
+            final Task task = createTask(taskId, stack, userId, bounds, resizeMode,
                     supportsPictureInPicture, taskDescription);
             final int position = toTop ? POSITION_TOP : POSITION_BOTTOM;
             // We only want to move the parents to the parents if we are creating this task at the
@@ -86,10 +85,9 @@
     }
 
     @VisibleForTesting
-    Task createTask(int taskId, TaskStack stack, int userId, Rect bounds,
-            Configuration overrideConfig, int resizeMode, boolean supportsPictureInPicture,
-            TaskDescription taskDescription) {
-        return new Task(taskId, stack, userId, mService, bounds, overrideConfig, resizeMode,
+    Task createTask(int taskId, TaskStack stack, int userId, Rect bounds, int resizeMode,
+            boolean supportsPictureInPicture, TaskDescription taskDescription) {
+        return new Task(taskId, stack, userId, mService, bounds, resizeMode,
                 supportsPictureInPicture, taskDescription, this);
     }
 
diff --git a/services/core/java/com/android/server/wm/WindowContainerController.java b/services/core/java/com/android/server/wm/WindowContainerController.java
index c4a6837..eb23faf 100644
--- a/services/core/java/com/android/server/wm/WindowContainerController.java
+++ b/services/core/java/com/android/server/wm/WindowContainerController.java
@@ -16,9 +16,7 @@
 
 package com.android.server.wm;
 
-import android.os.IBinder;
-
-import java.util.HashMap;
+import android.content.res.Configuration;
 
 /**
  * Class that allows the owner/creator of a {@link WindowContainer} to communicate directly with the
@@ -29,7 +27,8 @@
  *
  * Test class: {@link WindowContainerControllerTests}
  */
-class WindowContainerController<E extends WindowContainer, I extends WindowContainerListener> {
+class WindowContainerController<E extends WindowContainer, I extends WindowContainerListener>
+        implements ConfigurationContainerListener {
 
     final WindowManagerService mService;
     final RootWindowContainer mRoot;
@@ -53,18 +52,32 @@
                     + " for controller=" + this + " Already set to=" + mContainer);
         }
         mContainer = container;
+        if (mContainer != null && mListener != null) {
+            mListener.registerConfigurationChangeListener(this);
+        }
     }
 
     void removeContainer() {
         // TODO: See if most uses cases should support removeIfPossible here.
         //mContainer.removeIfPossible();
-        if (mContainer != null) {
-            mContainer.setController(null);
-            mContainer = null;
+        if (mContainer == null) {
+            return;
+        }
+
+        mContainer.setController(null);
+        mContainer = null;
+        if (mListener != null) {
+            mListener.unregisterConfigurationChangeListener(this);
         }
     }
 
-    boolean checkCallingPermission(String permission, String func) {
-        return mService.checkCallingPermission(permission, func);
+    @Override
+    public void onOverrideConfigurationChanged(Configuration overrideConfiguration) {
+        synchronized (mWindowMap) {
+            if (mContainer == null) {
+                return;
+            }
+            mContainer.onOverrideConfigurationChanged(overrideConfiguration);
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/WindowContainerListener.java b/services/core/java/com/android/server/wm/WindowContainerListener.java
index ab9d71a..4b3cd36 100644
--- a/services/core/java/com/android/server/wm/WindowContainerListener.java
+++ b/services/core/java/com/android/server/wm/WindowContainerListener.java
@@ -21,5 +21,6 @@
  * @see WindowContainerController
  */
 public interface WindowContainerListener {
-
+    void registerConfigurationChangeListener(ConfigurationContainerListener listener);
+    void unregisterConfigurationChangeListener(ConfigurationContainerListener listener);
 }