Skip to content

Commit

Permalink
SurfaceControl: Add setDropInputMode api
Browse files Browse the repository at this point in the history
Introduces an API to drop input events on this SurfaceControl. This
policy will be inherited by its children. The caller must hold the
ACCESS_SURFACE_FLINGER permission.

Options include:
ALL: SurfaceControl and its children will not receive any
input regardless of whether it has a valid input channel.

These policies are used to enable features that allow for a less trusted
interaction model between apps. See the bug for more details.

Note: this backport does not include the OBSCURED option since its
not needed for the security fix.

Test: atest libgui_test InputDispatcherDropInputFeatureTest
Bug: 197296414

Merged-In: I443741d5ab51a45d37fb865f11c433c436d96c1e
Change-Id: I443741d5ab51a45d37fb865f11c433c436d96c1e
  • Loading branch information
Vishnu Nair committed Feb 16, 2022
1 parent eb59e47 commit 122c4d2
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 3 deletions.
1 change: 1 addition & 0 deletions include/input/InputWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct InputWindowInfo {
INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES = 0x00000001,
INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002,
INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
INPUT_FEATURE_DROP_INPUT = 0x00000008,
};

/* These values are filled in by the WM and passed through SurfaceFlinger
Expand Down
9 changes: 9 additions & 0 deletions libs/gui/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ cc_library_headers {
min_sdk_version: "29",
}

// AIDL files that should be exposed to java
filegroup {
name: "guiconstants_aidl",
srcs: [
"android/gui/DropInputMode.aidl",
],
}

cc_library_shared {
name: "libgui",
vendor_available: false,
Expand All @@ -41,6 +49,7 @@ cc_library_shared {
defaults: ["libgui_bufferqueue-defaults"],

srcs: [
":guiconstants_aidl",
":framework_native_aidl",
":libgui_bufferqueue_sources",

Expand Down
9 changes: 8 additions & 1 deletion libs/gui/LayerState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ status_t layer_state_t::write(Parcel& output) const
output.writeByte(frameRateCompatibility);
output.writeUint32(fixedTransformHint);
output.writeBool(isTrustedOverlay);

output.writeUint32(static_cast<uint32_t>(dropInputMode));
return NO_ERROR;
}

Expand Down Expand Up @@ -204,6 +204,9 @@ status_t layer_state_t::read(const Parcel& input)
fixedTransformHint = static_cast<ui::Transform::RotationFlags>(input.readUint32());
isTrustedOverlay = input.readBool();

uint32_t mode;
mode = input.readUint32();
dropInputMode = static_cast<gui::DropInputMode>(mode);
return NO_ERROR;
}

Expand Down Expand Up @@ -447,6 +450,10 @@ void layer_state_t::merge(const layer_state_t& other) {
what |= eTrustedOverlayChanged;
isTrustedOverlay = other.isTrustedOverlay;
}
if (other.what & eDropInputModeChanged) {
what |= eDropInputModeChanged;
dropInputMode = other.dropInputMode;
}
if ((other.what & what) != other.what) {
ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
"other.what=0x%" PRIu64 " what=0x%" PRIu64,
Expand Down
15 changes: 15 additions & 0 deletions libs/gui/SurfaceComposerClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1497,6 +1497,21 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrust
return *this;
}

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDropInputMode(
const sp<SurfaceControl>& sc, gui::DropInputMode mode) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}

s->what |= layer_state_t::eDropInputModeChanged;
s->dropInputMode = mode;

registerSurfaceControlForCallback(sc);
return *this;
}

// ---------------------------------------------------------------------------

DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
Expand Down
40 changes: 40 additions & 0 deletions libs/gui/android/gui/DropInputMode.aidl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Copyright (c) 2022, 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.
*/

package android.gui;


/**
* Input event drop modes: Input event drop options for windows and its children.
*
* @hide
*/
@Backing(type="int")
enum DropInputMode {
/**
* Default mode, input events are sent to the target as usual.
*/
NONE,

/**
* Window and its children will not receive any input even if it has a valid input channel.
* Touches and keys will be dropped. If a window is focused, it will remain focused but will
* not receive any keys. If the window has a touchable region and is the target of an input
* event, the event will be dropped and will not go to the window behind. ref: b/197296414
*/
ALL,
}

8 changes: 7 additions & 1 deletion libs/gui/include/gui/LayerState.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <gui/ITransactionCompletedListener.h>
#include <math/mat4.h>

#include <android/gui/DropInputMode.h>
#ifndef NO_INPUT
#include <input/InputWindow.h>
#endif
Expand Down Expand Up @@ -106,6 +107,7 @@ struct layer_state_t {
eProducerDisconnect = 0x100'00000000,
eFixedTransformHintChanged = 0x200'00000000,
eTrustedOverlayChanged = 0x400'00000000,
eDropInputModeChanged = 0x8000'00000000,
};

