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:
Winson Chung 2021-06-29 15:42:56 -07:00
parent 5a68a6cfe0
commit a30f7c9974
14 changed files with 113 additions and 0 deletions

View file

@ -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;
}

View file

@ -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");

View file

@ -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;

View file

@ -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;

View file

@ -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.

View file

@ -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()) {

View file

@ -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.

View file

@ -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;

View file

@ -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");
}

View file

@ -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);

View file

@ -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());

View file

@ -109,6 +109,7 @@ public:
int32_t queuedFrames;
bool refreshPending;
bool isProtected;
bool isTrustedOverlay;
float cornerRadius;
int backgroundBlurRadius;
LayerMetadata metadata;

View file

@ -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 {

View file

@ -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);