Merge "surfaceflinger: work around dumpsys lockup"
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/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/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/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/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);
+ }
+}
+
}