Merge "Don't crash if a system restore fails before constructing the PMBA" into lmp-mr1-dev
diff --git a/core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl b/core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl
index a16e878..c708d20 100644
--- a/core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl
@@ -22,7 +22,7 @@
  *
  * @hide
  */
-oneway interface IHdmiVendorCommandListener {
+interface IHdmiVendorCommandListener {
     void onReceived(int logicalAddress, int destAddress, in byte[] operands, boolean hasVendorId);
     void onControlStateChanged(boolean enabled, int reason);
 }
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 56a05fe..9feb681 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -59,6 +59,11 @@
     public String name;
 
     /**
+     * Unique identifier for the display. Shouldn't be displayed to the user.
+     */
+    public String uniqueId;
+
+    /**
      * The width of the portion of the display that is available to applications, in pixels.
      * Represents the size of the display minus any system decorations.
      */
@@ -257,7 +262,7 @@
                 && flags == other.flags
                 && type == other.type
                 && Objects.equal(address, other.address)
-                && Objects.equal(name, other.name)
+                && Objects.equal(uniqueId, other.uniqueId)
                 && appWidth == other.appWidth
                 && appHeight == other.appHeight
                 && smallestNominalAppWidth == other.smallestNominalAppWidth
@@ -293,6 +298,7 @@
         type = other.type;
         address = other.address;
         name = other.name;
+        uniqueId = other.uniqueId;
         appWidth = other.appWidth;
         appHeight = other.appHeight;
         smallestNominalAppWidth = other.smallestNominalAppWidth;
@@ -348,6 +354,7 @@
         state = source.readInt();
         ownerUid = source.readInt();
         ownerPackageName = source.readString();
+        uniqueId = source.readString();
     }
 
     @Override
@@ -380,6 +387,7 @@
         dest.writeInt(state);
         dest.writeInt(ownerUid);
         dest.writeString(ownerPackageName);
+        dest.writeString(uniqueId);
     }
 
     @Override
@@ -445,6 +453,8 @@
         StringBuilder sb = new StringBuilder();
         sb.append("DisplayInfo{\"");
         sb.append(name);
+        sb.append("\", uniqueId \"");
+        sb.append(uniqueId);
         sb.append("\", app ");
         sb.append(appWidth);
         sb.append(" x ");
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 1a5ff26..1551504 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5033,8 +5033,8 @@
             child.getMatrix().mapRect(rect);
         }
 
-        int dx = child.mLeft - mScrollX;
-        int dy = child.mTop - mScrollY;
+        final int dx = child.mLeft - mScrollX;
+        final int dy = child.mTop - mScrollY;
 
         rect.offset(dx, dy);
 
@@ -5052,21 +5052,23 @@
             offset.y += dy;
         }
 
+        final int width = mRight - mLeft;
+        final int height = mBottom - mTop;
+
         boolean rectIsVisible = true;
         if (mParent instanceof ViewGroup && ((ViewGroup)mParent).getClipChildren()) {
-            // clipChildren clips to the child's bounds
-            rectIsVisible = rect.intersect(0, 0, mRight - mLeft, mBottom - mTop);
+            // Clip to bounds.
+            rectIsVisible = rect.intersect(0, 0, width, height);
         }
 
         if (rectIsVisible && (mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) {
-            // Clip to padding
+            // Clip to padding.
             rectIsVisible = rect.intersect(mPaddingLeft, mPaddingTop,
-                    mRight - mLeft - mPaddingLeft - mPaddingRight,
-                    mBottom - mTop - mPaddingTop - mPaddingBottom);
+                    width - mPaddingRight, height - mPaddingBottom);
         }
 
         if (rectIsVisible && mClipBounds != null) {
-            // Clip to clipBounds
+            // Clip to clipBounds.
             rectIsVisible = rect.intersect(mClipBounds.left, mClipBounds.top, mClipBounds.right,
                     mClipBounds.bottom);
         }
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 39528be..aa32541 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -60,6 +60,7 @@
 
 void CanvasContext::destroy() {
     stopDrawing();
+    setSurface(NULL);
     freePrefetechedLayers();
     destroyHardwareResources();
     mAnimationContext->destroy();
@@ -67,7 +68,6 @@
         delete mCanvas;
         mCanvas = 0;
     }
