Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions cmds/surfacereplayer/proto/src/trace.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ message SurfaceChange {
ReparentChildrenChange reparent_children = 20;
BackgroundBlurRadiusChange background_blur_radius = 21;
ShadowRadiusChange shadow_radius = 22;
TrustedOverlayChange trusted_overlay = 23;
}
}

Expand Down Expand Up @@ -208,4 +209,8 @@ message DetachChildrenChange {

message ShadowRadiusChange {
required float radius = 1;
}

message TrustedOverlayChange {
required float is_trusted_overlay = 1;
}
17 changes: 9 additions & 8 deletions include/input/InputWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ struct InputWindowInfo {
TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW + 32,
TYPE_DOCK_DIVIDER = FIRST_SYSTEM_WINDOW + 34,
TYPE_NOTIFICATION_SHADE = FIRST_SYSTEM_WINDOW + 40,
TYPE_TRUSTED_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 42,
LAST_SYSTEM_WINDOW = 2999,
};

enum {
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 Expand Up @@ -163,6 +163,12 @@ struct InputWindowInfo {
bool hasFocus = false;
bool hasWallpaper = false;
bool paused = false;
/* This flag is set when the window is of a trusted type that is allowed to silently
* overlay other windows for the purpose of implementing the secure views feature.
* Trusted overlays, such as IME windows, can partly obscure other windows without causing
* motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
*/
bool trustedOverlay = false;
int32_t ownerPid = -1;
int32_t ownerUid = -1;
int32_t inputFeatures = 0;
Expand All @@ -175,20 +181,15 @@ struct InputWindowInfo {
void addTouchableRegion(const Rect& region);

bool touchableRegionContainsPoint(int32_t x, int32_t y) const;
bool frameContainsPoint(int32_t x, int32_t y) const;

/* Returns true if the window is of a trusted type that is allowed to silently
* overlay other windows for the purpose of implementing the secure views feature.
* Trusted overlays, such as IME windows, can partly obscure other windows without causing
* motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
*/
bool isTrustedOverlay() const;
bool frameContainsPoint(int32_t x, int32_t y) const;

bool supportsSplitTouch() const;

bool overlaps(const InputWindowInfo* other) const;

status_t write(Parcel& output) const;

static InputWindowInfo read(const Parcel& from);
};

Expand Down
5 changes: 3 additions & 2 deletions libs/binder/IServiceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ sp<IBinder> ServiceManagerShim::getService(const String16& name) const

const bool isVendorService =
strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder") == 0;
const long timeout = uptimeMillis() + 5000;
const long timeout = 5000;
int64_t startTime = uptimeMillis();
// Vendor code can't access system properties
if (!gSystemBootCompleted && !isVendorService) {
#ifdef __ANDROID__
Expand All @@ -230,7 +231,7 @@ sp<IBinder> ServiceManagerShim::getService(const String16& name) const
const long sleepTime = gSystemBootCompleted ? 1000 : 100;

int n = 0;
while (uptimeMillis() < timeout) {
while (uptimeMillis() - startTime < timeout) {
n++;
ALOGI("Waiting for service '%s' on '%s'...", String8(name).string(),
ProcessState::self()->getDriverName().c_str());
Expand Down
8 changes: 5 additions & 3 deletions libs/binder/Parcel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2329,12 +2329,14 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
type == BINDER_TYPE_FD)) {
// We should never receive other types (eg BINDER_TYPE_FDA) as long as we don't support
// them in libbinder. If we do receive them, it probably means a kernel bug; try to
// recover gracefully by clearing out the objects, and releasing the objects we do
// know about.
// recover gracefully by clearing out the objects.
android_errorWriteLog(0x534e4554, "135930648");
android_errorWriteLog(0x534e4554, "203847542");
ALOGE("%s: unsupported type object (%" PRIu32 ") at offset %" PRIu64 "\n",
__func__, type, (uint64_t)offset);
releaseObjects();

// WARNING: callers of ipcSetDataReference need to make sure they
// don't rely on mObjectsSize in their release_func.
mObjectsSize = 0;
break;
}
Expand Down
45 changes: 42 additions & 3 deletions libs/binder/tests/binderLibTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ enum BinderLibTestTranscationCode {
BINDER_LIB_TEST_NOP_TRANSACTION_WAIT,
BINDER_LIB_TEST_GETPID,
BINDER_LIB_TEST_ECHO_VECTOR,
BINDER_LIB_TEST_REJECT_BUF,
BINDER_LIB_TEST_REJECT_OBJECTS,
};

pid_t start_server_process(int arg2, bool usePoll = false)
Expand Down Expand Up @@ -1137,14 +1137,53 @@ TEST_F(BinderLibTest, BufRejected) {
// And now, overwrite it with the buffer object
memcpy(parcelData, &obj, sizeof(obj));
data.setDataSize(sizeof(obj));
EXPECT_EQ(data.objectsCount(), 1);

status_t ret = server->transact(BINDER_LIB_TEST_REJECT_OBJECTS, data, &reply);

status_t ret = server->transact(BINDER_LIB_TEST_REJECT_BUF, data, &reply);
// Either the kernel should reject this transaction (if it's correct), but
// if it's not, the server implementation should return an error if it
// finds an object in the received Parcel.
EXPECT_NE(NO_ERROR, ret);
}

TEST_F(BinderLibTest, WeakRejected) {
Parcel data, reply;
sp<IBinder> server = addServer();
ASSERT_TRUE(server != nullptr);

sp<BBinder> binder = new BBinder();
wp<BBinder> wpBinder(binder);
flat_binder_object obj{
.hdr = {.type = BINDER_TYPE_WEAK_BINDER},
.flags = 0,
.binder = reinterpret_cast<uintptr_t>(wpBinder.get_refs()),
.cookie = reinterpret_cast<uintptr_t>(wpBinder.unsafe_get()),
};
data.setDataCapacity(1024);
// Write a bogus object at offset 0 to get an entry in the offset table
data.writeFileDescriptor(0);
EXPECT_EQ(data.objectsCount(), 1);
uint8_t *parcelData = const_cast<uint8_t *>(data.data());
// And now, overwrite it with the weak binder
memcpy(parcelData, &obj, sizeof(obj));
data.setDataSize(sizeof(obj));

// a previous bug caused other objects to be released an extra time, so we
// test with an object that libbinder will actually try to release
EXPECT_EQ(OK, data.writeStrongBinder(new BBinder()));

EXPECT_EQ(data.objectsCount(), 2);

// send it many times, since previous error was memory corruption, make it
// more likely that the server crashes
for (size_t i = 0; i < 100; i++) {
EXPECT_EQ(BAD_VALUE, server->transact(BINDER_LIB_TEST_REJECT_OBJECTS, data, &reply));
}

EXPECT_EQ(NO_ERROR, server->pingBinder());
}

class BinderLibTestService : public BBinder
{
public:
Expand Down Expand Up @@ -1443,7 +1482,7 @@ class BinderLibTestService : public BBinder
reply->writeUint64Vector(vector);
return NO_ERROR;
}
case BINDER_LIB_TEST_REJECT_BUF: {
case BINDER_LIB_TEST_REJECT_OBJECTS: {
return data.objectsCount() == 0 ? BAD_VALUE : NO_ERROR;
}
default:
Expand Down
11 changes: 10 additions & 1 deletion 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_defaults {
name: "libgui_defaults",

Expand All @@ -38,6 +46,7 @@ cc_defaults {
defaults: ["libgui_bufferqueue-defaults"],

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

Expand Down Expand Up @@ -286,4 +295,4 @@ cc_library_shared {
defaults: ["libgui_defaults"]
}

subdirs = ["tests"]
subdirs = ["tests"]
36 changes: 36 additions & 0 deletions libs/gui/LayerState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ status_t layer_state_t::write(Parcel& output) const
output.writeFloat(frameRate);
output.writeByte(frameRateCompatibility);
output.writeUint32(fixedTransformHint);
output.writeBool(isTrustedOverlay);
output.writeUint32(static_cast<uint32_t>(dropInputMode));
return NO_ERROR;
}

Expand Down Expand Up @@ -200,6 +202,11 @@ status_t layer_state_t::read(const Parcel& input)
frameRate = input.readFloat();
frameRateCompatibility = input.readByte();
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 @@ -269,6 +276,27 @@ void DisplayState::merge(const DisplayState& other) {
}
}

void DisplayState::sanitize(bool privileged) {
if (what & DisplayState::eLayerStackChanged) {
if (!privileged) {
what &= ~DisplayState::eLayerStackChanged;
ALOGE("Stripped attempt to set eLayerStackChanged in sanitize");
}
}
if (what & DisplayState::eDisplayProjectionChanged) {
if (!privileged) {
what &= ~DisplayState::eDisplayProjectionChanged;
ALOGE("Stripped attempt to set eDisplayProjectionChanged in sanitize");
}
}
if (what & DisplayState::eSurfaceChanged) {
if (!privileged) {
what &= ~DisplayState::eSurfaceChanged;
ALOGE("Stripped attempt to set eSurfaceChanged in sanitize");
}
}
}

void layer_state_t::merge(const layer_state_t& other) {
if (other.what & ePositionChanged) {
what |= ePositionChanged;
Expand Down Expand Up @@ -439,6 +467,14 @@ void layer_state_t::merge(const layer_state_t& other) {
what |= eFixedTransformHintChanged;
fixedTransformHint = other.fixedTransformHint;
}
if (other.what & eTrustedOverlayChanged) {
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
28 changes: 28 additions & 0 deletions libs/gui/SurfaceComposerClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1484,6 +1484,34 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixed
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::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,
}

15 changes: 14 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 @@ -105,6 +106,8 @@ struct layer_state_t {
eBackgroundBlurRadiusChanged = 0x80'00000000,
eProducerDisconnect = 0x100'00000000,
eFixedTransformHintChanged = 0x200'00000000,
eTrustedOverlayChanged = 0x400'00000000,
eDropInputModeChanged = 0x8000'00000000,
};

layer_state_t()
Expand Down Expand Up @@ -139,7 +142,9 @@ struct layer_state_t {
frameRateSelectionPriority(-1),
frameRate(0.0f),
frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
fixedTransformHint(ui::Transform::ROT_INVALID) {
fixedTransformHint(ui::Transform::ROT_INVALID),
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 @@ -237,6 +242,13 @@ struct layer_state_t {
// a buffer of a different size. -1 means the transform hint is not set,
// otherwise the value will be a valid ui::Rotation.
ui::Transform::RotationFlags fixedTransformHint;

// 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 All @@ -255,6 +267,7 @@ struct DisplayState {

DisplayState();
void merge(const DisplayState& other);
void sanitize(bool privileged);

uint32_t what;
sp<IBinder> token;
Expand Down
Loading