Merge "vrwm: Fix flickering when entering/leaving VR"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index ab323bb..1cf00f5 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1128,7 +1128,7 @@
     printf("== Running Application Activities\n");
     printf("========================================================\n");
 
-    RunDumpsys("APP ACTIVITIES", {"activity", "all"});
+    RunDumpsys("APP ACTIVITIES", {"activity", "-v", "all"});
 
     printf("========================================================\n");
     printf("== Running Application Services\n");
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 4a00818..a5e5c05 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -56,6 +56,7 @@
 extern "C" {
 #endif
 
+typedef struct AHardwareBuffer AHardwareBuffer;
 
 /**
  * Sensor types.
@@ -144,6 +145,30 @@
     AREPORTING_MODE_SPECIAL_TRIGGER = 3
 };
 
+/**
+ * Sensor Direct Report Rates.
+ */
+enum {
+    /** stopped */
+    ASENSOR_DIRECT_RATE_STOP = 0,
+    /** nominal 50Hz */
+    ASENSOR_DIRECT_RATE_NORMAL = 1,
+    /** nominal 200Hz */
+    ASENSOR_DIRECT_RATE_FAST = 2,
+    /** nominal 800Hz */
+    ASENSOR_DIRECT_RATE_VERY_FAST = 3
+};
+
+/**
+ * Sensor Direct Channel Type.
+ */
+enum {
+    /** shared memory created by ASharedMemory_create */
+    ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY = 1,
+    /** AHardwareBuffer */
+    ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER = 2
+};
+
 /*
  * A few useful constants
  */
@@ -391,6 +416,97 @@
  */
 int ASensorManager_destroyEventQueue(ASensorManager* manager, ASensorEventQueue* queue);
 
+#if __ANDROID_API__ >= __ANDROID_API_O__
+/**
+ * Create direct channel based on shared memory
+ *
+ * Create a direct channel of {@link ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY} to be used
+ * for configuring sensor direct report.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ *                {@link ASensorManager_getInstanceForPackage}.
+ * \param fd      file descriptor representing a shared memory created by
+ *                {@link ASharedMemory_create}
+ * \param size    size to be used, must be less or equal to size of shared memory.
+ *
+ * \return a positive integer as a channel id to be used in
+ *         {@link ASensorManager_destroyDirectChannel} and
+ *         {@link ASensorManager_configureDirectReport}, or value less or equal to 0 for failures.
+ */
+int ASensorManager_createSharedMemoryDirectChannel(ASensorManager* manager, int fd, size_t size);
+
+/**
+ * Create direct channel based on AHardwareBuffer
+ *
+ * Create a direct channel of {@link ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER} type to be used
+ * for configuring sensor direct report.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ *                {@link ASensorManager_getInstanceForPackage}.
+ * \param buffer  {@link AHardwareBuffer} instance created by {@link AHardwareBuffer_allocate}.
+ * \param size    the intended size to be used, must be less or equal to size of buffer.
+ *
+ * \return a positive integer as a channel id to be used in
+ *         {@link ASensorManager_destroyDirectChannel} and
+ *         {@link ASensorManager_configureDirectReport}, or value less or equal to 0 for failures.
+ */
+int ASensorManager_createHardwareBufferDirectChannel(
+        ASensorManager* manager, AHardwareBuffer const * buffer, size_t size);
+
+/**
+ * Destroy a direct channel
+ *
+ * Destroy a direct channel previously created using {@link ASensorManager_createDirectChannel}.
+ * The buffer used for creating direct channel does not get destroyed with
+ * {@link ASensorManager_destroy} and has to be close or released separately.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ *                {@link ASensorManager_getInstanceForPackage}.
+ * \param channelId channel id (a positive integer) returned from
+ *                  {@link ASensorManager_createSharedMemoryDirectChannel} or
+ *                  {@link ASensorManager_createHardwareBufferDirectChannel}.
+ */
+void ASensorManager_destroyDirectChannel(ASensorManager* manager, int channelId);
+
+/**
+ * Configure direct report on channel
+ *
+ * Configure sensor direct report on a direct channel: set rate to value other than
+ * {@link ASENSOR_DIRECT_RATE_STOP} so that sensor event can be directly
+ * written into the shared memory region used for creating the buffer; set rate to
+ * {@link ASENSOR_DIRECT_RATE_STOP} will stop the sensor direct report.
+ *
+ * To stop all active sensor direct report configured to a channel, set sensor to NULL and rate to
+ * {@link ASENSOR_DIRECT_RATE_STOP}.
+ *
+ * In order to successfully configure a direct report, the sensor has to support the specified rate
+ * and the channel type, which can be checked by {@link ASensor_getHighestDirectReportRateLevel} and
+ * {@link ASensor_isDirectChannelTypeSupported}, respectively.
+ *
+ * Example:
+ * \code{.cpp}
+ *      ASensorManager *manager = ...;
+ *      ASensor *sensor = ...;
+ *      int channelId = ...;
+ *
+ *      ASensorManager_configureDirectReport(
+ *              manager, sensor, channel_id, ASENSOR_DIRECT_RATE_FAST);
+ * \endcode
+ *
+ * \param manager   the {@link ASensorManager} instance obtained from
+ *                  {@link ASensorManager_getInstanceForPackage}.
+ * \param sensor    a {@link ASensor} to denote which sensor to be operate. It can be NULL if rate
+ *                  is {@link ASENSOR_DIRECT_RATE_STOP}, denoting stopping of all active sensor
+ *                  direct report.
+ * \param channelId channel id (a positive integer) returned from
+ *                  {@link ASensorManager_createSharedMemoryDirectChannel} or
+ *                  {@link ASensorManager_createHardwareBufferDirectChannel}.
+ *
+ * \return 0 for success or negative integer for failure.
+ */
+int ASensorManager_configureDirectReport(
+        ASensorManager* manager, ASensor const* sensor, int channelId, int rate);
+#endif
 
 /*****************************************************************************/
 
@@ -502,6 +618,29 @@
 bool ASensor_isWakeUpSensor(ASensor const* sensor);
 #endif /* __ANDROID_API__ >= 21 */
 
+#if __ANDROID_API__ >= __ANDROID_API_O__
+/**
+ * Test if sensor supports a certain type of direct channel.
+ *
+ * \param sensor  a {@link ASensor} to denote the sensor to be checked.
+ * \param channelType  Channel type constant, either
+ *                     {@ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY}
+ *                     or {@link ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER}.
+ * \returns true if sensor supports the specified direct channel type.
+ */
+bool ASensor_isDirectChannelTypeSupported(ASensor const* sensor, int channelType);
+/**
+ * Get the highest direct rate level that a sensor support.
+ *
+ * \param sensor  a {@link ASensor} to denote the sensor to be checked.
+ *
+ * \return a ASENSOR_DIRECT_RATE_... enum denoting the highest rate level supported by the sensor.
+ *         If return value is {@link ASENSOR_DIRECT_RATE_STOP}, it means the sensor
+ *         does not support direct report.
+ */
+int ASensor_getHighestDirectReportRateLevel(ASensor const* sensor);
+#endif
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/include/binder/HalToken.h b/include/binder/HalToken.h
new file mode 100644
index 0000000..7ef4f96
--- /dev/null
+++ b/include/binder/HalToken.h
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HALTOKEN_H
+#define ANDROID_HALTOKEN_H
+
+#include <binder/Parcel.h>
+#include <hidl/HidlSupport.h>
+
+/**
+ * It is possible to pass a hidl interface via as a binder interface by
+ * providing an appropriate "wrapper" class.
+ *
+ * Terminology:
+ * - `HalToken`: The type for a "token" of a hidl interface. This is defined to
+ *   be compatible with `ITokenManager.hal`.
+ * - `HInterface`: The base type for a hidl interface. Currently, it is defined
+ *   as `::android::hidl::base::V1_0::IBase`.
+ * - `HALINTERFACE`: The hidl interface that will be sent through binders.
+ * - `INTERFACE`: The binder interface that will be the wrapper of
+ *   `HALINTERFACE`. `INTERFACE` is supposed to be similar to `HALINTERFACE`.
+ *
+ * To demonstrate how this is done, here is an example. Suppose `INTERFACE` is
+ * `IFoo` and `HALINTERFACE` is `HFoo`. The required steps are:
+ * 1. Use DECLARE_HYBRID_META_INTERFACE instead of DECLARE_META_INTERFACE in the
+ *    definition of `IFoo`. The usage is
+ *        DECLARE_HYBRID_META_INTERFACE(IFoo, HFoo)
+ *    inside the body of `IFoo`.
+ * 2. Create a converter class that derives from
+ *    `H2BConverter<HFoo, IFoo, BnFoo>`. Let us call this `H2BFoo`.
+ * 3. Add the following constructors in `H2BFoo` that call the corresponding
+ *    constructors in `H2BConverter`:
+ *        H2BFoo(const sp<HalInterface>& base) : CBase(base) {}
+ *    Note: `CBase = H2BConverter<HFoo, IFoo, BnFoo>` and `HalInterface = HFoo`
+ *    are member typedefs of `CBase`, so the above line can be copied verbatim
+ *    into `H2BFoo`.
+ * 4. Add conversion functions inside `H2BFoo`. `H2BConverter` provides a
+ *    protected `mBase` of type `sp<HFoo>` that can be used to access the HFoo
+ *    instance. (There is also a public function named `getHalInterface()` that
+ *    returns `mBase`.)
+ * 5. Create a hardware proxy class that derives from
+ *    `HpInterface<BpFoo, H2BFoo>`. Name this class `HpFoo`. (This name cannot
+ *    deviate. See step 8 below.)
+ * 6. Add the following constructor to `HpFoo`:
+ *        HpFoo(const sp<IBinder>& base): PBase(base) {}
+ *    Note: `PBase` a member typedef of `HpInterface<BpFoo, H2BFoo>` that is
+ *    equal to `HpInterface<BpFoo, H2BFoo>` itself, so the above line can be
+ *    copied verbatim into `HpFoo`.
+ * 7. Delegate all functions in `HpFoo` that come from `IFoo` except
+ *    `getHalToken` and `getHalInterface` to the protected member `mBase`,
+ *    which is defined in `HpInterface<BpFoo, H2BFoo>` (hence in `HpFoo`) with
+ *    type `IFoo`. (There is also a public function named `getBaseInterface()`
+ *    that returns `mBase`.)
+ * 8. Replace the existing `IMPLEMENT_META_INTERFACE` for INTERFACE by
+ *    `IMPLEMENT_HYBRID_META_INTERFACE`. Note that this macro relies on the
+ *    exact naming of `HpFoo`, where `Foo` comes from the interface name `IFoo`.
+ *    An example usage is
+ *        IMPLEMENT_HYBRID_META_INTERFACE(IFoo, HFoo, "example.interface.foo");
+ *
+ * `GETTOKEN` Template Argument
+ * ============================
+ *
+ * Following the instructions above, `H2BConverter` and `HpInterface` would use
+ * `transact()` to send over tokens, with `code` (the first argument of
+ * `transact()`) equal to a 4-byte value of '_GTK'. If this value clashes with
+ * other values already in use in the `Bp` class, it can be changed by supplying
+ * the last optional template argument to `H2BConverter` and `HpInterface`.
+ *
+ */
+
+namespace android {
+
+typedef uint64_t HalToken;
+typedef ::android::hidl::base::V1_0::IBase HInterface;
+
+sp<HInterface> retrieveHalInterface(const HalToken& token);
+bool createHalToken(const sp<HInterface>& interface, HalToken* token);
+bool deleteHalToken(const HalToken& token);
+
+template <
+        typename HINTERFACE,
+        typename INTERFACE,
+        typename BNINTERFACE,
+        uint32_t GETTOKEN = '_GTK'>
+class H2BConverter : public BNINTERFACE {
+public:
+    typedef H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN> CBase;
+    typedef INTERFACE BaseInterface;
+    typedef HINTERFACE HalInterface;
+    static constexpr uint32_t GET_HAL_TOKEN = GETTOKEN;
+
+    H2BConverter(const sp<HalInterface>& base) : mBase(base) {}
+    virtual status_t onTransact(uint32_t code,
+            const Parcel& data, Parcel* reply, uint32_t flags = 0);
+    sp<HalInterface> getHalInterface() override { return mBase; }
+    HalInterface* getBaseInterface() { return mBase.get(); }
+
+protected:
+    sp<HalInterface> mBase;
+};
+
+template <typename BPINTERFACE, typename CONVERTER, uint32_t GETTOKEN = '_GTK'>
+class HpInterface : public BPINTERFACE {
+public:
+    typedef HpInterface<BPINTERFACE, CONVERTER, GETTOKEN> PBase; // Proxy Base
+    typedef typename CONVERTER::BaseInterface BaseInterface;
+    typedef typename CONVERTER::HalInterface HalInterface;
+    static constexpr uint32_t GET_HAL_TOKEN = GETTOKEN;
+
+    explicit HpInterface(const sp<IBinder>& impl);
+    sp<HalInterface> getHalInterface() override { return mHal; }
+    BaseInterface* getBaseInterface() { return mBase.get(); }
+
+protected:
+    sp<BaseInterface> mBase;
+    sp<HalInterface> mHal;
+};
+
+// ----------------------------------------------------------------------
+
+#define DECLARE_HYBRID_META_INTERFACE(INTERFACE, HAL)                   \
+    static const ::android::String16 descriptor;                        \
+    static ::android::sp<I##INTERFACE> asInterface(                     \
+            const ::android::sp<::android::IBinder>& obj);              \
+    virtual const ::android::String16& getInterfaceDescriptor() const;  \
+    I##INTERFACE();                                                     \
+    virtual ~I##INTERFACE();                                            \
+    virtual sp<HAL> getHalInterface();                                  \
+
+
+#define IMPLEMENT_HYBRID_META_INTERFACE(INTERFACE, HAL, NAME)           \
+    const ::android::String16 I##INTERFACE::descriptor(NAME);           \
+    const ::android::String16&                                          \
+            I##INTERFACE::getInterfaceDescriptor() const {              \
+        return I##INTERFACE::descriptor;                                \
+    }                                                                   \
+    ::android::sp<I##INTERFACE> I##INTERFACE::asInterface(              \
+            const ::android::sp<::android::IBinder>& obj)               \
+    {                                                                   \
+        ::android::sp<I##INTERFACE> intr;                               \
+        if (obj != NULL) {                                              \
+            intr = static_cast<I##INTERFACE*>(                          \
+                obj->queryLocalInterface(                               \
+                        I##INTERFACE::descriptor).get());               \
+            if (intr == NULL) {                                         \
+                intr = new Hp##INTERFACE(obj);                          \
+            }                                                           \
+        }                                                               \
+        return intr;                                                    \
+    }                                                                   \
+    I##INTERFACE::I##INTERFACE() { }                                    \
+    I##INTERFACE::~I##INTERFACE() { }                                   \
+    sp<HAL> I##INTERFACE::getHalInterface() { return nullptr; }         \
+
+// ----------------------------------------------------------------------
+
+template <
+        typename HINTERFACE,
+        typename INTERFACE,
+        typename BNINTERFACE,
+        uint32_t GETTOKEN>
+status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN>::
+        onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+    if (code == GET_HAL_TOKEN) {
+        HalToken token;
+        bool result;
+        result = createHalToken(mBase, &token);
+        if (!result) {
+            ALOGE("H2BConverter: Failed to create HAL token.");
+        }
+        reply->writeBool(result);
+        reply->writeUint64(token);
+        return NO_ERROR;
+    }
+    return BNINTERFACE::onTransact(code, data, reply, flags);
+}
+
+template <typename BPINTERFACE, typename CONVERTER, uint32_t GETTOKEN>
+HpInterface<BPINTERFACE, CONVERTER, GETTOKEN>::HpInterface(
+        const sp<IBinder>& impl):
+    BPINTERFACE(impl),
+    mBase(nullptr) {
+
+    Parcel data, reply;
+    data.writeInterfaceToken(BaseInterface::getInterfaceDescriptor());
+    if (this->remote()->transact(GET_HAL_TOKEN, data, &reply) == NO_ERROR) {
+        bool tokenCreated = reply.readBool();
+        HalToken token = reply.readUint64();
+        if (!tokenCreated) {
+            ALOGE("HpInterface: Sender failed to create HAL token.");
+            mBase = this;
+        } else {
+            sp<HInterface> hInterface = retrieveHalInterface(token);
+            deleteHalToken(token);
+            if (hInterface != nullptr) {
+                mHal = static_cast<HalInterface*>(hInterface.get());
+                mBase = new CONVERTER(mHal);
+            } else {
+                ALOGE("HpInterface: Cannot retrieve HAL interface from token.");
+                mBase = this;
+            }
+        }
+    } else {
+        mBase = this;
+    }
+}
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_HALTOKEN_H
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 46a3a5f..1e8cf76 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -155,8 +155,11 @@
     status_t    setLayerStack(const sp<IBinder>& id, uint32_t layerStack);
     status_t    deferTransactionUntil(const sp<IBinder>& id,
             const sp<IBinder>& handle, uint64_t frameNumber);
