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);
+ }
+}
+
}