-    setSurface(NULL);
 }
 
 void CanvasContext::setSurface(ANativeWindow* window) {
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 683212a..61631d4 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -34,6 +34,7 @@
 abstract class DisplayDevice {
     private final DisplayAdapter mDisplayAdapter;
     private final IBinder mDisplayToken;
+    private final String mUniqueId;
 
     // The display device does not manage these properties itself, they are set by
     // the display manager service.  The display device shouldn't really be looking at these.
@@ -46,9 +47,10 @@
     // within a transaction from performTraversalInTransactionLocked.
     private Surface mCurrentSurface;
 
-    public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken) {
+    public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken, String uniqueId) {
         mDisplayAdapter = displayAdapter;
         mDisplayToken = displayToken;
+        mUniqueId = uniqueId;
     }
 
     /**
@@ -80,6 +82,13 @@
     }
 
     /**
+     * Returns the unique id of the display device.
+     */
+    public final String getUniqueId() {
+        return mUniqueId;
+    }
+
+    /**
      * Gets information about the display device.
      *
      * The information returned should not change between calls unless the display
@@ -208,6 +217,7 @@
      */
     public void dumpLocked(PrintWriter pw) {
         pw.println("mAdapter=" + mDisplayAdapter.getName());
+        pw.println("mUniqueId=" + mUniqueId);
         pw.println("mDisplayToken=" + mDisplayToken);
         pw.println("mCurrentLayerStack=" + mCurrentLayerStack);
         pw.println("mCurrentOrientation=" + mCurrentOrientation);
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index f48428a..d1e73f0 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -104,12 +104,17 @@
     public static final int TOUCH_EXTERNAL = 2;
 
     /**
-     * Gets the name of the display device, which may be derived from
-     * EDID or other sources.  The name may be displayed to the user.
+     * Gets the name of the display device, which may be derived from EDID or
+     * other sources. The name may be localized and displayed to the user.
      */
     public String name;
 
     /**
+     * Unique Id of display device.
+     */
+    public String uniqueId;
+
+    /**
      * The width of the display in its natural orientation, in pixels.
      * This value is not affected by display rotation.
      */
@@ -235,6 +240,7 @@
     public boolean equals(DisplayDeviceInfo other) {
         return other != null
                 && Objects.equal(name, other.name)
+                && Objects.equal(uniqueId, other.uniqueId)
                 && width == other.width
                 && height == other.height
                 && refreshRate == other.refreshRate
@@ -261,6 +267,7 @@
 
     public void copyFrom(DisplayDeviceInfo other) {
         name = other.name;
+        uniqueId = other.uniqueId;
         width = other.width;
         height = other.height;
         refreshRate = other.refreshRate;
@@ -285,7 +292,8 @@
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("DisplayDeviceInfo{\"");
-        sb.append(name).append("\": ").append(width).append(" x ").append(height);
+        sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", ");
+        sb.append(width).append(" x ").append(height);
         sb.append(", ").append(refreshRate).append(" fps");
         sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates));
         sb.append(", density ").append(densityDpi);
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 24cf423..5ebe64d 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -41,6 +41,8 @@
 final class LocalDisplayAdapter extends DisplayAdapter {
     private static final String TAG = "LocalDisplayAdapter";
 
+    private static final String UNIQUE_ID_PREFIX = "local:";
+
     private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] {
             SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN,
             SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI,
@@ -140,7 +142,7 @@
 
         public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
                 SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
-            super(LocalDisplayAdapter.this, displayToken);
+            super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
             mBuiltInDisplayId = builtInDisplayId;
             mPhys = new SurfaceControl.PhysicalDisplayInfo(
                     physicalDisplayInfos[activeDisplayInfo]);
@@ -179,6 +181,7 @@
                 mInfo.appVsyncOffsetNanos = mPhys.appVsyncOffsetNanos;
                 mInfo.presentationDeadlineNanos = mPhys.presentationDeadlineNanos;
                 mInfo.state = mState;
+                mInfo.uniqueId = getUniqueId();
 
                 // Assume that all built-in displays that have secure output (eg. HDCP) also
                 // support compositing from gralloc protected buffers.
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 00ff1cf..6c57eec 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -118,6 +118,7 @@
                 mInfo.copyFrom(mOverrideDisplayInfo);
                 mInfo.layerStack = mBaseDisplayInfo.layerStack;
                 mInfo.name = mBaseDisplayInfo.name;
+                mInfo.uniqueId = mBaseDisplayInfo.uniqueId;
                 mInfo.state = mBaseDisplayInfo.state;
             } else {
                 mInfo.copyFrom(mBaseDisplayInfo);
@@ -208,6 +209,7 @@
             mBaseDisplayInfo.type = deviceInfo.type;
             mBaseDisplayInfo.address = deviceInfo.address;
             mBaseDisplayInfo.name = deviceInfo.name;
+            mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId;
             mBaseDisplayInfo.appWidth = deviceInfo.width;
             mBaseDisplayInfo.appHeight = deviceInfo.height;
             mBaseDisplayInfo.logicalWidth = deviceInfo.width;
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index f514531..5b6f35b 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -61,6 +61,9 @@
     private static final Pattern SETTING_PATTERN =
             Pattern.compile("(\\d+)x(\\d+)/(\\d+)(,[a-z]+)*");
 
+    // Unique id prefix for overlay displays.
+    private static final String UNIQUE_ID_PREFIX = "overlay:";
+
     private final Handler mUiHandler;
     private final ArrayList<OverlayDisplayHandle> mOverlays =
             new ArrayList<OverlayDisplayHandle>();
@@ -160,7 +163,7 @@
                                 + ", densityDpi=" + densityDpi + ", secure=" + secure);
 
                         mOverlays.add(new OverlayDisplayHandle(name,
-                                width, height, densityDpi, gravity, secure));
+                                width, height, densityDpi, gravity, secure, number));
                         continue;
                     }
                 } catch (NumberFormatException ex) {
@@ -203,8 +206,8 @@
         public OverlayDisplayDevice(IBinder displayToken, String name,
                 int width, int height, float refreshRate, long presentationDeadlineNanos,
                 int densityDpi, boolean secure, int state,
-                SurfaceTexture surfaceTexture) {
-            super(OverlayDisplayAdapter.this, displayToken);
+                SurfaceTexture surfaceTexture, int number) {
+            super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number);
             mName = name;
             mWidth = width;
             mHeight = height;
@@ -245,6 +248,7 @@
             if (mInfo == null) {
                 mInfo = new DisplayDeviceInfo();
                 mInfo.name = mName;
+                mInfo.uniqueId = getUniqueId();
                 mInfo.width = mWidth;
                 mInfo.height = mHeight;
                 mInfo.refreshRate = mRefreshRate;
@@ -279,18 +283,20 @@
         private final int mDensityDpi;
         private final int mGravity;
         private final boolean mSecure;
+        private final int mNumber;
 
         private OverlayDisplayWindow mWindow;
         private OverlayDisplayDevice mDevice;
 
-        public OverlayDisplayHandle(String name,
-                int width, int height, int densityDpi, int gravity, boolean secure) {
+        public OverlayDisplayHandle(String name, int width,
+                int height, int densityDpi, int gravity, boolean secure, int number) {
             mName = name;
             mWidth = width;
             mHeight = height;
             mDensityDpi = densityDpi;
             mGravity = gravity;
             mSecure = secure;
+            mNumber = number;
 
             mUiHandler.post(mShowRunnable);
         }
@@ -308,7 +314,7 @@
                 IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure);
                 mDevice = new OverlayDisplayDevice(displayToken, mName,
                         mWidth, mHeight, refreshRate, presentationDeadlineNanos,
-                        mDensityDpi, mSecure, state, surfaceTexture);
+                        mDensityDpi, mSecure, state, surfaceTexture, mNumber);
 
                 sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
             }