+    status_t    deferTransactionUntil(const sp<IBinder>& id,
+            const sp<Surface>& handle, uint64_t frameNumber);
     status_t    reparentChildren(const sp<IBinder>& id,
             const sp<IBinder>& newParentHandle);
+    status_t    detachChildren(const sp<IBinder>& id);
     status_t    setOverrideScalingMode(const sp<IBinder>& id,
             int32_t overrideScalingMode);
     status_t    setGeometryAppliesWithResize(const sp<IBinder>& id);
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index 99208b2..8ee35bc 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -80,11 +80,31 @@
     status_t    setGeometryAppliesWithResize();
 
     // Defers applying any changes made in this transaction until the Layer
-    // identified by handle reaches the given frameNumber
+    // identified by handle reaches the given frameNumber. If the Layer identified
+    // by handle is removed, then we will apply this transaction regardless of
+    // what frame number has been reached.
     status_t deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber);
+
+    // A variant of deferTransactionUntil which identifies the Layer we wait for by
+    // Surface instead of Handle. Useful for clients which may not have the
+    // SurfaceControl for some of their Surfaces. Otherwise behaves identically.
+    status_t deferTransactionUntil(const sp<Surface>& barrier, uint64_t frameNumber);
+
     // Reparents all children of this layer to the new parent handle.
     status_t reparentChildren(const sp<IBinder>& newParentHandle);
 
