Add mechanism for a task's windows to be trusted overlays (SF)
- Add a layer state to indicate that this layer and its children in the hierarchy are trusted. This can only be set by callers holding ACCESS_SURFACE_FLINGER, and will be used for the PIP task layer to indicate that activities in PIP are trusted (as they are controlled only by the user and SystemUI) Bug: 191529039 Test: TBD Change-Id: Id92ccb087bd0d8dbaeeef3ba50b67fe015e53db8
This commit is contained in:
parent
5a68a6cfe0
commit
a30f7c9974
14 changed files with 113 additions and 0 deletions
|
@ -52,6 +52,7 @@ message SurfaceChange {
|
|||
BackgroundBlurRadiusChange background_blur_radius = 20;
|
||||
ShadowRadiusChange shadow_radius = 21;
|
||||
BlurRegionsChange blur_regions = 22;
|
||||
TrustedOverlayChange trusted_overlay = 23;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,6 +193,10 @@ message ShadowRadiusChange {
|
|||
required float radius = 1;
|
||||
}
|
||||
|
||||
message TrustedOverlayChange {
|
||||
required float is_trusted_overlay = 1;
|
||||
}
|
||||
|
||||
message BlurRegionsChange {
|
||||
repeated BlurRegionChange blur_regions = 1;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ layer_state_t::layer_state_t()
|
|||
fixedTransformHint(ui::Transform::ROT_INVALID),
|
||||
frameNumber(0),
|
||||
autoRefresh(false),
|
||||
isTrustedOverlay(false),
|
||||
bufferCrop(Rect::INVALID_RECT),
|
||||
destinationFrame(Rect::INVALID_RECT),
|
||||
releaseBufferListener(nullptr) {
|
||||
|
@ -170,6 +171,7 @@ status_t layer_state_t::write(Parcel& output) const
|
|||
SAFE_PARCEL(output.write, stretchEffect);
|
||||
SAFE_PARCEL(output.write, bufferCrop);
|
||||
SAFE_PARCEL(output.write, destinationFrame);
|
||||
SAFE_PARCEL(output.writeBool, isTrustedOverlay);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
@ -300,6 +302,7 @@ status_t layer_state_t::read(const Parcel& input)
|
|||
SAFE_PARCEL(input.read, stretchEffect);
|
||||
SAFE_PARCEL(input.read, bufferCrop);
|
||||
SAFE_PARCEL(input.read, destinationFrame);
|
||||
SAFE_PARCEL(input.readBool, &isTrustedOverlay);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
@ -532,6 +535,10 @@ void layer_state_t::merge(const layer_state_t& other) {
|
|||
what |= eAutoRefreshChanged;
|
||||
autoRefresh = other.autoRefresh;
|
||||
}
|
||||
if (other.what & eTrustedOverlayChanged) {
|
||||
what |= eTrustedOverlayChanged;
|
||||
isTrustedOverlay = other.isTrustedOverlay;
|
||||
}
|
||||
if (other.what & eReleaseBufferListenerChanged) {
|
||||
if (releaseBufferListener) {
|
||||
ALOGW("Overriding releaseBufferListener");
|
||||
|
|
|
@ -1656,6 +1656,19 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAutoR
|
|||
return *this;
|
||||
}
|
||||
|
||||
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrustedOverlay(
|
||||
const sp<SurfaceControl>& sc, bool isTrustedOverlay) {
|
||||
layer_state_t* s = getLayerState(sc);
|
||||
if (!s) {
|
||||
mStatus = BAD_INDEX;
|
||||
return *this;
|
||||
}
|
||||
|
||||
s->what |= layer_state_t::eTrustedOverlayChanged;
|
||||
s->isTrustedOverlay = isTrustedOverlay;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setApplyToken(
|
||||
const sp<IBinder>& applyToken) {
|
||||
mApplyToken = applyToken;
|
||||
|
|
|
@ -118,6 +118,7 @@ struct layer_state_t {
|
|||
eBlurRegionsChanged = 0x800'00000000,
|
||||
eAutoRefreshChanged = 0x1000'00000000,
|
||||
eStretchChanged = 0x2000'00000000,
|
||||
eTrustedOverlayChanged = 0x4000'00000000,
|
||||
};
|
||||
|
||||
layer_state_t();
|
||||
|
@ -225,6 +226,10 @@ struct layer_state_t {
|
|||
// in shared buffer mode.
|
||||
bool autoRefresh;
|
||||
|
||||
// An inherited state that indicates that this surface control and its children
|
||||
// should be trusted for input occlusion detection purposes
|
||||
bool isTrustedOverlay;
|
||||
|
||||
// Stretch effect to be applied to this layer
|
||||
StretchEffect stretchEffect;
|
||||
|
||||
|
|
|
@ -537,6 +537,9 @@ public:
|
|||
// in shared buffer mode.
|
||||
Transaction& setAutoRefresh(const sp<SurfaceControl>& sc, bool autoRefresh);
|
||||
|
||||
// Sets that this surface control and its children are trusted overlays for input
|
||||
Transaction& setTrustedOverlay(const sp<SurfaceControl>& sc, bool isTrustedOverlay);
|
||||
|
||||
// Queues up transactions using this token in SurfaceFlinger. By default, all transactions
|
||||
// from a client are placed on the same queue. This can be used to prevent multiple
|
||||
// transactions from blocking each other.
|
||||
|
|
|
@ -851,6 +851,23 @@ bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relati
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Layer::setTrustedOverlay(bool isTrustedOverlay) {
|
||||
if (mDrawingState.isTrustedOverlay == isTrustedOverlay) return false;
|
||||
mDrawingState.isTrustedOverlay = isTrustedOverlay;
|
||||
mDrawingState.modified = true;
|
||||
mFlinger->mInputInfoChanged = true;
|
||||
setTransactionFlags(eTransactionNeeded);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Layer::isTrustedOverlay() const {
|
||||
if (getDrawingState().isTrustedOverlay) {
|
||||
return true;
|
||||
}
|
||||
const auto& p = mDrawingParent.promote();
|
||||
return (p != nullptr) && p->isTrustedOverlay();
|
||||
}
|
||||
|
||||
bool Layer::setSize(uint32_t w, uint32_t h) {
|
||||
if (mDrawingState.requested_legacy.w == w && mDrawingState.requested_legacy.h == h)
|
||||
return false;
|
||||
|
@ -2041,6 +2058,7 @@ void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags,
|
|||
|
||||
layerInfo->set_corner_radius(getRoundedCornerState().radius);
|
||||
layerInfo->set_background_blur_radius(getBackgroundBlurRadius());
|
||||
layerInfo->set_is_trusted_overlay(isTrustedOverlay());
|
||||
LayerProtoHelper::writeToProto(transform, layerInfo->mutable_transform());
|
||||
LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
|
||||
[&]() { return layerInfo->mutable_position(); });
|
||||
|
@ -2327,6 +2345,11 @@ InputWindowInfo Layer::fillInputInfo(const sp<DisplayDevice>& display) {
|
|||
toPhysicalDisplay.transform(Rect{cropLayer->mScreenBounds}));
|
||||
}
|
||||
|
||||
// Inherit the trusted state from the parent hierarchy, but don't clobber the trusted state
|
||||
// if it was set by WM for a known system overlay
|
||||
info.trustedOverlay = info.trustedOverlay || isTrustedOverlay();
|
||||
|
||||
|
||||
// If the layer is a clone, we need to crop the input region to cloned root to prevent
|
||||
// touches from going outside the cloned area.
|
||||
if (isClone()) {
|
||||
|
|
|
@ -275,6 +275,9 @@ public:
|
|||
// Stretch effect to apply to this layer
|
||||
StretchEffect stretchEffect;
|
||||
|
||||
// Whether or not this layer is a trusted overlay for input
|
||||
bool isTrustedOverlay;
|
||||
|
||||
Rect bufferCrop;
|
||||
Rect destinationFrame;
|
||||
};
|
||||
|
@ -393,6 +396,7 @@ public:
|
|||
virtual bool setBackgroundBlurRadius(int backgroundBlurRadius);
|
||||
virtual bool setBlurRegions(const std::vector<BlurRegion>& effectRegions);
|
||||
virtual bool setTransparentRegionHint(const Region& transparent);
|
||||
virtual bool setTrustedOverlay(bool);
|
||||
virtual bool setFlags(uint32_t flags, uint32_t mask);
|
||||
virtual bool setLayerStack(uint32_t layerStack);
|
||||
virtual uint32_t getLayerStack() const;
|
||||
|
@ -1050,6 +1054,7 @@ private:
|
|||
|
||||
void updateTreeHasFrameRateVote();
|
||||
void setZOrderRelativeOf(const wp<Layer>& relativeOf);
|
||||
bool isTrustedOverlay() const;
|
||||
|
||||
// Find the root of the cloned hierarchy, this means the first non cloned parent.
|
||||
// This will return null if first non cloned parent is not found.
|
||||
|
|
|
@ -4156,6 +4156,15 @@ uint32_t SurfaceFlinger::setClientStateLocked(
|
|||
if (what & layer_state_t::eAutoRefreshChanged) {
|
||||
layer->setAutoRefresh(s.autoRefresh);
|
||||
}
|
||||
if (what & layer_state_t::eTrustedOverlayChanged) {
|
||||
if (privileged) {
|
||||
if (layer->setTrustedOverlay(s.isTrustedOverlay)) {
|
||||
flags |= eTraversalNeeded;
|
||||
}
|
||||
} else {
|
||||
ALOGE("Attempt to set trusted overlay without permission ACCESS_SURFACE_FLINGER");
|
||||
}
|
||||
}
|
||||
if (what & layer_state_t::eStretchChanged) {
|
||||
if (layer->setStretchEffect(s.stretchEffect)) {
|
||||
flags |= eTraversalNeeded;
|
||||
|
|
|
@ -149,6 +149,7 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment,
|
|||
getLayerIdFromWeakRef(layer->mDrawingState.zOrderRelativeOf),
|
||||
layer->mDrawingState.z);
|
||||
addShadowRadiusLocked(transaction, layerId, layer->mDrawingState.shadowRadius);
|
||||
addTrustedOverlayLocked(transaction, layerId, layer->mDrawingState.isTrustedOverlay);
|
||||
}
|
||||
|
||||
void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment,
|
||||
|
@ -397,6 +398,13 @@ void SurfaceInterceptor::addShadowRadiusLocked(Transaction* transaction, int32_t
|
|||
overrideChange->set_radius(shadowRadius);
|
||||
}
|
||||
|
||||
void SurfaceInterceptor::addTrustedOverlayLocked(Transaction* transaction, int32_t layerId,
|
||||
bool isTrustedOverlay) {
|
||||
SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId));
|
||||
TrustedOverlayChange* overrideChange(change->mutable_trusted_overlay());
|
||||
overrideChange->set_is_trusted_overlay(isTrustedOverlay);
|
||||
}
|
||||
|
||||
void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction,
|
||||
const layer_state_t& state)
|
||||
{
|
||||
|
@ -460,6 +468,9 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction,
|
|||
if (state.what & layer_state_t::eShadowRadiusChanged) {
|
||||
addShadowRadiusLocked(transaction, layerId, state.shadowRadius);
|
||||
}
|
||||
if (state.what & layer_state_t::eTrustedOverlayChanged) {
|
||||
addTrustedOverlayLocked(transaction, layerId, state.isTrustedOverlay);
|
||||
}
|
||||
if (state.what & layer_state_t::eStretchChanged) {
|
||||
ALOGW("SurfaceInterceptor not implemented for eStretchChanged");
|
||||
}
|
||||
|
|
|
@ -177,6 +177,7 @@ private:
|
|||
void addRelativeParentLocked(Transaction* transaction, int32_t layerId, int32_t parentId,
|
||||
int z);
|
||||
void addShadowRadiusLocked(Transaction* transaction, int32_t layerId, float shadowRadius);
|
||||
void addTrustedOverlayLocked(Transaction* transaction, int32_t layerId, bool isTrustedOverlay);
|
||||
|
||||
// Add display transactions to the trace
|
||||
DisplayChange* createDisplayChangeLocked(Transaction* transaction, int32_t sequenceId);
|
||||
|
|
|
@ -105,6 +105,7 @@ LayerProtoParser::Layer LayerProtoParser::generateLayer(const LayerProto& layerP
|
|||
layer.queuedFrames = layerProto.queued_frames();
|
||||
layer.refreshPending = layerProto.refresh_pending();
|
||||
layer.isProtected = layerProto.is_protected();
|
||||
layer.isTrustedOverlay = layerProto.is_trusted_overlay();
|
||||
layer.cornerRadius = layerProto.corner_radius();
|
||||
layer.backgroundBlurRadius = layerProto.background_blur_radius();
|
||||
for (const auto& entry : layerProto.metadata()) {
|
||||
|
@ -289,6 +290,7 @@ std::string LayerProtoParser::Layer::to_string() const {
|
|||
StringAppendF(&result, "crop=%s, ", crop.to_string().c_str());
|
||||
StringAppendF(&result, "cornerRadius=%f, ", cornerRadius);
|
||||
StringAppendF(&result, "isProtected=%1d, ", isProtected);
|
||||
StringAppendF(&result, "isTrustedOverlay=%1d, ", isTrustedOverlay);
|
||||
StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
|
||||
StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
|
||||
StringAppendF(&result, "defaultPixelFormat=%s, ", pixelFormat.c_str());
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
int32_t queuedFrames;
|
||||
bool refreshPending;
|
||||
bool isProtected;
|
||||
bool isTrustedOverlay;
|
||||
float cornerRadius;
|
||||
int backgroundBlurRadius;
|
||||
LayerMetadata metadata;
|
||||
|
|
|
@ -128,6 +128,8 @@ message LayerProto {
|
|||
|
||||
// Regions of a layer, where blur should be applied.
|
||||
repeated BlurRegion blur_regions = 54;
|
||||
|
||||
bool is_trusted_overlay = 55;
|
||||
}
|
||||
|
||||
message PositionProto {
|
||||
|
|
|
@ -193,6 +193,7 @@ public:
|
|||
bool reparentUpdateFound(const SurfaceChange& change, bool found);
|
||||
bool relativeParentUpdateFound(const SurfaceChange& change, bool found);
|
||||
bool shadowRadiusUpdateFound(const SurfaceChange& change, bool found);
|
||||
bool trustedOverlayUpdateFound(const SurfaceChange& change, bool found);
|
||||
bool surfaceUpdateFound(const Trace& trace, SurfaceChange::SurfaceChangeCase changeCase);
|
||||
|
||||
// Find all of the updates in the single trace
|
||||
|
@ -228,6 +229,7 @@ public:
|
|||
void reparentUpdate(Transaction&);
|
||||
void relativeParentUpdate(Transaction&);
|
||||
void shadowRadiusUpdate(Transaction&);
|
||||
void trustedOverlayUpdate(Transaction&);
|
||||
void surfaceCreation(Transaction&);
|
||||
void displayCreation(Transaction&);
|
||||
void displayDeletion(Transaction&);
|
||||
|
@ -405,6 +407,10 @@ void SurfaceInterceptorTest::shadowRadiusUpdate(Transaction& t) {
|
|||
t.setShadowRadius(mBGSurfaceControl, SHADOW_RADIUS_UPDATE);
|
||||
}
|
||||
|
||||
void SurfaceInterceptorTest::trustedOverlayUpdate(Transaction& t) {
|
||||
t.setTrustedOverlay(mBGSurfaceControl, true);
|
||||
}
|
||||
|
||||
void SurfaceInterceptorTest::displayCreation(Transaction&) {
|
||||
sp<IBinder> testDisplay = SurfaceComposerClient::createDisplay(DISPLAY_NAME, false);
|
||||
SurfaceComposerClient::destroyDisplay(testDisplay);
|
||||
|
@ -433,6 +439,7 @@ void SurfaceInterceptorTest::runAllUpdates() {
|
|||
runInTransaction(&SurfaceInterceptorTest::reparentUpdate);
|
||||
runInTransaction(&SurfaceInterceptorTest::relativeParentUpdate);
|
||||
runInTransaction(&SurfaceInterceptorTest::shadowRadiusUpdate);
|
||||
runInTransaction(&SurfaceInterceptorTest::trustedOverlayUpdate);
|
||||
}
|
||||
|
||||
void SurfaceInterceptorTest::surfaceCreation(Transaction&) {
|
||||
|
@ -644,6 +651,17 @@ bool SurfaceInterceptorTest::shadowRadiusUpdateFound(const SurfaceChange& change
|
|||
return foundShadowRadius;
|
||||
}
|
||||
|
||||
bool SurfaceInterceptorTest::trustedOverlayUpdateFound(const SurfaceChange& change,
|
||||
bool foundTrustedOverlay) {
|
||||
bool hasTrustedOverlay(change.trusted_overlay().is_trusted_overlay());
|
||||
if (hasTrustedOverlay && !foundTrustedOverlay) {
|
||||
foundTrustedOverlay = true;
|
||||
} else if (hasTrustedOverlay && foundTrustedOverlay) {
|
||||
[]() { FAIL(); }();
|
||||
}
|
||||
return foundTrustedOverlay;
|
||||
}
|
||||
|
||||
bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace,
|
||||
SurfaceChange::SurfaceChangeCase changeCase) {
|
||||
bool foundUpdate = false;
|
||||
|
@ -704,6 +722,9 @@ bool SurfaceInterceptorTest::surfaceUpdateFound(const Trace& trace,
|
|||
case SurfaceChange::SurfaceChangeCase::kShadowRadius:
|
||||
foundUpdate = shadowRadiusUpdateFound(change, foundUpdate);
|
||||
break;
|
||||
case SurfaceChange::SurfaceChangeCase::kTrustedOverlay:
|
||||
foundUpdate = trustedOverlayUpdateFound(change, foundUpdate);
|
||||
break;
|
||||
case SurfaceChange::SurfaceChangeCase::SURFACECHANGE_NOT_SET:
|
||||
break;
|
||||
}
|
||||
|
@ -897,6 +918,11 @@ TEST_F(SurfaceInterceptorTest, InterceptShadowRadiusUpdateWorks) {
|
|||
SurfaceChange::SurfaceChangeCase::kShadowRadius);
|
||||
}
|
||||
|
||||
TEST_F(SurfaceInterceptorTest, InterceptTrustedOverlayUpdateWorks) {
|
||||
captureTest(&SurfaceInterceptorTest::trustedOverlayUpdate,
|
||||
SurfaceChange::SurfaceChangeCase::kTrustedOverlay);
|
||||
}
|
||||
|
||||
TEST_F(SurfaceInterceptorTest, InterceptAllUpdatesWorks) {
|
||||
captureTest(&SurfaceInterceptorTest::runAllUpdates,
|
||||
&SurfaceInterceptorTest::assertAllUpdatesFound);
|
||||
|
|
Loading…
Reference in a new issue