layer_state_t()
Expand Down Expand Up @@ -141,7 +143,8 @@ struct layer_state_t {
frameRate(0.0f),
frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
fixedTransformHint(ui::Transform::ROT_INVALID),
isTrustedOverlay(false) {
isTrustedOverlay(false),
dropInputMode(gui::DropInputMode::NONE) {
matrix.dsdx = matrix.dtdy = 1.0f;
matrix.dsdy = matrix.dtdx = 0.0f;
hdrMetadata.validTypes = 0;
Expand Down Expand Up @@ -243,6 +246,9 @@ struct layer_state_t {
// An inherited state that indicates that this surface control and its children
// should be trusted for input occlusion detection purposes
bool isTrustedOverlay;

// Force inputflinger to drop all input events for the layer and its children.
gui::DropInputMode dropInputMode;
};

struct ComposerState {
Expand Down
3 changes: 2 additions & 1 deletion libs/gui/include/gui/SurfaceComposerClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,8 @@ class SurfaceComposerClient : public RefBase

// Sets that this surface control and its children are trusted overlays for input
Transaction& setTrustedOverlay(const sp<SurfaceControl>& sc, bool isTrustedOverlay);


Transaction& setDropInputMode(const sp<SurfaceControl>& sc, gui::DropInputMode mode);
status_t setDisplaySurface(const sp<IBinder>& token,
const sp<IGraphicBufferProducer>& bufferProducer);

Expand Down
11 changes: 11 additions & 0 deletions services/surfaceflinger/Layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ Layer::Layer(const LayerCreationArgs& args)
mCurrentState.treeHasFrameRateVote = false;
mCurrentState.fixedTransformHint = ui::Transform::ROT_INVALID;
mCurrentState.isTrustedOverlay = false;
mCurrentState.dropInputMode = gui::DropInputMode::NONE;

if (args.flags & ISurfaceComposerClient::eNoColorFill) {
// Set an invalid color so there is no color fill.
Expand Down Expand Up @@ -2645,6 +2646,16 @@ Layer::FrameRateCompatibility Layer::FrameRate::convertCompatibility(int8_t comp
}
}

bool Layer::setDropInputMode(gui::DropInputMode mode) {
if (mCurrentState.dropInputMode == mode) {
return false;
}
mCurrentState.dropInputMode = mode;
mCurrentState.modified = true;
mCurrentState.inputInfoChanged = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
// ---------------------------------------------------------------------------

}; // namespace android
Expand Down
5 changes: 5 additions & 0 deletions services/surfaceflinger/Layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#pragma once

#include <android/gui/DropInputMode.h>
#include <compositionengine/LayerFE.h>
#include <gui/BufferQueue.h>
#include <gui/ISurfaceComposerClient.h>
Expand Down Expand Up @@ -282,6 +283,8 @@ class Layer : public virtual RefBase, compositionengine::LayerFE {

// Whether or not this layer is a trusted overlay for input
bool isTrustedOverlay;

gui::DropInputMode dropInputMode;
};

explicit Layer(const LayerCreationArgs& args);
Expand Down Expand Up @@ -410,6 +413,8 @@ class Layer : public virtual RefBase, compositionengine::LayerFE {
bool setShadowRadius(float shadowRadius);
virtual bool setFrameRateSelectionPriority(int32_t priority);
virtual bool setFixedTransformHint(ui::Transform::RotationFlags fixedTransformHint);
bool setDropInputMode(gui::DropInputMode);

// If the variable is not set on the layer, it traverses up the tree to inherit the frame
// rate priority from its parent.
virtual int32_t getFrameRateSelectionPriority() const;
Expand Down
9 changes: 9 additions & 0 deletions services/surfaceflinger/SurfaceFlinger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3867,6 +3867,15 @@ uint32_t SurfaceFlinger::setClientStateLocked(
ALOGE("Attempt to set trusted overlay without permission ACCESS_SURFACE_FLINGER");
}
}
if (what & layer_state_t::eDropInputModeChanged) {
if (privileged) {
if (layer->setDropInputMode(s.dropInputMode)) {
flags |= eTraversalNeeded;
}
} else {
ALOGE("Attempt to update InputPolicyFlags without permission ACCESS_SURFACE_FLINGER");
}
}
// This has to happen after we reparent children because when we reparent to null we remove
// child layers from current state and remove its relative z. If the children are reparented in
// the same transaction, then we have to make sure we reparent the children first so we do not
Expand Down

0 comments on commit 122c4d2

Please sign in to comment.