+    // Detaches all child surfaces (and their children recursively)
+    // from their SurfaceControl.
+    // The child SurfaceControl's will not throw exceptions or return errors,
+    // but transactions will have no effect.
+    // The child surfaces will continue to follow their parent surfaces,
+    // and remain eligible for rendering, but their relative state will be
+    // frozen. We use this in the WindowManager, in app shutdown/relaunch
+    // scenarios, where the app would otherwise clean up its child Surfaces.
+    // Sometimes the WindowManager needs to extend their lifetime slightly
+    // in order to perform an exit animation or prevent flicker.
+    status_t detachChildren();
+
     // Set an override scaling mode as documented in <system/window.h>
     // the override scaling mode will take precedence over any client
     // specified scaling mode. -1 will clear the override scaling mode.
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 0bcff46..20f51a5 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -24,6 +24,7 @@
 
 #include <ui/Region.h>
 #include <ui/Rect.h>
+#include <gui/IGraphicBufferProducer.h>
 
 namespace android {
 
@@ -57,6 +58,7 @@
         eOverrideScalingModeChanged = 0x00000800,
         eGeometryAppliesWithResize  = 0x00001000,
         eReparentChildren           = 0x00002000,
+        eDetachChildren             = 0x00004000
     };
 
     layer_state_t()