@@ -343,6 +349,7 @@
             pw.println("    mDensityDpi=" + mDensityDpi);
             pw.println("    mGravity=" + mGravity);
             pw.println("    mSecure=" + mSecure);
+            pw.println("    mNumber=" + mNumber);
 
             // Try to dump the window state.
             if (mWindow != null) {
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 28d5fc0..f181cd5 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -34,6 +34,7 @@
 import android.view.SurfaceControl;
 
 import java.io.PrintWriter;
+import java.util.Iterator;
 
 /**
  * A display adapter that provides virtual displays on behalf of applications.
@@ -45,6 +46,9 @@
     static final String TAG = "VirtualDisplayAdapter";
     static final boolean DEBUG = false;
 
+    // Unique id prefix for virtual displays
+    private static final String UNIQUE_ID_PREFIX = "virtual:";
+
     private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices =
             new ArrayMap<IBinder, VirtualDisplayDevice>();
     private Handler mHandler;
@@ -62,9 +66,12 @@
         boolean secure = (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0;
         IBinder appToken = callback.asBinder();
         IBinder displayToken = SurfaceControl.createDisplay(name, secure);
+        final String baseUniqueId =
+                UNIQUE_ID_PREFIX + ownerPackageName + "," + ownerUid + "," + name + ",";
+        final int uniqueIndex = getNextUniqueIndex(baseUniqueId);
         VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken,
                 ownerUid, ownerPackageName, name, width, height, densityDpi, surface, flags,
-                new Callback(callback, mHandler));
+                new Callback(callback, mHandler), baseUniqueId + uniqueIndex, uniqueIndex);
 
         mVirtualDisplayDevices.put(appToken, device);
 
@@ -112,6 +119,29 @@
         return device;
     }
 
+    /**
+     * Returns the next unique index for the uniqueIdPrefix
+     */
+    private int getNextUniqueIndex(String uniqueIdPrefix) {
+        if (mVirtualDisplayDevices.isEmpty()) {
+            return 0;
+        }
+
+        int nextUniqueIndex = 0;
+        Iterator<VirtualDisplayDevice> it = mVirtualDisplayDevices.values().iterator();
+        while (it.hasNext()) {
+            VirtualDisplayDevice device = it.next();
+            if (device.getUniqueId().startsWith(uniqueIdPrefix)
+                    && device.mUniqueIndex >= nextUniqueIndex) {
+                // Increment the next unique index to be greater than ones we have already ran
+                // across for displays that have the same unique Id prefix.
+                nextUniqueIndex = device.mUniqueIndex + 1;
+            }
+        }
+
+        return nextUniqueIndex;
+    }
+
     private void handleBinderDiedLocked(IBinder appToken) {
         VirtualDisplayDevice device = mVirtualDisplayDevices.remove(appToken);
         if (device != null) {
@@ -150,12 +180,13 @@
         private int mDisplayState;
         private boolean mStopped;
         private int mPendingChanges;
+        private int mUniqueIndex;
 
         public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
                 int ownerUid, String ownerPackageName,
                 String name, int width, int height, int densityDpi, Surface surface, int flags,
-                Callback callback) {
-            super(VirtualDisplayAdapter.this, displayToken);
+                Callback callback, String uniqueId, int uniqueIndex) {
+            super(VirtualDisplayAdapter.this, displayToken, uniqueId);
             mAppToken = appToken;
             mOwnerUid = ownerUid;
             mOwnerPackageName = ownerPackageName;
@@ -168,6 +199,7 @@
             mCallback = callback;
             mDisplayState = Display.STATE_UNKNOWN;
             mPendingChanges |= PENDING_SURFACE_CHANGE;
+            mUniqueIndex = uniqueIndex;
         }
 
         @Override
@@ -255,6 +287,7 @@
             if (mInfo == null) {
                 mInfo = new DisplayDeviceInfo();
                 mInfo.name = mName;
+                mInfo.uniqueId = getUniqueId();
                 mInfo.width = mWidth;
                 mInfo.height = mHeight;
                 mInfo.refreshRate = 60;
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index 6b010d9..c939861 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -68,6 +68,9 @@
 
     private static final String ACTION_DISCONNECT = "android.server.display.wfd.DISCONNECT";
 
+    // Unique id prefix for wifi displays
+    private static final String DISPLAY_NAME_PREFIX = "wifi:";
+
     private final WifiDisplayHandler mHandler;
     private final PersistentDataStore mPersistentDataStore;
     private final boolean mSupportsProtectedBuffers;
@@ -587,7 +590,7 @@
         public WifiDisplayDevice(IBinder displayToken, String name,
                 int width, int height, float refreshRate, int flags, String address,
                 Surface surface) {
-            super(WifiDisplayAdapter.this, displayToken);
+            super(WifiDisplayAdapter.this, displayToken, DISPLAY_NAME_PREFIX + address);
             mName = name;
             mWidth = width;
             mHeight = height;
@@ -622,6 +625,7 @@
             if (mInfo == null) {
                 mInfo = new DisplayDeviceInfo();
                 mInfo.name = mName;
+                mInfo.uniqueId = getUniqueId();
                 mInfo.width = mWidth;
                 mInfo.height = mHeight;
                 mInfo.refreshRate = mRefreshRate;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 0e8788a..1486fee 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -129,7 +129,7 @@
     }
 
     private void init(long nativePtr) {
-        mIoHandler = new Handler(mService.getServiceLooper());
+        mIoHandler = new Handler(mService.getIoLooper());
         mControlHandler = new Handler(mService.getServiceLooper());
         mNativePtr = nativePtr;
     }
@@ -324,6 +324,7 @@
     @ServiceThreadOnly
     void setOption(int flag, int value) {
         assertRunOnServiceThread();
+        HdmiLogger.debug("setOption: [flag:%d, value:%d]", flag, value);
         nativeSetOption(mNativePtr, flag, value);
     }
 
@@ -501,6 +502,19 @@
         mControlHandler.post(runnable);
     }
 
+    @ServiceThreadOnly
+    void flush(final Runnable runnable) {
+        assertRunOnServiceThread();
+        runOnIoThread(new Runnable() {
+            @Override
+            public void run() {
+                // This ensures the runnable for cleanup is performed after all the pending
+                // commands are processed by IO thread.
+                runOnServiceThread(runnable);
+            }
+        });
+    }
+
     private boolean isAcceptableAddress(int address) {
         // Can access command targeting devices available in local device or broadcast command.
         if (address == Constants.ADDR_BROADCAST) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 8a25f62..5f8b389 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -2021,30 +2021,52 @@
     void setControlEnabled(boolean enabled) {
         assertRunOnServiceThread();
 
-        if (!enabled) {
-            // Call the vendor handler before the service is disabled.
-            invokeVendorCommandListenersOnControlStateChanged(false,
-                    HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING);
-        }
-        int value = toInt(enabled);
-        mCecController.setOption(OPTION_CEC_ENABLE, value);
-        mMhlController.setOption(OPTION_MHL_ENABLE, value);
-
         synchronized (mLock) {
             mHdmiControlEnabled = enabled;
         }
 
         if (enabled) {
-            initializeCec(INITIATED_BY_ENABLE_CEC);
-        } else {
-            disableDevices(new PendingActionClearedCallback() {
-                @Override
-                public void onCleared(HdmiCecLocalDevice device) {
-                    assertRunOnServiceThread();
-                    clearLocalDevices();
-                }
-            });
+            enableHdmiControlService();
+            return;
         }
+        // Call the vendor handler before the service is disabled.
+        invokeVendorCommandListenersOnControlStateChanged(false,
+                HdmiControlManager.CONTROL_STATE_CHANGED_REASON_SETTING);
+        // Post the remained tasks in the service thread again to give the vendor-issued-tasks
+        // a chance to run.
+        runOnServiceThread(new Runnable() {
+            @Override
+            public void run() {
+                disableHdmiControlService();
+            }
+        });
+        return;
+    }
+
+    @ServiceThreadOnly
+    private void enableHdmiControlService() {
+        mCecController.setOption(OPTION_CEC_ENABLE, ENABLED);
+        mMhlController.setOption(OPTION_MHL_ENABLE, ENABLED);
+
+        initializeCec(INITIATED_BY_ENABLE_CEC);
+    }
+
+    @ServiceThreadOnly
+    private void disableHdmiControlService() {
+        disableDevices(new PendingActionClearedCallback() {
+            @Override
+            public void onCleared(HdmiCecLocalDevice device) {
+                assertRunOnServiceThread();
+                mCecController.flush(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCecController.setOption(OPTION_CEC_ENABLE, DISABLED);
+                        mMhlController.setOption(OPTION_MHL_ENABLE, DISABLED);
+                        clearLocalDevices();
+                    }
+                });
+            }
+        });
     }
 
     @ServiceThreadOnly
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java
index 34d1a64..ba995f2 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplaySettings.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import android.content.Context;
 import android.graphics.Rect;
 import android.os.Environment;
 import android.util.AtomicFile;
@@ -41,7 +40,6 @@
 public class DisplaySettings {
     private static final String TAG = WindowManagerService.TAG;
 
-    private final Context mContext;
     private final AtomicFile mFile;
     private final HashMap<String, Entry> mEntries = new HashMap<String, Entry>();
 
@@ -57,15 +55,19 @@
         }
     }
 
-    public DisplaySettings(Context context) {
-        mContext = context;
+    public DisplaySettings() {
         File dataDir = Environment.getDataDirectory();
         File systemDir = new File(dataDir, "system");
         mFile = new AtomicFile(new File(systemDir, "display_settings.xml"));
     }
 
-    public void getOverscanLocked(String name, Rect outRect) {
-        Entry entry = mEntries.get(name);
+    public void getOverscanLocked(String name, String uniqueId, Rect outRect) {
+        // Try to get the entry with the unique if possible.
+        // Else, fall back on the display name.
+        Entry entry;
+        if (uniqueId == null || (entry = mEntries.get(uniqueId)) == null) {
+            entry = mEntries.get(name);
+        }
         if (entry != null) {
             outRect.left = entry.overscanLeft;
             outRect.top = entry.overscanTop;
@@ -110,7 +112,7 @@
             int type;
             while ((type = parser.next()) != XmlPullParser.START_TAG
                     && type != XmlPullParser.END_DOCUMENT) {
-                ;
+                // Do nothing.
             }
 
             if (type != XmlPullParser.START_TAG) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index bcfd7f0..6a55ffc 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -825,7 +825,7 @@
                 com.android.internal.R.bool.config_hasPermanentDpad);
         mInputManager = inputManager; // Must be before createDisplayContentLocked.
         mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
-        mDisplaySettings = new DisplaySettings(context);
+        mDisplaySettings = new DisplaySettings();
         mDisplaySettings.readSettingsLocked();
 
         LocalServices.addService(WindowManagerPolicy.class, mPolicy);
@@ -8476,7 +8476,7 @@
             displayInfo.overscanBottom = bottom;
         }
 
-        mDisplaySettings.setOverscanLocked(displayInfo.name, left, top, right, bottom);
+        mDisplaySettings.setOverscanLocked(displayInfo.uniqueId, left, top, right, bottom);
         mDisplaySettings.writeSettingsLocked();
 
         reconfigureDisplayLocked(displayContent);
@@ -9539,6 +9539,9 @@
                                     + " interesting=" + numInteresting
                                     + " drawn=" + wtoken.numDrawnWindows);
                             wtoken.allDrawn = true;
+                            // Force an additional layout pass where WindowStateAnimator#
+                            // commitFinishDrawingLocked() will call performShowLocked().
+                            displayContent.layoutNeeded = true;
                             mH.obtainMessage(H.NOTIFY_ACTIVITY_DRAWN, wtoken.token).sendToTarget();
                         }
                     }
@@ -11458,7 +11461,7 @@
 
         DisplayInfo displayInfo = displayContent.getDisplayInfo();
         final Rect rect = new Rect();
-        mDisplaySettings.getOverscanLocked(displayInfo.name, rect);
+        mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
         synchronized (displayContent.mDisplaySizeLock) {
             displayInfo.overscanLeft = rect.left;
             displayInfo.overscanTop = rect.top;
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 125ada0..9ee4e1b 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -1009,7 +1009,7 @@
     }
 
     /** @hide */
-    @Deprecated public final void setCapabilities(int connectionCapabilities) {
+    @SystemApi @Deprecated public final void setCallCapabilities(int connectionCapabilities) {
         setConnectionCapabilities(connectionCapabilities);
     }