@@ -95,10 +97,13 @@
             matrix22_t      matrix;
             Rect            crop;
             Rect            finalCrop;
-            sp<IBinder>     handle;
+            sp<IBinder>     barrierHandle;
             sp<IBinder>     reparentHandle;
             uint64_t        frameNumber;
             int32_t         overrideScalingMode;
+
+            sp<IGraphicBufferProducer> barrierGbp;
+
             // non POD must be last. see write/read
             Region          transparentRegion;
 };
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 93b8684..2cb44eb 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -34,6 +34,7 @@
         "IResultReceiver.cpp",
         "IServiceManager.cpp",
         "IShellCallback.cpp",
+        "HalToken.cpp",
         "MemoryBase.cpp",
         "MemoryDealer.cpp",
         "MemoryHeapBase.cpp",
@@ -65,6 +66,8 @@
         "liblog",
         "libcutils",
         "libutils",
+        "libhidlbase",
+        "android.hidl.token@1.0",
     ],
     export_shared_lib_headers: [
         "libbase",
diff --git a/libs/binder/HalToken.cpp b/libs/binder/HalToken.cpp
new file mode 100644
index 0000000..6e71a52
--- /dev/null
+++ b/libs/binder/HalToken.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+#define LOG_TAG "HalToken"
+
+#include <utils/Log.h>
+#include <binder/HalToken.h>
+
+#include <android/hidl/token/1.0/ITokenManager.h>
+
+namespace android {
+
+using ::android::hidl::token::V1_0::ITokenManager;
+
+sp<ITokenManager> gTokenManager = nullptr;
+
+ITokenManager* getTokenManager() {
+    if (gTokenManager != nullptr) {
+        return gTokenManager.get();
+    }
+    gTokenManager = ITokenManager::getService();
+    if (gTokenManager == nullptr) {
+        ALOGE("Cannot retrieve TokenManager.");
+    }
+    return gTokenManager.get();
+}
+
+sp<HInterface> retrieveHalInterface(const HalToken& token) {
+    auto transaction = getTokenManager()->get(token);
+    if (!transaction.isOk()) {
+        ALOGE("getHalInterface: Cannot obtain interface from token.");
+        return nullptr;
+    }
+    return static_cast<sp<HInterface> >(transaction);
+}
+
+bool createHalToken(const sp<HInterface>& interface, HalToken* token) {
+    auto transaction = getTokenManager()->createToken(interface);
+    if (!transaction.isOk()) {
+        ALOGE("createHalToken: Cannot create token from interface.");
+        return false;
+    }
+    *token = static_cast<HalToken>(transaction);
+    return true;
+}
+
+bool deleteHalToken(const HalToken& token) {
+    auto transaction = getTokenManager()->unregister(token);
+    if (!transaction.isOk()) {
+        ALOGE("deleteHalToken: Cannot unregister hal token.");
+        return false;
+    }
+    return true;
+}
+
+}; // namespace android
+
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index bb552aa..2461cba 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -39,10 +39,11 @@
             output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix;
     output.write(crop);
     output.write(finalCrop);
-    output.writeStrongBinder(handle);
+    output.writeStrongBinder(barrierHandle);
     output.writeStrongBinder(reparentHandle);
     output.writeUint64(frameNumber);
     output.writeInt32(overrideScalingMode);
+    output.writeStrongBinder(IInterface::asBinder(barrierGbp));
     output.write(transparentRegion);
     return NO_ERROR;
 }
@@ -68,10 +69,12 @@
     }
     input.read(crop);
     input.read(finalCrop);
-    handle = input.readStrongBinder();
+    barrierHandle = input.readStrongBinder();
     reparentHandle = input.readStrongBinder();
     frameNumber = input.readUint64();
     overrideScalingMode = input.readInt32();
+    barrierGbp =
+        interface_cast<IGraphicBufferProducer>(input.readStrongBinder());
     input.read(transparentRegion);
     return NO_ERROR;
 }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 91e84c4..088933a 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -37,6 +37,7 @@
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/ISurfaceComposerClient.h>
+#include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
 
 #include <private/gui/ComposerService.h>
@@ -167,9 +168,14 @@
     status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id, const sp<IBinder>& handle,
             uint64_t frameNumber);
+    status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client,
+            const sp<IBinder>& id, const sp<Surface>& barrierSurface,
+            uint64_t frameNumber);
     status_t reparentChildren(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id,
             const sp<IBinder>& newParentHandle);
+    status_t detachChildren(const sp<SurfaceComposerClient>& client,
+            const sp<IBinder>& id);
     status_t setOverrideScalingMode(const sp<SurfaceComposerClient>& client,
             const sp<IBinder>& id, int32_t overrideScalingMode);
     status_t setGeometryAppliesWithResize(const sp<SurfaceComposerClient>& client,
@@ -438,7 +444,21 @@
         return BAD_INDEX;
     }
     s->what |= layer_state_t::eDeferTransaction;
-    s->handle = handle;
+    s->barrierHandle = handle;
+    s->frameNumber = frameNumber;
+    return NO_ERROR;
+}
+
+status_t Composer::deferTransactionUntil(
+        const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+        const sp<Surface>& barrierSurface, uint64_t frameNumber) {
+    Mutex::Autolock lock(mLock);
+    layer_state_t* s = getLayerStateLocked(client, id);
+    if (!s) {
+        return BAD_INDEX;
+    }
+    s->what |= layer_state_t::eDeferTransaction;
+    s->barrierGbp = barrierSurface->getIGraphicBufferProducer();
     s->frameNumber = frameNumber;
     return NO_ERROR;
 }
@@ -457,6 +477,18 @@
     return NO_ERROR;
 }
 
+status_t Composer::detachChildren(
+        const sp<SurfaceComposerClient>& client,
+        const sp<IBinder>& id) {
+    Mutex::Autolock lock(mLock);
+    layer_state_t* s = getLayerStateLocked(client, id);
+    if (!s) {
+        return BAD_INDEX;
+    }
+    s->what |= layer_state_t::eDetachChildren;
+    return NO_ERROR;
+}
+
 status_t Composer::setOverrideScalingMode(
         const sp<SurfaceComposerClient>& client,
         const sp<IBinder>& id, int32_t overrideScalingMode) {
@@ -776,11 +808,20 @@
     return getComposer().deferTransactionUntil(this, id, handle, frameNumber);
 }
 
+status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id,
+        const sp<Surface>& barrierSurface, uint64_t frameNumber) {
+    return getComposer().deferTransactionUntil(this, id, barrierSurface, frameNumber);
+}
+
 status_t SurfaceComposerClient::reparentChildren(const sp<IBinder>& id,
         const sp<IBinder>& newParentHandle) {
     return getComposer().reparentChildren(this, id, newParentHandle);
 }
 
+status_t SurfaceComposerClient::detachChildren(const sp<IBinder>& id) {
+    return getComposer().detachChildren(this, id);
+}
+
 status_t SurfaceComposerClient::setOverrideScalingMode(
         const sp<IBinder>& id, int32_t overrideScalingMode) {
     return getComposer().setOverrideScalingMode(
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 070a3c8..1e69379 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -170,12 +170,25 @@
     return mClient->deferTransactionUntil(mHandle, handle, frameNumber);
 }
 
+status_t SurfaceControl::deferTransactionUntil(const sp<Surface>& handle,
+        uint64_t frameNumber) {
+    status_t err = validate();
+    if (err < 0) return err;
+    return mClient->deferTransactionUntil(mHandle, handle, frameNumber);
+}
+
 status_t SurfaceControl::reparentChildren(const sp<IBinder>& newParentHandle) {
     status_t err = validate();
     if (err < 0) return err;
     return mClient->reparentChildren(mHandle, newParentHandle);
 }
 
+status_t SurfaceControl::detachChildren() {
+    status_t err = validate();
+    if (err < 0) return err;
+    return mClient->detachChildren(mHandle);
+}
+
 status_t SurfaceControl::setOverrideScalingMode(int32_t overrideScalingMode) {
     status_t err = validate();
     if (err < 0) return err;
diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp
index d755ed3..9d761fd 100644
--- a/libs/input/InputDevice.cpp
+++ b/libs/input/InputDevice.cpp
@@ -21,6 +21,7 @@
 #include <ctype.h>
 
 #include <input/InputDevice.h>
+#include <input/InputEventLabels.h>
 
 namespace android {
 
@@ -87,17 +88,23 @@
         const String8& name, InputDeviceConfigurationFileType type) {
     // Search system repository.
     String8 path;
-    path.setTo(getenv("ANDROID_ROOT"));
-    path.append("/usr/");
-    appendInputDeviceConfigurationFileRelativePath(path, name, type);
+
+    // Treblized input device config files will be located /odm/usr or /vendor/usr.
+    char *rootsForPartition[] {"/odm", "/vendor", getenv("ANDROID_ROOT")};
+    for (size_t i = 0; i < size(rootsForPartition); i++) {
+        path.setTo(rootsForPartition[i]);
+        path.append("/usr/");
+        appendInputDeviceConfigurationFileRelativePath(path, name, type);
 #if DEBUG_PROBE
-    ALOGD("Probing for system provided input device configuration file: path='%s'", path.string());
+        ALOGD("Probing for system provided input device configuration file: path='%s'",
+              path.string());
 #endif
-    if (!access(path.string(), R_OK)) {
+        if (!access(path.string(), R_OK)) {
 #if DEBUG_PROBE
-        ALOGD("Found");
+            ALOGD("Found");
 #endif
-        return path;
+            return path;
+        }
     }
 
     // Search user repository.
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index d0e4161..9c5f096 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -20,6 +20,14 @@
     license: "NOTICE",
 }
 
+ndk_library {
+    name: "libnativewindow.ndk",
+    symbol_file: "libnativewindow.map.txt",
+
+    // Android O
+    first_version: "26",
+}
+
 cc_library {
     name: "libnativewindow",
     export_include_dirs: ["include"],
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
new file mode 100644
index 0000000..dcfabac
--- /dev/null
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -0,0 +1,26 @@
+LIBNATIVEWINDOW {
+  global:
+    AHardwareBuffer_acquire;
+    AHardwareBuffer_allocate;
+    AHardwareBuffer_describe;
+    AHardwareBuffer_fromHardwareBuffer;
+    AHardwareBuffer_getNativeHandle;
+    AHardwareBuffer_lock;
+    AHardwareBuffer_recvHandleFromUnixSocket;
+    AHardwareBuffer_release;
+    AHardwareBuffer_sendHandleToUnixSocket;
+    AHardwareBuffer_toHardwareBuffer;
+    AHardwareBuffer_unlock;
+    ANativeWindow_acquire;
+    ANativeWindow_fromSurface;
+    ANativeWindow_fromSurfaceTexture;
+    ANativeWindow_getFormat;
+    ANativeWindow_getHeight;
+    ANativeWindow_getWidth;
+    ANativeWindow_lock;
+    ANativeWindow_release;
+    ANativeWindow_setBuffersGeometry;
+    ANativeWindow_unlockAndPost;
+  local:
+    *;
+};
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 2b4f4cb..9ddae2b 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -49,7 +49,10 @@
 {
     const size_t count = mLayers.size();
     for (size_t i=0 ; i<count ; i++) {
-        mFlinger->removeLayer(mLayers.valueAt(i));
+        sp<Layer> l = mLayers.valueAt(i).promote();
+        if (l != nullptr) {
+            mFlinger->removeLayer(l);
+        }
     }
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 4a281d4..f03491f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -69,7 +69,8 @@
       mCBContext(),
       mEventHandler(nullptr),
       mVSyncCounts(),
-      mRemainingHwcVirtualDisplays(0)
+      mRemainingHwcVirtualDisplays(0),
+      mDumpMayLockUp(false)
 {
     for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {
         mLastHwVSync[i] = 0;
@@ -489,6 +490,8 @@
         return NO_ERROR;
     }
 
+    mDumpMayLockUp = true;
+
     uint32_t numTypes = 0;
     uint32_t numRequests = 0;
     auto error = hwcDisplay->validate(&numTypes, &numRequests);
@@ -633,6 +636,9 @@
     auto& displayData = mDisplayData[displayId];
     auto& hwcDisplay = displayData.hwcDisplay;
     auto error = hwcDisplay->present(&displayData.lastPresentFence);
+
+    mDumpMayLockUp = false;
+
     if (error != HWC2::Error::None) {
         ALOGE("presentAndGetReleaseFences: failed for display %d: %s (%d)",
               displayId, to_string(error).c_str(), static_cast<int32_t>(error));
@@ -878,6 +884,11 @@
 }
 
 void HWComposer::dump(String8& result) const {
+    if (mDumpMayLockUp) {
+        result.append("HWComposer dump skipped because present in progress");
+        return;
+    }
+
     // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
     // all the state going into the layers. This is probably better done in
     // Layer itself, but it's going to take a bit of work to get there.
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 0713709..20cca39 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -231,6 +231,9 @@
 
     // thread-safe
     mutable Mutex mVsyncLock;
+
+    // XXX temporary workaround for b/35806047
+    mutable std::atomic<bool> mDumpMayLockUp;
 };
 
 class HWComposerBufferCache {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index f45f2a1..24ebac7 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1436,29 +1436,23 @@
 
     // If this transaction is waiting on the receipt of a frame, generate a sync
     // point and send it to the remote layer.
-    if (mCurrentState.handle != nullptr) {
-        sp<IBinder> strongBinder = mCurrentState.handle.promote();
-        sp<Handle> handle = nullptr;
-        sp<Layer> handleLayer = nullptr;
-        if (strongBinder != nullptr) {
-            handle = static_cast<Handle*>(strongBinder.get());
-            handleLayer = handle->owner.promote();
-        }
-        if (strongBinder == nullptr || handleLayer == nullptr) {
-            ALOGE("[%s] Unable to promote Layer handle", mName.string());
+    if (mCurrentState.barrierLayer != nullptr) {
+        sp<Layer> barrierLayer = mCurrentState.barrierLayer.promote();
+        if (barrierLayer == nullptr) {
+            ALOGE("[%s] Unable to promote barrier Layer.", mName.string());
             // If we can't promote the layer we are intended to wait on,
             // then it is expired or otherwise invalid. Allow this transaction
             // to be applied as per normal (no synchronization).
-            mCurrentState.handle = nullptr;
+            mCurrentState.barrierLayer = nullptr;
         } else {
             auto syncPoint = std::make_shared<SyncPoint>(
                     mCurrentState.frameNumber);
-            if (handleLayer->addSyncPoint(syncPoint)) {
+            if (barrierLayer->addSyncPoint(syncPoint)) {
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
                 // We already missed the frame we're supposed to synchronize
                 // on, so go ahead and apply the state update
-                mCurrentState.handle = nullptr;
+                mCurrentState.barrierLayer = nullptr;
             }
         }
 
@@ -1481,7 +1475,7 @@
 bool Layer::applyPendingStates(State* stateToCommit) {
     bool stateUpdateAvailable = false;
     while (!mPendingStates.empty()) {
-        if (mPendingStates[0].handle != nullptr) {
+        if (mPendingStates[0].barrierLayer != nullptr) {
             if (mRemoteSyncPoints.empty()) {
                 // If we don't have a sync point for this, apply it anyway. It
                 // will be visually wrong, but it should keep us from getting
@@ -1828,17 +1822,24 @@
     return p->getLayerStack();
 }
 
-void Layer::deferTransactionUntil(const sp<IBinder>& handle,
+void Layer::deferTransactionUntil(const sp<Layer>& barrierLayer,
         uint64_t frameNumber) {
-    mCurrentState.handle = handle;
+    mCurrentState.barrierLayer = barrierLayer;
     mCurrentState.frameNumber = frameNumber;
     // We don't set eTransactionNeeded, because just receiving a deferral
     // request without any other state updates shouldn't actually induce a delay
     mCurrentState.modified = true;
     pushPendingState();
-    mCurrentState.handle = nullptr;
+    mCurrentState.barrierLayer = nullptr;
     mCurrentState.frameNumber = 0;
     mCurrentState.modified = false;
+    ALOGE("Deferred transaction");
+}
+
+void Layer::deferTransactionUntil(const sp<IBinder>& barrierHandle,
+        uint64_t frameNumber) {
+    sp<Handle> handle = static_cast<Handle*>(barrierHandle.get());
+    deferTransactionUntil(handle->owner.promote(), frameNumber);
 }
 
 void Layer::useSurfaceDamage() {
@@ -2454,6 +2455,21 @@
     return true;
 }
 
+bool Layer::detachChildren() {
+    traverseInZOrder([this](Layer* child) {
+        if (child == this) {
+            return;
+        }
+
+        sp<Client> client(child->mClientRef.promote());
+        if (client != nullptr) {
+            client->detachLayer(child);
+        }
+    });
+
+    return true;
+}
+
 void Layer::setParent(const sp<Layer>& layer) {
     mParent = layer;
 }
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c5fea73..f2e5f22 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -128,9 +128,9 @@
         // finalCrop is expressed in display space coordinate.
         Rect finalCrop;
 
-        // If set, defers this state update until the Layer identified by handle
+        // If set, defers this state update until the identified Layer
         // receives a frame with the given frameNumber
-        wp<IBinder> handle;
+        wp<Layer> barrierLayer;
         uint64_t frameNumber;
 
         // the transparentRegion hint is a bit special, it's latched only
@@ -171,10 +171,12 @@
     bool setLayerStack(uint32_t layerStack);
     bool setDataSpace(android_dataspace dataSpace);
     uint32_t getLayerStack() const;
-    void deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber);
+    void deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t frameNumber);
+    void deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber);
     bool setOverrideScalingMode(int32_t overrideScalingMode);
     void setInfo(uint32_t type, uint32_t appId);
     bool reparentChildren(const sp<IBinder>& layer);
+    bool detachChildren();
 
     // If we have received a new buffer this frame, we will pass its surface
     // damage down to hardware composer. Otherwise, we must send a region with
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e9613cc..4acdb82 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -166,7 +166,7 @@
         mLastTransactionTime(0),
         mBootFinished(false),
         mForceFullDamage(false),
-        mInterceptor(),
+        mInterceptor(this),
         mPrimaryDispSync("PrimaryDispSync"),
         mPrimaryHWVsyncEnabled(false),
         mHWVsyncAvailable(false),
@@ -628,6 +628,11 @@
 bool SurfaceFlinger::authenticateSurfaceTexture(
         const sp<IGraphicBufferProducer>& bufferProducer) const {
     Mutex::Autolock _l(mStateLock);
+    return authenticateSurfaceTextureLocked(bufferProducer);
+}
+
+bool SurfaceFlinger::authenticateSurfaceTextureLocked(
+        const sp<IGraphicBufferProducer>& bufferProducer) const {
     sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
     return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
 }
@@ -2529,14 +2534,7 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
-    Mutex::Autolock _l(mStateLock);
-    sp<Layer> layer = weakLayer.promote();
-    if (layer == nullptr) {
-        // The layer has already been removed, carry on
-        return NO_ERROR;
-    }
-
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
     const auto& p = layer->getParent();
     const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
         mCurrentState.layersSortedByZ.remove(layer);
@@ -2798,7 +2796,19 @@
             }
         }
         if (what & layer_state_t::eDeferTransaction) {
-            layer->deferTransactionUntil(s.handle, s.frameNumber);
+            if (s.barrierHandle != nullptr) {
+                layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
+            } else if (s.barrierGbp != nullptr) {
+                const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
+                if (authenticateSurfaceTextureLocked(gbp)) {
+                    const auto& otherLayer =
+                        (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+                    layer->deferTransactionUntil(otherLayer, s.frameNumber);
+                } else {
+                    ALOGE("Attempt to defer transaction to to an"
+                            " unrecognized GraphicBufferProducer");
+                }
+            }
             // We don't trigger a traversal here because if no other state is
             // changed, we don't want this to cause any more work
         }
@@ -2807,6 +2817,9 @@
                 flags |= eTransactionNeeded|eTraversalNeeded;
             }
         }
+        if (what & layer_state_t::eDetachChildren) {
+            layer->detachChildren();
+        }
         if (what & layer_state_t::eOverrideScalingModeChanged) {
             layer->setOverrideScalingMode(s.overrideScalingMode);
             // We don't trigger a traversal here because if no other state is
@@ -2903,7 +2916,7 @@
 
 status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
 {
-    // called by the window manager when it wants to remove a Layer
+    // called by a client when it wants to remove a Layer
     status_t err = NO_ERROR;
     sp<Layer> l(client->getLayerUser(handle));
     if (l != NULL) {
@@ -2919,7 +2932,15 @@
 {
     // called by ~LayerCleaner() when all references to the IBinder (handle)
     // are gone
-    return removeLayer(layer);
+    sp<Layer> l = layer.promote();
+    if (l == nullptr) {
+        // The layer has already been removed, carry on
+        return NO_ERROR;
+    } if (l->getParent() != nullptr) {
+        // If we have a parent, then we can continue to live as long as it does.
+        return NO_ERROR;
+    }
+    return removeLayer(l);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b415078..0b3deef 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -158,6 +158,9 @@
         return *mRenderEngine;
     }
 
+    bool authenticateSurfaceTextureLocked(
+        const sp<IGraphicBufferProducer>& bufferProducer) const;
+
 private:
     friend class Client;
     friend class DisplayEventConnection;
@@ -327,7 +330,7 @@
     status_t onLayerDestroyed(const wp<Layer>& layer);
 
     // remove a layer from SurfaceFlinger immediately
-    status_t removeLayer(const wp<Layer>& layer);
+    status_t removeLayer(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
     status_t addClientLayer(const sp<Client>& client,
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 6f686a6..fe8dd0c 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -154,7 +154,7 @@
         mLastTransactionTime(0),
         mBootFinished(false),
         mForceFullDamage(false),
-        mInterceptor(),
+        mInterceptor(this),
         mPrimaryDispSync("PrimaryDispSync"),
         mPrimaryHWVsyncEnabled(false),
         mHWVsyncAvailable(false),
@@ -627,6 +627,11 @@
 bool SurfaceFlinger::authenticateSurfaceTexture(
         const sp<IGraphicBufferProducer>& bufferProducer) const {
     Mutex::Autolock _l(mStateLock);
+    return authenticateSurfaceTextureLocked(bufferProducer);
+}
+
+bool SurfaceFlinger::authenticateSurfaceTextureLocked(
+        const sp<IGraphicBufferProducer>& bufferProducer) const {
     sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
     return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
 }
@@ -2312,14 +2317,7 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
-    Mutex::Autolock _l(mStateLock);
-    sp<Layer> layer = weakLayer.promote();
-    if (layer == nullptr) {
-        // The layer has already been removed, carry on
-        return NO_ERROR;
-    }
-
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
     const auto& p = layer->getParent();
     const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
              mCurrentState.layersSortedByZ.remove(layer);
@@ -2581,7 +2579,19 @@
             }
         }
         if (what & layer_state_t::eDeferTransaction) {
-            layer->deferTransactionUntil(s.handle, s.frameNumber);
+            if (s.barrierHandle != nullptr) {
+                layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
+            } else if (s.barrierGbp != nullptr) {
+                const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
+                if (authenticateSurfaceTextureLocked(gbp)) {
+                    const auto& otherLayer =
+                        (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+                    layer->deferTransactionUntil(otherLayer, s.frameNumber);
+                } else {
+                    ALOGE("Attempt to defer transaction to to an"
+                            " unrecognized GraphicBufferProducer");
+                }
+            }
             // We don't trigger a traversal here because if no other state is
             // changed, we don't want this to cause any more work
         }
@@ -2590,6 +2600,9 @@
                 flags |= eTransactionNeeded|eTraversalNeeded;
             }
         }
+        if (what & layer_state_t::eDetachChildren) {
+            layer->detachChildren();
+        }
         if (what & layer_state_t::eOverrideScalingModeChanged) {
             layer->setOverrideScalingMode(s.overrideScalingMode);
             // We don't trigger a traversal here because if no other state is
@@ -2686,7 +2699,7 @@
 
 status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
 {
-    // called by the window manager when it wants to remove a Layer
+    // called by a client when it wants to remove a Layer
     status_t err = NO_ERROR;
     sp<Layer> l(client->getLayerUser(handle));
     if (l != NULL) {
@@ -2702,7 +2715,15 @@
 {
     // called by ~LayerCleaner() when all references to the IBinder (handle)
     // are gone
-    return removeLayer(layer);
+    sp<Layer> l = layer.promote();
+    if (l == nullptr) {
+        // The layer has already been removed, carry on
+        return NO_ERROR;
+    } if (l->getParent() != nullptr) {
+        // If we have a parent, then we can continue to live as long as it does.
+        return NO_ERROR;
+    }
+    return removeLayer(l);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 2d6472a..026fe80 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -31,6 +31,11 @@
 
 // ----------------------------------------------------------------------------
 
+SurfaceInterceptor::SurfaceInterceptor(SurfaceFlinger* flinger)
+    :   mFlinger(flinger)
+{
+}
+
 void SurfaceInterceptor::enable(const SortedVector<sp<Layer>>& layers,
         const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays)
 {
@@ -97,8 +102,8 @@
     addTransparentRegionLocked(transaction, layerId, layer->mCurrentState.activeTransparentRegion);
     addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
     addCropLocked(transaction, layerId, layer->mCurrentState.crop);
-    if (layer->mCurrentState.handle != nullptr) {
-        addDeferTransactionLocked(transaction, layerId, layer->mCurrentState.handle,
+    if (layer->mCurrentState.barrierLayer != nullptr) {
+        addDeferTransactionLocked(transaction, layerId, layer->mCurrentState.barrierLayer.promote(),
                 layer->mCurrentState.frameNumber);
     }
     addFinalCropLocked(transaction, layerId, layer->mCurrentState.finalCrop);
@@ -287,10 +292,9 @@
 }
 
 void SurfaceInterceptor::addDeferTransactionLocked(Transaction* transaction, int32_t layerId,
-        const wp<const IBinder>& weakHandle, uint64_t frameNumber)
+        const sp<const Layer>& layer, uint64_t frameNumber)
 {
     SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId));
-    const sp<const Layer> layer(getLayer(weakHandle));
     if (layer == nullptr) {
         ALOGE("An existing layer could not be retrieved with the handle"
                 " for the deferred transaction");
@@ -349,7 +353,18 @@
         addCropLocked(transaction, layerId, state.crop);
     }
     if (state.what & layer_state_t::eDeferTransaction) {
-        addDeferTransactionLocked(transaction, layerId, state.handle, state.frameNumber);
+        sp<Layer> otherLayer = nullptr;
+        if (state.barrierHandle != nullptr) {
+            otherLayer = static_cast<Layer::Handle*>(state.barrierHandle.get())->owner.promote();
+        } else if (state.barrierGbp != nullptr) {
+            auto const& gbp = state.barrierGbp;
+            if (mFlinger->authenticateSurfaceTextureLocked(gbp)) {
+                otherLayer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+            } else {
+                ALOGE("Attempt to defer transaction to to an unrecognized GraphicBufferProducer");
+            }
+        }
+        addDeferTransactionLocked(transaction, layerId, otherLayer, state.frameNumber);
     }
     if (state.what & layer_state_t::eFinalCropChanged) {
         addFinalCropLocked(transaction, layerId, state.finalCrop);
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index 9af6e61..30ebcc6 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -28,6 +28,7 @@
 
 class BufferItem;
 class Layer;
+class SurfaceFlinger;
 struct DisplayState;
 struct layer_state_t;
 
@@ -39,6 +40,7 @@
  */
 class SurfaceInterceptor {
 public:
+    SurfaceInterceptor(SurfaceFlinger* const flinger);
     // Both vectors are used to capture the current state of SF as the initial snapshot in the trace
     void enable(const SortedVector<sp<Layer>>& layers,
             const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays);
@@ -102,7 +104,7 @@
     void addLayerStackLocked(Transaction* transaction, int32_t layerId, uint32_t layerStack);
     void addCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect);
     void addDeferTransactionLocked(Transaction* transaction, int32_t layerId,
-            const wp<const IBinder>& weakHandle, uint64_t frameNumber);
+            const sp<const Layer>& layer, uint64_t frameNumber);
     void addFinalCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect);
     void addOverrideScalingModeLocked(Transaction* transaction, int32_t layerId,
             int32_t overrideScalingMode);
@@ -129,6 +131,7 @@
     std::string mOutputFileName {DEFAULT_FILENAME};
     std::mutex mTraceMutex {};
     Trace mTrace {};
+    SurfaceFlinger* const mFlinger;
 };
 
 }
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 8bbb974..aeb557a 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -628,4 +628,68 @@
         mCapture->expectFGColor(20, 20);
     }
 }
+
+TEST_F(ChildLayerTest, ReparentChildren) {
+    SurfaceComposerClient::openGlobalTransaction();
+    mChild->show();
+    mChild->setPosition(10, 10);
+    mFGSurfaceControl->setPosition(64, 64);
+    SurfaceComposerClient::closeGlobalTransaction(true);
+
+    {
+        ScreenCapture::captureScreen(&mCapture);
+        // Top left of foreground must now be visible
+        mCapture->expectFGColor(64, 64);
+        // But 10 pixels in we should see the child surface
+        mCapture->expectChildColor(74, 74);
+        // And 10 more pixels we should be back to the foreground surface
+        mCapture->expectFGColor(84, 84);
+    }
+    mFGSurfaceControl->reparentChildren(mBGSurfaceControl->getHandle());
+    {
+        ScreenCapture::captureScreen(&mCapture);
+        mCapture->expectFGColor(64, 64);
+        // In reparenting we should have exposed the entire foreground surface.
+        mCapture->expectFGColor(74, 74);
+        // And the child layer should now begin at 10, 10 (since the BG
+        // layer is at (0, 0)).
+        mCapture->expectBGColor(9, 9);
+        mCapture->expectChildColor(10, 10);
+    }
+}
+
+TEST_F(ChildLayerTest, DetachChildren) {
+    SurfaceComposerClient::openGlobalTransaction();
+    mChild->show();
+    mChild->setPosition(10, 10);
+    mFGSurfaceControl->setPosition(64, 64);
+    SurfaceComposerClient::closeGlobalTransaction(true);
+
+    {
+        ScreenCapture::captureScreen(&mCapture);
+        // Top left of foreground must now be visible
+        mCapture->expectFGColor(64, 64);
+        // But 10 pixels in we should see the child surface
+        mCapture->expectChildColor(74, 74);
+        // And 10 more pixels we should be back to the foreground surface
+        mCapture->expectFGColor(84, 84);
+    }
+
+    SurfaceComposerClient::openGlobalTransaction();
+    mFGSurfaceControl->detachChildren();
+    SurfaceComposerClient::closeGlobalTransaction();
+
+    SurfaceComposerClient::openGlobalTransaction();
+    mChild->hide();
+    SurfaceComposerClient::closeGlobalTransaction();
+
+    // Nothing should have changed.
+    {
+        ScreenCapture::captureScreen(&mCapture);
+        mCapture->expectFGColor(64, 64);
+        mCapture->expectChildColor(74, 74);
+        mCapture->expectFGColor(84, 84);
+    }
+}
+
 }