Merge "Notify policy of untrusted touch for toast"
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index eb1bbd9..b821578 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -946,6 +946,33 @@
auto scope_guard = android::base::make_scope_guard(deleter);
+ if (storageFlags & FLAG_STORAGE_DE) {
+ auto from = create_data_user_de_package_path(volume_uuid, user, package_name);
+ auto to = create_data_misc_de_rollback_path(volume_uuid, user, snapshotId);
+ auto rollback_package_path = create_data_misc_de_rollback_package_path(volume_uuid, user,
+ snapshotId, package_name);
+
+ int rc = create_dir_if_needed(to.c_str(), kRollbackFolderMode);
+ if (rc != 0) {
+ return error(rc, "Failed to create folder " + to);
+ }
+
+ rc = delete_dir_contents(rollback_package_path, true /* ignore_if_missing */);
+ if (rc != 0) {
+ return error(rc, "Failed clearing existing snapshot " + rollback_package_path);
+ }
+
+ // Check if we have data to copy.
+ if (access(from.c_str(), F_OK) == 0) {
+ rc = copy_directory_recursive(from.c_str(), to.c_str());
+ }
+ if (rc != 0) {
+ res = error(rc, "Failed copying " + from + " to " + to);
+ clear_de_on_exit = true;
+ return res;
+ }
+ }
+
// The app may not have any data at all, in which case it's OK to skip here.
auto from_ce = create_data_user_ce_package_path(volume_uuid, user, package_name);
if (access(from_ce.c_str(), F_OK) != 0) {
@@ -971,30 +998,6 @@
LOG(WARNING) << "Failed to clear code_cache of app " << packageName;
}
- if (storageFlags & FLAG_STORAGE_DE) {
- auto from = create_data_user_de_package_path(volume_uuid, user, package_name);
- auto to = create_data_misc_de_rollback_path(volume_uuid, user, snapshotId);
- auto rollback_package_path = create_data_misc_de_rollback_package_path(volume_uuid, user,
- snapshotId, package_name);
-
- int rc = create_dir_if_needed(to.c_str(), kRollbackFolderMode);
- if (rc != 0) {
- return error(rc, "Failed to create folder " + to);
- }
-
- rc = delete_dir_contents(rollback_package_path, true /* ignore_if_missing */);
- if (rc != 0) {
- return error(rc, "Failed clearing existing snapshot " + rollback_package_path);
- }
-
- rc = copy_directory_recursive(from.c_str(), to.c_str());
- if (rc != 0) {
- res = error(rc, "Failed copying " + from + " to " + to);
- clear_de_on_exit = true;
- return res;
- }
- }
-
if (storageFlags & FLAG_STORAGE_CE) {
auto from = create_data_user_ce_package_path(volume_uuid, user, package_name);
auto to = create_data_misc_ce_rollback_path(volume_uuid, user, snapshotId);
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 9508de0..4610ba9 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -74,12 +74,12 @@
AIBinder::~AIBinder() {}
std::optional<bool> AIBinder::associateClassInternal(const AIBinder_Class* clazz,
- const String8& newDescriptor, bool set) {
+ const String16& newDescriptor, bool set) {
std::lock_guard<std::mutex> lock(mClazzMutex);
if (mClazz == clazz) return true;
if (mClazz != nullptr) {
- String8 currentDescriptor(mClazz->getInterfaceDescriptor());
+ const String16& currentDescriptor = mClazz->getInterfaceDescriptor();
if (newDescriptor == currentDescriptor) {
LOG(ERROR) << __func__ << ": Class descriptors '" << currentDescriptor
<< "' match during associateClass, but they are different class objects. "
@@ -88,8 +88,7 @@
LOG(ERROR) << __func__
<< ": Class cannot be associated on object which already has a class. "
"Trying to associate to '"
- << newDescriptor.c_str() << "' but already set to '"
- << currentDescriptor.c_str() << "'.";
+ << newDescriptor << "' but already set to '" << currentDescriptor << "'.";
}
// always a failure because we know mClazz != clazz
@@ -108,21 +107,21 @@
bool AIBinder::associateClass(const AIBinder_Class* clazz) {
if (clazz == nullptr) return false;
- String8 newDescriptor(clazz->getInterfaceDescriptor());
+ const String16& newDescriptor = clazz->getInterfaceDescriptor();
auto result = associateClassInternal(clazz, newDescriptor, false);
if (result.has_value()) return *result;
CHECK(asABpBinder() != nullptr); // ABBinder always has a descriptor
- String8 descriptor(getBinder()->getInterfaceDescriptor());
+ const String16& descriptor = getBinder()->getInterfaceDescriptor();
if (descriptor != newDescriptor) {
if (getBinder()->isBinderAlive()) {
- LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str()
- << "' but descriptor is actually '" << descriptor.c_str() << "'.";
+ LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor
+ << "' but descriptor is actually '" << descriptor << "'.";
} else {
// b/155793159
- LOG(ERROR) << __func__ << ": Cannot associate class '" << newDescriptor.c_str()
+ LOG(ERROR) << __func__ << ": Cannot associate class '" << newDescriptor
<< "' to dead binder.";
}
return false;
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index bf27046..0fa47c6 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -54,7 +54,7 @@
private:
std::optional<bool> associateClassInternal(const AIBinder_Class* clazz,
- const ::android::String8& newDescriptor, bool set);
+ const ::android::String16& newDescriptor, bool set);
// AIBinder instance is instance of this class for a local object. In order to transact on a
// remote object, this also must be set for simplicity (although right now, only the
diff --git a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
index 439b019..18877af 100644
--- a/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_auto_utils.h
@@ -44,9 +44,14 @@
class SpAIBinder {
public:
/**
+ * Default constructor.
+ */
+ SpAIBinder() : mBinder(nullptr) {}
+
+ /**
* Takes ownership of one strong refcount of binder.
*/
- explicit SpAIBinder(AIBinder* binder = nullptr) : mBinder(binder) {}
+ explicit SpAIBinder(AIBinder* binder) : mBinder(binder) {}
/**
* Convenience operator for implicitly constructing an SpAIBinder from nullptr. This is not
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index a814362..5e7a7ec 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -49,13 +49,13 @@
status_t createSurface(const String8& name, uint32_t width, uint32_t height, PixelFormat format,
uint32_t flags, const sp<IBinder>& parent, LayerMetadata metadata,
- sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, int32_t* outId,
- uint32_t* outTransformHint) override {
+ sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,
+ int32_t* outLayerId, uint32_t* outTransformHint) override {
return callRemote<decltype(&ISurfaceComposerClient::createSurface)>(Tag::CREATE_SURFACE,
name, width, height,
format, flags, parent,
std::move(metadata),
- handle, gbp, outId,
+ handle, gbp, outLayerId,
outTransformHint);
}
@@ -63,14 +63,14 @@
PixelFormat format, uint32_t flags,
const sp<IGraphicBufferProducer>& parent,
LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outId,
+ sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
uint32_t* outTransformHint) override {
return callRemote<decltype(
&ISurfaceComposerClient::createWithSurfaceParent)>(Tag::CREATE_WITH_SURFACE_PARENT,
name, width, height, format,
flags, parent,
std::move(metadata), handle, gbp,
- outId, outTransformHint);
+ outLayerId, outTransformHint);
}
status_t clearLayerFrameStats(const sp<IBinder>& handle) const override {
@@ -86,10 +86,10 @@
}
status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle,
- int32_t* outId) override {
+ int32_t* outLayerId) override {
return callRemote<decltype(&ISurfaceComposerClient::mirrorSurface)>(Tag::MIRROR_SURFACE,
mirrorFromHandle,
- outHandle, outId);
+ outHandle, outLayerId);
}
};
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index bde73ba..8594ab3 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -592,19 +592,20 @@
SAFE_PARCEL(output.writeFloat, frameScale);
SAFE_PARCEL(output.writeBool, captureSecureLayers);
SAFE_PARCEL(output.writeInt32, uid);
- SAFE_PARCEL(output.writeBool, useRGBColorSpace);
+ SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(dataspace));
return NO_ERROR;
}
status_t CaptureArgs::read(const Parcel& input) {
- int32_t format = 0;
- SAFE_PARCEL(input.readInt32, &format);
- pixelFormat = static_cast<ui::PixelFormat>(format);
+ int32_t value = 0;
+ SAFE_PARCEL(input.readInt32, &value);
+ pixelFormat = static_cast<ui::PixelFormat>(value);
SAFE_PARCEL(input.read, sourceCrop);
SAFE_PARCEL(input.readFloat, &frameScale);
SAFE_PARCEL(input.readBool, &captureSecureLayers);
SAFE_PARCEL(input.readInt32, &uid);
- SAFE_PARCEL(input.readBool, &useRGBColorSpace);
+ SAFE_PARCEL(input.readInt32, &value);
+ dataspace = static_cast<ui::Dataspace>(value);
return NO_ERROR;
}
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
index f3fcebe..4a92f53 100644
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ b/libs/gui/include/gui/ISurfaceComposerClient.h
@@ -58,7 +58,7 @@
virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags, const sp<IBinder>& parent,
LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outId,
+ sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
uint32_t* outTransformHint) = 0;
/*
@@ -68,7 +68,7 @@
PixelFormat format, uint32_t flags,
const sp<IGraphicBufferProducer>& parent,
LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outId,
+ sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
uint32_t* outTransformHint) = 0;
/*
@@ -82,7 +82,7 @@
virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const = 0;
virtual status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle,
- int32_t* outId) = 0;
+ int32_t* outLayerId) = 0;
};
class BnSurfaceComposerClient : public SafeBnInterface<ISurfaceComposerClient> {
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index fed0ef3..ff395ec 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -312,12 +312,12 @@
float frameScale{1};
bool captureSecureLayers{false};
int32_t uid{UNSET_UID};
- // True to force using RGB color as the capture result.
+ // Force capture to be in a color space. If the value is ui::Dataspace::UNKNOWN, the captured
+ // result will be in the display's colorspace.
// The display may use non-RGB dataspace (ex. displayP3) that could cause pixel data could be
- // different from RGB (byte per color), and failed when checking colors.
- // NOTE: This should only be used for testing since in normal cases, we want the screen
- // capture's colorspace to match the display's colorspace
- bool useRGBColorSpace{false};
+ // different from SRGB (byte per color), and failed when checking colors in tests.
+ // NOTE: In normal cases, we want the screen to be captured in display's colorspace.
+ ui::Dataspace dataspace = ui::Dataspace::UNKNOWN;
virtual status_t write(Parcel& output) const;
virtual status_t read(const Parcel& input);
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index b442700..d8c3e6f 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -17,9 +17,11 @@
filegroup {
name: "inputconstants_aidl",
srcs: [
- "android/os/IInputConstants.aidl",
- "android/os/TouchOcclusionMode.aidl",
"android/os/BlockUntrustedTouchesMode.aidl",
+ "android/os/IInputConstants.aidl",
+ "android/os/InputEventInjectionResult.aidl",
+ "android/os/InputEventInjectionSync.aidl",
+ "android/os/TouchOcclusionMode.aidl",
],
}
@@ -73,6 +75,8 @@
"android/FocusRequest.aidl",
"android/InputApplicationInfo.aidl",
"android/os/IInputConstants.aidl",
+ "android/os/InputEventInjectionResult.aidl",
+ "android/os/InputEventInjectionSync.aidl",
"android/os/TouchOcclusionMode.aidl",
"android/os/BlockUntrustedTouchesMode.aidl",
"android/os/IInputFlinger.aidl",
diff --git a/libs/input/android/os/InputEventInjectionResult.aidl b/libs/input/android/os/InputEventInjectionResult.aidl
new file mode 100644
index 0000000..34f10ec
--- /dev/null
+++ b/libs/input/android/os/InputEventInjectionResult.aidl
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2020, 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.os;
+
+/**
+ * Constants used to report the outcome of input event injection.
+ *
+ * @hide
+ */
+@Backing(type="int")
+enum InputEventInjectionResult {
+ /* (INTERNAL USE ONLY) Specifies that injection is pending and its outcome is unknown. */
+ PENDING = -1,
+
+ /* Injection succeeded. */
+ SUCCEEDED = 0,
+
+ /* Injection failed because the injector did not have permission to inject
+ * into the application with input focus. */
+ PERMISSION_DENIED = 1,
+
+ /* Injection failed because there were no available input targets. */
+ FAILED = 2,
+
+ /* Injection failed due to a timeout. */
+ TIMED_OUT = 3,
+}
diff --git a/libs/input/android/os/InputEventInjectionSync.aidl b/libs/input/android/os/InputEventInjectionSync.aidl
new file mode 100644
index 0000000..95d24cb
--- /dev/null
+++ b/libs/input/android/os/InputEventInjectionSync.aidl
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2020, 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.os;
+
+/**
+ * Constants used to specify the input event injection synchronization mode.
+ *
+ * @hide
+ */
+@Backing(type="int")
+enum InputEventInjectionSync {
+ /* Injection is asynchronous and is assumed always to be successful. */
+ NONE = 0,
+
+ /* Waits for previous events to be dispatched so that the input dispatcher can determine
+ * whether input event injection willbe permitted based on the current input focus.
+ * Does not wait for the input event to finish processing. */
+ WAIT_FOR_RESULT = 1,
+
+ /* Waits for the input event to be completely processed. */
+ WAIT_FOR_FINISHED = 2,
+}
diff --git a/libs/ui/include/ui/DisplayId.h b/libs/ui/include/ui/DisplayId.h
index 9eb5483..f196ab9 100644
--- a/libs/ui/include/ui/DisplayId.h
+++ b/libs/ui/include/ui/DisplayId.h
@@ -17,13 +17,20 @@
#pragma once
#include <cstdint>
-#include <functional>
+#include <optional>
#include <string>
namespace android {
// ID of a physical or a virtual display. This class acts as a type safe wrapper around uint64_t.
+// The encoding of the ID is type-specific for bits 0 to 61.
struct DisplayId {
+ // Flag indicating that the display is virtual.
+ static constexpr uint64_t FLAG_VIRTUAL = 1ULL << 63;
+
+ // Flag indicating that the ID is stable across reboots.
+ static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
+
// TODO(b/162612135) Remove default constructor
DisplayId() = default;
constexpr DisplayId(const DisplayId&) = default;
@@ -51,8 +58,12 @@
// DisplayId of a physical display, such as the internal display or externally connected display.
struct PhysicalDisplayId : DisplayId {
- // Flag indicating that the ID is stable across reboots.
- static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
+ static constexpr std::optional<PhysicalDisplayId> tryCast(DisplayId id) {
+ if (id.value & FLAG_VIRTUAL) {
+ return std::nullopt;
+ }
+ return {PhysicalDisplayId(id)};
+ }
// Returns a stable ID based on EDID information.
static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId,
@@ -69,8 +80,8 @@
// TODO(b/162612135) Remove default constructor
PhysicalDisplayId() = default;
+ // TODO(b/162612135) Remove constructor
explicit constexpr PhysicalDisplayId(uint64_t id) : DisplayId(id) {}
- explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other.value) {}
constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); }
@@ -81,10 +92,82 @@
uint32_t modelHash)
: DisplayId(flags | (static_cast<uint64_t>(manufacturerId) << 40) |
(static_cast<uint64_t>(modelHash) << 8) | port) {}
+
+ explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other) {}
};
static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));
+struct VirtualDisplayId : DisplayId {
+ using BaseId = uint32_t;
+ // Flag indicating that this virtual display is backed by the GPU.
+ static constexpr uint64_t FLAG_GPU = 1ULL << 61;
+
+ static constexpr std::optional<VirtualDisplayId> tryCast(DisplayId id) {
+ if (id.value & FLAG_VIRTUAL) {
+ return {VirtualDisplayId(id)};
+ }
+ return std::nullopt;
+ }
+
+protected:
+ constexpr VirtualDisplayId(uint64_t flags, BaseId baseId)
+ : DisplayId(DisplayId::FLAG_VIRTUAL | flags | baseId) {}
+
+ explicit constexpr VirtualDisplayId(DisplayId other) : DisplayId(other) {}
+};
+
+struct HalVirtualDisplayId : VirtualDisplayId {
+ explicit constexpr HalVirtualDisplayId(BaseId baseId) : VirtualDisplayId(0, baseId) {}
+
+ static constexpr std::optional<HalVirtualDisplayId> tryCast(DisplayId id) {
+ if ((id.value & FLAG_VIRTUAL) && !(id.value & VirtualDisplayId::FLAG_GPU)) {
+ return {HalVirtualDisplayId(id)};
+ }
+ return std::nullopt;
+ }
+
+private:
+ explicit constexpr HalVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
+};
+
+struct GpuVirtualDisplayId : VirtualDisplayId {
+ explicit constexpr GpuVirtualDisplayId(BaseId baseId)
+ : VirtualDisplayId(VirtualDisplayId::FLAG_GPU, baseId) {}
+
+ static constexpr std::optional<GpuVirtualDisplayId> tryCast(DisplayId id) {
+ if ((id.value & FLAG_VIRTUAL) && (id.value & VirtualDisplayId::FLAG_GPU)) {
+ return {GpuVirtualDisplayId(id)};
+ }
+ return std::nullopt;
+ }
+
+private:
+ explicit constexpr GpuVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
+};
+
+// HalDisplayId is the ID of a display which is managed by HWC.
+// PhysicalDisplayId and HalVirtualDisplayId are implicitly convertible to HalDisplayId.
+struct HalDisplayId : DisplayId {
+ constexpr HalDisplayId(HalVirtualDisplayId other) : DisplayId(other) {}
+ constexpr HalDisplayId(PhysicalDisplayId other) : DisplayId(other) {}
+
+ static constexpr std::optional<HalDisplayId> tryCast(DisplayId id) {
+ if (GpuVirtualDisplayId::tryCast(id)) {
+ return std::nullopt;
+ }
+ return {HalDisplayId(id)};
+ }
+
+private:
+ explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {}
+};
+
+static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t));
+static_assert(sizeof(HalVirtualDisplayId) == sizeof(uint64_t));
+static_assert(sizeof(GpuVirtualDisplayId) == sizeof(uint64_t));
+static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
+
} // namespace android
namespace std {
@@ -99,4 +182,13 @@
template <>
struct hash<android::PhysicalDisplayId> : hash<android::DisplayId> {};
+template <>
+struct hash<android::HalVirtualDisplayId> : hash<android::DisplayId> {};
+
+template <>
+struct hash<android::GpuVirtualDisplayId> : hash<android::DisplayId> {};
+
+template <>
+struct hash<android::HalDisplayId> : hash<android::DisplayId> {};
+
} // namespace std
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 032dd4c..d005ce8 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -29,6 +29,13 @@
}
cc_test {
+ name: "DisplayId_test",
+ shared_libs: ["libui"],
+ srcs: ["DisplayId_test.cpp"],
+ cflags: ["-Wall", "-Werror"],
+}
+
+cc_test {
name: "FlattenableHelpers_test",
shared_libs: ["libui"],
srcs: ["FlattenableHelpers_test.cpp"],
diff --git a/libs/ui/tests/DisplayId_test.cpp b/libs/ui/tests/DisplayId_test.cpp
new file mode 100644
index 0000000..1d908b8
--- /dev/null
+++ b/libs/ui/tests/DisplayId_test.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#include <ui/DisplayId.h>
+
+#include <gtest/gtest.h>
+
+namespace android::ui {
+
+TEST(DisplayIdTest, createPhysicalIdFromEdid) {
+ constexpr uint8_t port = 1;
+ constexpr uint16_t manufacturerId = 13;
+ constexpr uint32_t modelHash = 42;
+ PhysicalDisplayId id = PhysicalDisplayId::fromEdid(port, manufacturerId, modelHash);
+ EXPECT_EQ(port, id.getPort());
+ EXPECT_EQ(manufacturerId, id.getManufacturerId());
+ EXPECT_FALSE(VirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
+ EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
+ EXPECT_TRUE(HalDisplayId::tryCast(id));
+}
+
+TEST(DisplayIdTest, createPhysicalIdFromPort) {
+ constexpr uint8_t port = 3;
+ PhysicalDisplayId id = PhysicalDisplayId::fromPort(port);
+ EXPECT_EQ(port, id.getPort());
+ EXPECT_FALSE(VirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
+ EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
+ EXPECT_TRUE(HalDisplayId::tryCast(id));
+}
+
+TEST(DisplayIdTest, createGpuVirtualId) {
+ GpuVirtualDisplayId id(42);
+ EXPECT_TRUE(VirtualDisplayId::tryCast(id));
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
+ EXPECT_FALSE(HalDisplayId::tryCast(id));
+}
+
+TEST(DisplayIdTest, createHalVirtualId) {
+ HalVirtualDisplayId id(42);
+ EXPECT_TRUE(VirtualDisplayId::tryCast(id));
+ EXPECT_TRUE(HalVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
+ EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
+ EXPECT_TRUE(HalDisplayId::tryCast(id));
+}
+
+} // namespace android::ui
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index b00364d..c2d165e 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -19,6 +19,9 @@
#include <binder/Binder.h>
#include "../dispatcher/InputDispatcher.h"
+using android::os::InputEventInjectionResult;
+using android::os::InputEventInjectionSync;
+
namespace android::inputdispatcher {
// An arbitrary device id.
@@ -288,13 +291,13 @@
MotionEvent event = generateMotionEvent();
// Send ACTION_DOWN
dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, INJECT_EVENT_TIMEOUT,
+ InputEventInjectionSync::NONE, INJECT_EVENT_TIMEOUT,
POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
// Send ACTION_UP
event.setAction(AMOTION_EVENT_ACTION_UP);
dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, INJECT_EVENT_TIMEOUT,
+ InputEventInjectionSync::NONE, INJECT_EVENT_TIMEOUT,
POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
window->consumeEvent();
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index 4328e03..34fa239 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -70,12 +70,6 @@
releaseInjectionState();
}
-std::string EventEntry::getDescription() const {
- std::string result;
- appendDescription(result);
- return result;
-}
-
void EventEntry::release() {
refCount -= 1;
if (refCount == 0) {
@@ -99,8 +93,8 @@
ConfigurationChangedEntry::~ConfigurationChangedEntry() {}
-void ConfigurationChangedEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
+std::string ConfigurationChangedEntry::getDescription() const {
+ return StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
}
// --- DeviceResetEntry ---
@@ -110,8 +104,8 @@
DeviceResetEntry::~DeviceResetEntry() {}
-void DeviceResetEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
+std::string DeviceResetEntry::getDescription() const {
+ return StringPrintf("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x", deviceId, policyFlags);
}
// --- FocusEntry ---
@@ -126,8 +120,8 @@
FocusEntry::~FocusEntry() {}
-void FocusEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
+std::string FocusEntry::getDescription() const {
+ return StringPrintf("FocusEvent(hasFocus=%s)", hasFocus ? "true" : "false");
}
// --- KeyEntry ---
@@ -153,12 +147,11 @@
KeyEntry::~KeyEntry() {}
-void KeyEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("KeyEvent");
+std::string KeyEntry::getDescription() const {
if (!GetBoolProperty("ro.debuggable", false)) {
- return;
+ return "KeyEvent";
}
- msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
+ return StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
"flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
"repeatCount=%d), policyFlags=0x%08x",
deviceId, source, displayId, KeyEvent::actionToString(action), flags,
@@ -212,12 +205,12 @@
MotionEntry::~MotionEntry() {}
-void MotionEntry::appendDescription(std::string& msg) const {
- msg += StringPrintf("MotionEvent");
+std::string MotionEntry::getDescription() const {
if (!GetBoolProperty("ro.debuggable", false)) {
- return;
+ return "MotionEvent";
}
- msg += StringPrintf("(deviceId=%d, source=0x%08x, displayId=%" PRId32
+ std::string msg;
+ msg += StringPrintf("MotionEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32
", action=%s, actionButton=0x%08x, flags=0x%08x, metaState=0x%08x, "
"buttonState=0x%08x, "
"classification=%s, edgeFlags=0x%08x, xPrecision=%.1f, yPrecision=%.1f, "
@@ -235,6 +228,7 @@
pointerCoords[i].getY());
}
msg += StringPrintf("]), policyFlags=0x%08x", policyFlags);
+ return msg;
}
// --- DispatchEntry ---
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index d25bc23..47f75cbe 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -81,9 +81,7 @@
void release();
- virtual void appendDescription(std::string& msg) const = 0;
-
- std::string getDescription() const;
+ virtual std::string getDescription() const = 0;
protected:
EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags);
@@ -93,7 +91,7 @@
struct ConfigurationChangedEntry : EventEntry {
explicit ConfigurationChangedEntry(int32_t id, nsecs_t eventTime);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
protected:
virtual ~ConfigurationChangedEntry();
@@ -103,7 +101,7 @@
int32_t deviceId;
DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
protected:
virtual ~DeviceResetEntry();
@@ -116,7 +114,7 @@
FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus,
std::string_view reason);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
protected:
virtual ~FocusEntry();
@@ -148,7 +146,7 @@
KeyEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
int32_t metaState, int32_t repeatCount, nsecs_t downTime);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
void recycle();
protected:
@@ -182,7 +180,7 @@
float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
float xOffset, float yOffset);
- virtual void appendDescription(std::string& msg) const;
+ std::string getDescription() const override;
protected:
virtual ~MotionEntry();
diff --git a/services/inputflinger/dispatcher/InjectionState.cpp b/services/inputflinger/dispatcher/InjectionState.cpp
index b2d0a26..c8024a6 100644
--- a/services/inputflinger/dispatcher/InjectionState.cpp
+++ b/services/inputflinger/dispatcher/InjectionState.cpp
@@ -24,7 +24,7 @@
: refCount(1),
injectorPid(injectorPid),
injectorUid(injectorUid),
- injectionResult(INPUT_EVENT_INJECTION_PENDING),
+ injectionResult(android::os::InputEventInjectionResult::PENDING),
injectionIsAsync(false),
pendingForegroundDispatches(0) {}
diff --git a/services/inputflinger/dispatcher/InjectionState.h b/services/inputflinger/dispatcher/InjectionState.h
index 311a0f1..0bfafb1 100644
--- a/services/inputflinger/dispatcher/InjectionState.h
+++ b/services/inputflinger/dispatcher/InjectionState.h
@@ -17,34 +17,19 @@
#ifndef _UI_INPUT_INPUTDISPATCHER_INJECTIONSTATE_H
#define _UI_INPUT_INPUTDISPATCHER_INJECTIONSTATE_H
+#include <stdint.h>
#include "InputDispatcherInterface.h"
-#include <stdint.h>
+namespace android {
-namespace android::inputdispatcher {
-
-/*
- * Constants used to determine the input event injection synchronization mode.
- */
-enum {
- /* Injection is asynchronous and is assumed always to be successful. */
- INPUT_EVENT_INJECTION_SYNC_NONE = 0,
-
- /* Waits for previous events to be dispatched so that the input dispatcher can determine
- * whether input event injection willbe permitted based on the current input focus.
- * Does not wait for the input event to finish processing. */
- INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1,
-
- /* Waits for the input event to be completely processed. */
- INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED = 2,
-};
+namespace inputdispatcher {
struct InjectionState {
mutable int32_t refCount;
int32_t injectorPid;
int32_t injectorUid;
- int32_t injectionResult; // initially INPUT_EVENT_INJECTION_PENDING
+ android::os::InputEventInjectionResult injectionResult; // initially PENDING
bool injectionIsAsync; // set to true if injection is not waiting for the result
int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
@@ -55,6 +40,7 @@
~InjectionState();
};
-} // namespace android::inputdispatcher
+} // namespace inputdispatcher
+} // namespace android
#endif // _UI_INPUT_INPUTDISPATCHER_INJECTIONSTATE_H
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 5dc399e..d7aea4e 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -74,6 +74,9 @@
#define INDENT4 " "
using android::base::StringPrintf;
+using android::os::BlockUntrustedTouchesMode;
+using android::os::InputEventInjectionResult;
+using android::os::InputEventInjectionSync;
namespace android::inputdispatcher {
@@ -217,6 +220,36 @@
}
}
+static std::string dumpQueue(const std::deque<DispatchEntry*>& queue, nsecs_t currentTime) {
+ constexpr size_t maxEntries = 50; // max events to print
+ constexpr size_t skipBegin = maxEntries / 2;
+ const size_t skipEnd = queue.size() - maxEntries / 2;
+ // skip from maxEntries / 2 ... size() - maxEntries/2
+ // only print from 0 .. skipBegin and then from skipEnd .. size()
+
+ std::string dump;
+ for (size_t i = 0; i < queue.size(); i++) {
+ const DispatchEntry& entry = *queue[i];
+ if (i >= skipBegin && i < skipEnd) {
+ dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
+ i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
+ continue;
+ }
+ dump.append(INDENT4);
+ dump += entry.eventEntry->getDescription();
+ dump += StringPrintf(", seq=%" PRIu32
+ ", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64 "ms",
+ entry.seq, entry.targetFlags, entry.resolvedAction,
+ ns2ms(currentTime - entry.eventEntry->eventTime));
+ if (entry.deliveryTime != 0) {
+ // This entry was delivered, so add information on how long we've been waiting
+ dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
+ }
+ dump.append("\n");
+ }
+ return dump;
+}
+
/**
* Find the entry in std::unordered_map by key, and return it.
* If the entry is not found, return a default constructed entry.
@@ -1018,11 +1051,11 @@
void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
InjectionState* injectionState = entry->injectionState;
- if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+ if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
#if DEBUG_DISPATCH_CYCLE
ALOGD("Injected inbound event was dropped.");
#endif
- setInjectionResult(entry, INPUT_EVENT_INJECTION_FAILED);
+ setInjectionResult(entry, InputEventInjectionResult::FAILED);
}
if (entry == mNextUnblockedEvent) {
mNextUnblockedEvent = nullptr;
@@ -1227,22 +1260,22 @@
// Clean up if dropping the event.
if (*dropReason != DropReason::NOT_DROPPED) {
setInjectionResult(entry,
- *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
- : INPUT_EVENT_INJECTION_FAILED);
+ *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
+ : InputEventInjectionResult::FAILED);
mReporter->reportDroppedKey(entry->id);
return true;
}
// Identify targets.
std::vector<InputTarget> inputTargets;
- int32_t injectionResult =
+ InputEventInjectionResult injectionResult =
findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
- if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+ if (injectionResult == InputEventInjectionResult::PENDING) {
return false;
}
setInjectionResult(entry, injectionResult);
- if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
+ if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
return true;
}
@@ -1278,8 +1311,8 @@
// Clean up if dropping the event.
if (*dropReason != DropReason::NOT_DROPPED) {
setInjectionResult(entry,
- *dropReason == DropReason::POLICY ? INPUT_EVENT_INJECTION_SUCCEEDED
- : INPUT_EVENT_INJECTION_FAILED);
+ *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
+ : InputEventInjectionResult::FAILED);
return true;
}
@@ -1289,7 +1322,7 @@
std::vector<InputTarget> inputTargets;
bool conflictingPointerActions = false;
- int32_t injectionResult;
+ InputEventInjectionResult injectionResult;
if (isPointerEvent) {
// Pointer event. (eg. touchscreen)
injectionResult =
@@ -1300,16 +1333,16 @@
injectionResult =
findFocusedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime);
}
- if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+ if (injectionResult == InputEventInjectionResult::PENDING) {
return false;
}
setInjectionResult(entry, injectionResult);
- if (injectionResult == INPUT_EVENT_INJECTION_PERMISSION_DENIED) {
+ if (injectionResult == InputEventInjectionResult::PERMISSION_DENIED) {
ALOGW("Permission denied, dropping the motion (isPointer=%s)", toString(isPointerEvent));
return true;
}
- if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
+ if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
CancelationOptions::Mode mode(isPointerEvent
? CancelationOptions::CANCEL_POINTER_EVENTS
: CancelationOptions::CANCEL_NON_POINTER_EVENTS);
@@ -1491,10 +1524,9 @@
return false;
}
-int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
- const EventEntry& entry,
- std::vector<InputTarget>& inputTargets,
- nsecs_t* nextWakeupTime) {
+InputEventInjectionResult InputDispatcher::findFocusedWindowTargetsLocked(
+ nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
+ nsecs_t* nextWakeupTime) {
std::string reason;
int32_t displayId = getTargetDisplayId(entry);
@@ -1508,7 +1540,7 @@
ALOGI("Dropping %s event because there is no focused window or focused application in "
"display %" PRId32 ".",
EventEntry::typeToString(entry.type), displayId);
- return INPUT_EVENT_INJECTION_FAILED;
+ return InputEventInjectionResult::FAILED;
}
// Compatibility behavior: raise ANR if there is a focused application, but no focused window.
@@ -1528,15 +1560,15 @@
"window when it finishes starting up. Will wait for %" PRId64 "ms",
mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
*nextWakeupTime = *mNoFocusedWindowTimeoutTime;
- return INPUT_EVENT_INJECTION_PENDING;
+ return InputEventInjectionResult::PENDING;
} else if (currentTime > *mNoFocusedWindowTimeoutTime) {
// Already raised ANR. Drop the event
ALOGE("Dropping %s event because there is no focused window",
EventEntry::typeToString(entry.type));
- return INPUT_EVENT_INJECTION_FAILED;
+ return InputEventInjectionResult::FAILED;
} else {
// Still waiting for the focused window
- return INPUT_EVENT_INJECTION_PENDING;
+ return InputEventInjectionResult::PENDING;
}
}
@@ -1545,12 +1577,12 @@
// Check permissions.
if (!checkInjectionPermission(focusedWindowHandle, entry.injectionState)) {
- return INPUT_EVENT_INJECTION_PERMISSION_DENIED;
+ return InputEventInjectionResult::PERMISSION_DENIED;
}
if (focusedWindowHandle->getInfo()->paused) {
ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
- return INPUT_EVENT_INJECTION_PENDING;
+ return InputEventInjectionResult::PENDING;
}
// If the event is a key event, then we must wait for all previous events to
@@ -1567,7 +1599,7 @@
if (entry.type == EventEntry::Type::KEY) {
if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
*nextWakeupTime = *mKeyIsWaitingForEventsTimeout;
- return INPUT_EVENT_INJECTION_PENDING;
+ return InputEventInjectionResult::PENDING;
}
}
@@ -1577,7 +1609,7 @@
BitSet32(0), inputTargets);
// Done.
- return INPUT_EVENT_INJECTION_SUCCEEDED;
+ return InputEventInjectionResult::SUCCEEDED;
}
/**
@@ -1606,11 +1638,9 @@
return responsiveMonitors;
}
-int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
- const MotionEntry& entry,
- std::vector<InputTarget>& inputTargets,
- nsecs_t* nextWakeupTime,
- bool* outConflictingPointerActions) {
+InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
+ nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
+ nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) {
ATRACE_CALL();
enum InjectionPermission {
INJECTION_PERMISSION_UNKNOWN,
@@ -1625,7 +1655,7 @@
int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
// Update the touch state as needed based on the properties of the touch event.
- int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
+ InputEventInjectionResult injectionResult = InputEventInjectionResult::PENDING;
InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
sp<InputWindowHandle> newHoverWindowHandle(mLastHoverWindowHandle);
sp<InputWindowHandle> newTouchedWindowHandle;
@@ -1660,7 +1690,7 @@
"in display %" PRId32,
displayId);
// TODO: test multiple simultaneous input streams.
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
+ injectionResult = InputEventInjectionResult::FAILED;
switchedDevice = false;
wrongDevice = true;
goto Failed;
@@ -1676,7 +1706,7 @@
"in display %" PRId32,
displayId);
// TODO: test multiple simultaneous input streams.
- injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
+ injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
switchedDevice = false;
wrongDevice = true;
goto Failed;
@@ -1760,7 +1790,7 @@
ALOGI("Dropping event because there is no touchable window or gesture monitor at "
"(%d, %d) in display %" PRId32 ".",
x, y, displayId);
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
+ injectionResult = InputEventInjectionResult::FAILED;
goto Failed;
}
@@ -1803,7 +1833,7 @@
"dropped the pointer down event in display %" PRId32,
displayId);
}
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
+ injectionResult = InputEventInjectionResult::FAILED;
goto Failed;
}
@@ -1888,7 +1918,7 @@
if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
haveForegroundWindow = true;
if (!checkInjectionPermission(touchedWindow.windowHandle, entry.injectionState)) {
- injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
+ injectionResult = InputEventInjectionResult::PERMISSION_DENIED;
injectionPermission = INJECTION_PERMISSION_DENIED;
goto Failed;
}
@@ -1899,7 +1929,7 @@
ALOGI("Dropping event because there is no touched foreground window in display "
"%" PRId32 " or gesture monitor to receive it.",
displayId);
- injectionResult = INPUT_EVENT_INJECTION_FAILED;
+ injectionResult = InputEventInjectionResult::FAILED;
goto Failed;
}
@@ -1956,7 +1986,7 @@
}
// Success! Output targets.
- injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
+ injectionResult = InputEventInjectionResult::SUCCEEDED;
for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
@@ -3483,9 +3513,9 @@
}
}
-int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t injectorPid,
- int32_t injectorUid, int32_t syncMode,
- std::chrono::milliseconds timeout, uint32_t policyFlags) {
+InputEventInjectionResult InputDispatcher::injectInputEvent(
+ const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
+ InputEventInjectionSync syncMode, std::chrono::milliseconds timeout, uint32_t policyFlags) {
#if DEBUG_INBOUND_EVENT_DETAILS
ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
"syncMode=%d, timeout=%lld, policyFlags=0x%08x",
@@ -3504,7 +3534,7 @@
const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
int32_t action = incomingKey.getAction();
if (!validateKeyEvent(action)) {
- return INPUT_EVENT_INJECTION_FAILED;
+ return InputEventInjectionResult::FAILED;
}
int32_t flags = incomingKey.getFlags();
@@ -3550,7 +3580,7 @@
int32_t actionButton = motionEvent->getActionButton();
int32_t displayId = motionEvent->getDisplayId();
if (!validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
- return INPUT_EVENT_INJECTION_FAILED;
+ return InputEventInjectionResult::FAILED;
}
if (!(policyFlags & POLICY_FLAG_FILTERED)) {
@@ -3603,11 +3633,11 @@
default:
ALOGW("Cannot inject %s events", inputEventTypeToString(event->getType()));
- return INPUT_EVENT_INJECTION_FAILED;
+ return InputEventInjectionResult::FAILED;
}
InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
- if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
+ if (syncMode == InputEventInjectionSync::NONE) {
injectionState->injectionIsAsync = true;
}
@@ -3626,16 +3656,16 @@
mLooper->wake();
}
- int32_t injectionResult;
+ InputEventInjectionResult injectionResult;
{ // acquire lock
std::unique_lock _l(mLock);
- if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
- injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
+ if (syncMode == InputEventInjectionSync::NONE) {
+ injectionResult = InputEventInjectionResult::SUCCEEDED;
} else {
for (;;) {
injectionResult = injectionState->injectionResult;
- if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
+ if (injectionResult != InputEventInjectionResult::PENDING) {
break;
}
@@ -3645,15 +3675,15 @@
ALOGD("injectInputEvent - Timed out waiting for injection result "
"to become available.");
#endif
- injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
+ injectionResult = InputEventInjectionResult::TIMED_OUT;
break;
}
mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
}
- if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED &&
- syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
+ if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
+ syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
while (injectionState->pendingForegroundDispatches != 0) {
#if DEBUG_INJECTION
ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
@@ -3665,7 +3695,7 @@
ALOGD("injectInputEvent - Timed out waiting for pending foreground "
"dispatches to finish.");
#endif
- injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
+ injectionResult = InputEventInjectionResult::TIMED_OUT;
break;
}
@@ -3723,7 +3753,8 @@
mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
}
-void InputDispatcher::setInjectionResult(EventEntry* entry, int32_t injectionResult) {
+void InputDispatcher::setInjectionResult(EventEntry* entry,
+ InputEventInjectionResult injectionResult) {
InjectionState* injectionState = entry->injectionState;
if (injectionState) {
#if DEBUG_INJECTION
@@ -3735,18 +3766,21 @@
if (injectionState->injectionIsAsync && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
// Log the outcome since the injector did not wait for the injection result.
switch (injectionResult) {
- case INPUT_EVENT_INJECTION_SUCCEEDED:
+ case InputEventInjectionResult::SUCCEEDED:
ALOGV("Asynchronous input event injection succeeded.");
break;
- case INPUT_EVENT_INJECTION_FAILED:
+ case InputEventInjectionResult::FAILED:
ALOGW("Asynchronous input event injection failed.");
break;
- case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
+ case InputEventInjectionResult::PERMISSION_DENIED:
ALOGW("Asynchronous input event injection permission denied.");
break;
- case INPUT_EVENT_INJECTION_TIMED_OUT:
+ case InputEventInjectionResult::TIMED_OUT:
ALOGW("Asynchronous input event injection timed out.");
break;
+ case InputEventInjectionResult::PENDING:
+ ALOGE("Setting result to 'PENDING' for asynchronous injection");
+ break;
}
}
@@ -4453,7 +4487,7 @@
dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
for (EventEntry* entry : mRecentQueue) {
dump += INDENT2;
- entry->appendDescription(dump);
+ dump += entry->getDescription();
dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
}
} else {
@@ -4464,7 +4498,7 @@
if (mPendingEvent) {
dump += INDENT "PendingEvent:\n";
dump += INDENT2;
- mPendingEvent->appendDescription(dump);
+ dump += mPendingEvent->getDescription();
dump += StringPrintf(", age=%" PRId64 "ms\n",
ns2ms(currentTime - mPendingEvent->eventTime));
} else {
@@ -4476,7 +4510,7 @@
dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
for (EventEntry* entry : mInboundQueue) {
dump += INDENT2;
- entry->appendDescription(dump);
+ dump += entry->getDescription();
dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
}
} else {
@@ -4508,14 +4542,8 @@
if (!connection->outboundQueue.empty()) {
dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
connection->outboundQueue.size());
- for (DispatchEntry* entry : connection->outboundQueue) {
- dump.append(INDENT4);
- entry->eventEntry->appendDescription(dump);
- dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, age=%" PRId64
- "ms\n",
- entry->targetFlags, entry->resolvedAction,
- ns2ms(currentTime - entry->eventEntry->eventTime));
- }
+ dump += dumpQueue(connection->outboundQueue, currentTime);
+
} else {
dump += INDENT3 "OutboundQueue: <empty>\n";
}
@@ -4523,15 +4551,7 @@
if (!connection->waitQueue.empty()) {
dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
connection->waitQueue.size());
- for (DispatchEntry* entry : connection->waitQueue) {
- dump += INDENT4;
- entry->eventEntry->appendDescription(dump);
- dump += StringPrintf(", targetFlags=0x%08x, resolvedAction=%d, "
- "age=%" PRId64 "ms, wait=%" PRId64 "ms seq=%" PRIu32 "\n",
- entry->targetFlags, entry->resolvedAction,
- ns2ms(currentTime - entry->eventEntry->eventTime),
- ns2ms(currentTime - entry->deliveryTime), entry->seq);
- }
+ dump += dumpQueue(connection->waitQueue, currentTime);
} else {
dump += INDENT3 "WaitQueue: <empty>\n";
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index c0b0a7f..235a8d3 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -95,10 +95,10 @@
virtual void notifySwitch(const NotifySwitchArgs* args) override;
virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) override;
- virtual int32_t injectInputEvent(const InputEvent* event, int32_t injectorPid,
- int32_t injectorUid, int32_t syncMode,
- std::chrono::milliseconds timeout,
- uint32_t policyFlags) override;
+ virtual android::os::InputEventInjectionResult injectInputEvent(
+ const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
+ android::os::InputEventInjectionSync syncMode, std::chrono::milliseconds timeout,
+ uint32_t policyFlags) override;
virtual std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) override;
@@ -113,7 +113,7 @@
virtual void setInputFilterEnabled(bool enabled) override;
virtual void setInTouchMode(bool inTouchMode) override;
virtual void setMaximumObscuringOpacityForTouch(float opacity) override;
- virtual void setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) override;
+ virtual void setBlockUntrustedTouchesMode(android::os::BlockUntrustedTouchesMode mode) override;
virtual bool transferTouchFocus(const sp<IBinder>& fromToken,
const sp<IBinder>& toToken) override;
@@ -242,7 +242,8 @@
// Event injection and synchronization.
std::condition_variable mInjectionResultAvailable;
bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
- void setInjectionResult(EventEntry* entry, int32_t injectionResult);
+ void setInjectionResult(EventEntry* entry,
+ android::os::InputEventInjectionResult injectionResult);
std::condition_variable mInjectionSyncFinished;
void incrementPendingForegroundDispatches(EventEntry* entry);
@@ -299,7 +300,7 @@
bool mInputFilterEnabled GUARDED_BY(mLock);
bool mInTouchMode GUARDED_BY(mLock);
float mMaximumObscuringOpacityForTouch GUARDED_BY(mLock);
- BlockUntrustedTouchesMode mBlockUntrustedTouchesMode GUARDED_BY(mLock);
+ android::os::BlockUntrustedTouchesMode mBlockUntrustedTouchesMode GUARDED_BY(mLock);
std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay
GUARDED_BY(mLock);
@@ -431,13 +432,12 @@
void resetNoFocusedWindowTimeoutLocked() REQUIRES(mLock);
int32_t getTargetDisplayId(const EventEntry& entry);
- int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry& entry,
- std::vector<InputTarget>& inputTargets,
- nsecs_t* nextWakeupTime) REQUIRES(mLock);
- int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry,
- std::vector<InputTarget>& inputTargets,
- nsecs_t* nextWakeupTime,
- bool* outConflictingPointerActions) REQUIRES(mLock);
+ android::os::InputEventInjectionResult findFocusedWindowTargetsLocked(
+ nsecs_t currentTime, const EventEntry& entry, std::vector<InputTarget>& inputTargets,
+ nsecs_t* nextWakeupTime) REQUIRES(mLock);
+ android::os::InputEventInjectionResult findTouchedWindowTargetsLocked(
+ nsecs_t currentTime, const MotionEntry& entry, std::vector<InputTarget>& inputTargets,
+ nsecs_t* nextWakeupTime, bool* outConflictingPointerActions) REQUIRES(mLock);
std::vector<TouchedMonitor> findTouchedGestureMonitorsLocked(
int32_t displayId, const std::vector<sp<InputWindowHandle>>& portalWindows) const
REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 65687c4..9154d48 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -22,36 +22,16 @@
#include <android/FocusRequest.h>
#include <android/os/BlockUntrustedTouchesMode.h>
#include <android/os/ISetInputWindowsListener.h>
+#include <android/os/InputEventInjectionResult.h>
+#include <android/os/InputEventInjectionSync.h>
#include <input/InputApplication.h>
#include <input/InputTransport.h>
#include <input/InputWindow.h>
#include <unordered_map>
-using android::os::BlockUntrustedTouchesMode;
namespace android {
-/*
- * Constants used to report the outcome of input event injection.
- */
-enum {
- /* (INTERNAL USE ONLY) Specifies that injection is pending and its outcome is unknown. */
- INPUT_EVENT_INJECTION_PENDING = -1,
-
- /* Injection succeeded. */
- INPUT_EVENT_INJECTION_SUCCEEDED = 0,
-
- /* Injection failed because the injector did not have permission to inject
- * into the application with input focus. */
- INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1,
-
- /* Injection failed because there were no available input targets. */
- INPUT_EVENT_INJECTION_FAILED = 2,
-
- /* Injection failed due to a timeout. */
- INPUT_EVENT_INJECTION_TIMED_OUT = 3
-};
-
/* Notifies the system about input events generated by the input reader.
* The dispatcher is expected to be mostly asynchronous. */
class InputDispatcherInterface : public virtual RefBase, public InputListenerInterface {
@@ -93,9 +73,10 @@
*
* This method may be called on any thread (usually by the input manager).
*/
- virtual int32_t injectInputEvent(const InputEvent* event, int32_t injectorPid,
- int32_t injectorUid, int32_t syncMode,
- std::chrono::milliseconds timeout, uint32_t policyFlags) = 0;
+ virtual android::os::InputEventInjectionResult injectInputEvent(
+ const InputEvent* event, int32_t injectorPid, int32_t injectorUid,
+ android::os::InputEventInjectionSync syncMode, std::chrono::milliseconds timeout,
+ uint32_t policyFlags) = 0;
/*
* Check whether InputEvent actually happened by checking the signature of the event.
@@ -161,7 +142,7 @@
*
* TODO(b/169067926): Clean-up feature modes.
*/
- virtual void setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mode) = 0;
+ virtual void setBlockUntrustedTouchesMode(android::os::BlockUntrustedTouchesMode mode) = 0;
/* Transfers touch focus from one window to another window.
*
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
index 573524e..ffd8bf2 100644
--- a/services/inputflinger/include/InputReaderBase.h
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -78,7 +78,7 @@
*
* This method may be called on any thread (usually by the input manager).
*/
- virtual void getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) = 0;
+ virtual std::vector<InputDeviceInfo> getInputDevices() const = 0;
/* Query current input state. */
virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 7c96e54..2028b91 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -87,7 +87,6 @@
int32_t oldGeneration;
int32_t timeoutMillis;
bool inputDevicesChanged = false;
- std::vector<InputDeviceInfo> inputDevices;
{ // acquire lock
AutoMutex _l(mLock);
@@ -128,13 +127,12 @@
if (oldGeneration != mGeneration) {
inputDevicesChanged = true;
- getInputDevicesLocked(inputDevices);
}
} // release lock
// Send out a message that the describes the changed input devices.
if (inputDevicesChanged) {
- mPolicy->notifyInputDevicesChanged(inputDevices);
+ mPolicy->notifyInputDevicesChanged(getInputDevicesLocked());
}
// Flush queued events out to the listener.
@@ -474,13 +472,14 @@
return ++mGeneration;
}
-void InputReader::getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) {
+std::vector<InputDeviceInfo> InputReader::getInputDevices() const {
AutoMutex _l(mLock);
- getInputDevicesLocked(outInputDevices);
+ return getInputDevicesLocked();
}
-void InputReader::getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices) {
- outInputDevices.clear();
+std::vector<InputDeviceInfo> InputReader::getInputDevicesLocked() const {
+ std::vector<InputDeviceInfo> outInputDevices;
+ outInputDevices.reserve(mDeviceToEventHubIdsMap.size());
for (const auto& [device, eventHubIds] : mDeviceToEventHubIdsMap) {
if (!device->isIgnored()) {
@@ -489,6 +488,7 @@
outInputDevices.push_back(info);
}
}
+ return outInputDevices;
}
int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask, int32_t keyCode) {
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index a902482..563018a 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -61,7 +61,7 @@
status_t start() override;
status_t stop() override;
- void getInputDevices(std::vector<InputDeviceInfo>& outInputDevices) override;
+ std::vector<InputDeviceInfo> getInputDevices() const override;
bool isInputDeviceEnabled(int32_t deviceId) override;
@@ -121,7 +121,7 @@
private:
std::unique_ptr<InputThread> mThread;
- Mutex mLock;
+ mutable Mutex mLock;
Condition mReaderIsAliveCondition;
@@ -181,7 +181,7 @@
int32_t mNextInputDeviceId;
int32_t nextInputDeviceIdLocked();
- void getInputDevicesLocked(std::vector<InputDeviceInfo>& outInputDevices);
+ std::vector<InputDeviceInfo> getInputDevicesLocked() const;
nsecs_t mDisableVirtualKeysTimeout;
void disableVirtualKeysUntilLocked(nsecs_t time);
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 662b8d0..dc32003 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -29,6 +29,8 @@
#include <vector>
using android::base::StringPrintf;
+using android::os::InputEventInjectionResult;
+using android::os::InputEventInjectionSync;
using namespace android::flag_operators;
namespace android::inputdispatcher {
@@ -354,18 +356,18 @@
INVALID_HMAC,
/*action*/ -1, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME,
ARBITRARY_TIME);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject key events with undefined action.";
// Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
INVALID_HMAC, AKEY_EVENT_ACTION_MULTIPLE, 0, AKEYCODE_A, KEY_A, AMETA_NONE, 0,
ARBITRARY_TIME, ARBITRARY_TIME);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject key events with ACTION_MULTIPLE.";
}
@@ -392,9 +394,9 @@
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with undefined action.";
// Rejects pointer down with invalid index.
@@ -405,9 +407,9 @@
AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with pointer down index too large.";
event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
@@ -417,9 +419,9 @@
AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with pointer down index too small.";
// Rejects pointer up with invalid index.
@@ -430,9 +432,9 @@
AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with pointer up index too large.";
event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
@@ -442,9 +444,9 @@
AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
ARBITRARY_TIME, ARBITRARY_TIME, /*pointerCount*/ 1, pointerProperties,
pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with pointer up index too small.";
// Rejects motion events with invalid number of pointers.
@@ -453,9 +455,9 @@
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 0, pointerProperties, pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with 0 pointers.";
event.initialize(InputEvent::nextId(), DEVICE_ID, source, DISPLAY_ID, INVALID_HMAC,
@@ -463,9 +465,9 @@
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with more than MAX_POINTERS pointers.";
// Rejects motion events with invalid pointer ids.
@@ -475,9 +477,9 @@
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with pointer ids less than 0.";
pointerProperties[0].id = MAX_POINTER_ID + 1;
@@ -486,9 +488,9 @@
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 1, pointerProperties, pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
// Rejects motion events with duplicate pointer ids.
@@ -499,9 +501,9 @@
identityTransform, 0, 0, AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, ARBITRARY_TIME, ARBITRARY_TIME,
/*pointerCount*/ 2, pointerProperties, pointerCoords);
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
- INPUT_EVENT_INJECTION_SYNC_NONE, 0ms, 0))
+ InputEventInjectionSync::NONE, 0ms, 0))
<< "Should reject motion events with duplicate pointer ids.";
}
@@ -868,10 +870,11 @@
std::atomic<int32_t> FakeWindowHandle::sId{1};
-static int32_t injectKey(const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount,
- int32_t displayId = ADISPLAY_ID_NONE,
- int32_t syncMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
- std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) {
+static InputEventInjectionResult injectKey(
+ const sp<InputDispatcher>& dispatcher, int32_t action, int32_t repeatCount,
+ int32_t displayId = ADISPLAY_ID_NONE,
+ InputEventInjectionSync syncMode = InputEventInjectionSync::WAIT_FOR_RESULT,
+ std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT) {
KeyEvent event;
nsecs_t currentTime = systemTime(SYSTEM_TIME_MONOTONIC);
@@ -886,13 +889,13 @@
POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
}
-static int32_t injectKeyDown(const sp<InputDispatcher>& dispatcher,
- int32_t displayId = ADISPLAY_ID_NONE) {
+static InputEventInjectionResult injectKeyDown(const sp<InputDispatcher>& dispatcher,
+ int32_t displayId = ADISPLAY_ID_NONE) {
return injectKey(dispatcher, AKEY_EVENT_ACTION_DOWN, /* repeatCount */ 0, displayId);
}
-static int32_t injectKeyUp(const sp<InputDispatcher>& dispatcher,
- int32_t displayId = ADISPLAY_ID_NONE) {
+static InputEventInjectionResult injectKeyUp(const sp<InputDispatcher>& dispatcher,
+ int32_t displayId = ADISPLAY_ID_NONE) {
return injectKey(dispatcher, AKEY_EVENT_ACTION_UP, /* repeatCount */ 0, displayId);
}
@@ -1007,22 +1010,22 @@
std::vector<PointerBuilder> mPointers;
};
-static int32_t injectMotionEvent(
+static InputEventInjectionResult injectMotionEvent(
const sp<InputDispatcher>& dispatcher, const MotionEvent& event,
std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
- int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT) {
+ InputEventInjectionSync injectionMode = InputEventInjectionSync::WAIT_FOR_RESULT) {
return dispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID, injectionMode,
injectionTimeout,
POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER);
}
-static int32_t injectMotionEvent(
+static InputEventInjectionResult injectMotionEvent(
const sp<InputDispatcher>& dispatcher, int32_t action, int32_t source, int32_t displayId,
const PointF& position,
const PointF& cursorPosition = {AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION},
std::chrono::milliseconds injectionTimeout = INJECT_EVENT_TIMEOUT,
- int32_t injectionMode = INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
+ InputEventInjectionSync injectionMode = InputEventInjectionSync::WAIT_FOR_RESULT,
nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC)) {
MotionEvent event = MotionEventBuilder(action, source)
.displayId(displayId)
@@ -1038,13 +1041,15 @@
return injectMotionEvent(dispatcher, event);
}
-static int32_t injectMotionDown(const sp<InputDispatcher>& dispatcher, int32_t source,
- int32_t displayId, const PointF& location = {100, 200}) {
+static InputEventInjectionResult injectMotionDown(const sp<InputDispatcher>& dispatcher,
+ int32_t source, int32_t displayId,
+ const PointF& location = {100, 200}) {
return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_DOWN, source, displayId, location);
}
-static int32_t injectMotionUp(const sp<InputDispatcher>& dispatcher, int32_t source,
- int32_t displayId, const PointF& location = {100, 200}) {
+static InputEventInjectionResult injectMotionUp(const sp<InputDispatcher>& dispatcher,
+ int32_t source, int32_t displayId,
+ const PointF& location = {100, 200}) {
return injectMotionEvent(dispatcher, AMOTION_EVENT_ACTION_UP, source, displayId, location);
}
@@ -1101,9 +1106,9 @@
ADISPLAY_ID_DEFAULT);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
- AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
// Window should receive motion event.
window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
@@ -1125,10 +1130,10 @@
window->setFlags(InputWindowInfo::Flag::NOT_TOUCH_MODAL);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
{50, 50}))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
// Window should receive motion event.
window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
@@ -1149,10 +1154,10 @@
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
{50, 50}))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
// Window should receive motion event.
window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
@@ -1167,9 +1172,9 @@
ADISPLAY_ID_DEFAULT);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
- AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
// Top window should receive the touch down event. Second window should not receive anything.
windowTop->consumeMotionDown(ADISPLAY_ID_DEFAULT);
@@ -1192,7 +1197,7 @@
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
// Start cursor position in right window so that we can move the cursor to left window.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_MOUSE)
@@ -1206,7 +1211,7 @@
ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
// Move cursor into left window
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_MOUSE)
@@ -1222,7 +1227,7 @@
ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
// Inject a series of mouse events for a mouse click
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
@@ -1232,7 +1237,7 @@
.build()));
windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
AINPUT_SOURCE_MOUSE)
@@ -1245,7 +1250,7 @@
windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
AINPUT_SOURCE_MOUSE)
@@ -1258,7 +1263,7 @@
windowLeft->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
.buttonState(0)
@@ -1269,7 +1274,7 @@
windowLeft->consumeMotionUp(ADISPLAY_ID_DEFAULT);
// Move mouse cursor back to right window
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
AINPUT_SOURCE_MOUSE)
@@ -1298,7 +1303,7 @@
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
AINPUT_SOURCE_MOUSE)
@@ -1310,7 +1315,7 @@
ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
// Inject a series of mouse events for a mouse click
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE)
.buttonState(AMOTION_EVENT_BUTTON_PRIMARY)
@@ -1320,7 +1325,7 @@
.build()));
window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_PRESS,
AINPUT_SOURCE_MOUSE)
@@ -1333,7 +1338,7 @@
window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_PRESS,
ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_BUTTON_RELEASE,
AINPUT_SOURCE_MOUSE)
@@ -1346,7 +1351,7 @@
window->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_BUTTON_RELEASE,
ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_MOUSE)
.buttonState(0)
@@ -1356,7 +1361,7 @@
.build()));
window->consumeMotionUp(ADISPLAY_ID_DEFAULT);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher,
MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
AINPUT_SOURCE_MOUSE)
@@ -1386,7 +1391,7 @@
// Inject an event with coordinate in the area of right window, with mouse cursor in the area of
// left window. This event should be dispatched to the left window.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_MOUSE,
ADISPLAY_ID_DEFAULT, {610, 400}, {599, 400}));
windowLeft->consumeMotionDown(ADISPLAY_ID_DEFAULT);
@@ -1696,9 +1701,9 @@
FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
true /*isGestureMonitor*/);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
}
@@ -1719,8 +1724,8 @@
FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
true /*isGestureMonitor*/);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
window->consumeKeyDown(ADISPLAY_ID_DEFAULT);
monitor.assertNoEvents();
}
@@ -1734,9 +1739,9 @@
FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
true /*isGestureMonitor*/);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
window->consumeMotionDown(ADISPLAY_ID_DEFAULT);
monitor.consumeMotionDown(ADISPLAY_ID_DEFAULT);
@@ -1744,9 +1749,9 @@
mDispatcher->pilferPointers(monitor.getToken());
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
monitor.consumeMotionUp(ADISPLAY_ID_DEFAULT);
}
@@ -1755,7 +1760,7 @@
FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
true /*isGestureMonitor*/);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT));
std::optional<uint32_t> consumeSeq = monitor.receiveEvent();
ASSERT_TRUE(consumeSeq);
@@ -1986,8 +1991,8 @@
setFocusedWindow(windowSecond);
windowSecond->consumeFocusEvent(true);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
// Focused window should receive event.
windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
@@ -2007,8 +2012,8 @@
setFocusedWindow(window);
// Test inject a key down, should timeout.
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
// window channel is invalid, so it should not receive any input event.
window->assertNoEvents();
@@ -2025,8 +2030,8 @@
setFocusedWindow(window);
// Test inject a key down, should timeout.
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
// window is invalid, so it should not receive any input event.
window->assertNoEvents();
@@ -2050,8 +2055,8 @@
windowSecond->consumeFocusEvent(true);
windowTop->consumeFocusEvent(false);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
// Focused window should receive event.
windowSecond->consumeKeyDown(ADISPLAY_ID_NONE);
@@ -2070,8 +2075,8 @@
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
setFocusedWindow(windowSecond, windowTop);
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
// Event should be dropped.
windowTop->assertNoEvents();
@@ -2099,9 +2104,9 @@
previousFocusedWindow->consumeFocusEvent(false);
// Injected key goes to pending queue.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
- ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
+ ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE));
// Window does not get focus event or key down.
window->assertNoEvents();
@@ -2305,43 +2310,43 @@
TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayTouch) {
// Test touch down on primary display.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
- AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
windowInSecondary->assertNoEvents();
// Test touch down on second display.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
- AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
windowInPrimary->assertNoEvents();
windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
}
TEST_F(InputDispatcherFocusOnTwoDisplaysTest, SetInputWindow_MultiDisplayFocus) {
// Test inject a key down with display id specified.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
windowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
windowInSecondary->assertNoEvents();
// Test inject a key down without display id specified.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
windowInPrimary->assertNoEvents();
windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
// Remove all windows in secondary display.
mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
- // Expect old focus should receive a cancel event.
+ // Old focus should receive a cancel event.
windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
AKEY_EVENT_FLAG_CANCELED);
// Test inject a key down, should timeout because of no target window.
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
windowInPrimary->assertNoEvents();
windowInSecondary->consumeFocusEvent(false);
windowInSecondary->assertNoEvents();
@@ -2355,18 +2360,18 @@
FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
// Test touch down on primary display.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
- AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
windowInPrimary->consumeMotionDown(ADISPLAY_ID_DEFAULT);
monitorInPrimary.consumeMotionDown(ADISPLAY_ID_DEFAULT);
windowInSecondary->assertNoEvents();
monitorInSecondary.assertNoEvents();
// Test touch down on second display.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
- AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, SECOND_DISPLAY_ID))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
windowInPrimary->assertNoEvents();
monitorInPrimary.assertNoEvents();
windowInSecondary->consumeMotionDown(SECOND_DISPLAY_ID);
@@ -2375,9 +2380,9 @@
// Test inject a non-pointer motion event.
// If specific a display, it will dispatch to the focused window of particular display,
// or it will dispatch to the focused window of focused display.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
- AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_NONE))
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
windowInPrimary->assertNoEvents();
monitorInPrimary.assertNoEvents();
windowInSecondary->consumeMotionDown(ADISPLAY_ID_NONE);
@@ -2393,8 +2398,8 @@
FakeMonitorReceiver(mDispatcher, "M_2", SECOND_DISPLAY_ID);
// Test inject a key down.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
windowInPrimary->assertNoEvents();
monitorInPrimary.assertNoEvents();
windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
@@ -2411,8 +2416,8 @@
secondWindowInPrimary->consumeFocusEvent(true);
// Test inject a key down.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
windowInPrimary->assertNoEvents();
windowInSecondary->assertNoEvents();
secondWindowInPrimary->consumeKeyDown(ADISPLAY_ID_DEFAULT);
@@ -2536,10 +2541,10 @@
// DOWN on the window that doesn't have focus. Ensure the window that didn't have focus received
// the onPointerDownOutsideFocus callback.
TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_Success) {
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
{20, 20}))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
mUnfocusedWindow->consumeMotionDown();
ASSERT_TRUE(mDispatcher->waitForIdle());
@@ -2550,9 +2555,9 @@
// DOWN on the window that doesn't have focus. Ensure no window received the
// onPointerDownOutsideFocus callback.
TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonPointerSource) {
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TRACKBALL, ADISPLAY_ID_DEFAULT, {20, 20}))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
mFocusedWindow->consumeMotionDown();
ASSERT_TRUE(mDispatcher->waitForIdle());
@@ -2562,8 +2567,8 @@
// Have two windows, one with focus. Inject KeyEvent with action DOWN on the window that doesn't
// have focus. Ensure no window received the onPointerDownOutsideFocus callback.
TEST_F(InputDispatcherOnPointerDownOutsideFocus, OnPointerDownOutsideFocus_NonMotionFailure) {
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mFocusedWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
ASSERT_TRUE(mDispatcher->waitForIdle());
@@ -2575,10 +2580,10 @@
// onPointerDownOutsideFocus callback.
TEST_F(InputDispatcherOnPointerDownOutsideFocus,
OnPointerDownOutsideFocus_OnAlreadyFocusedWindow) {
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
FOCUSED_WINDOW_TOUCH_POINT))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
mFocusedWindow->consumeMotionDown();
ASSERT_TRUE(mDispatcher->waitForIdle());
@@ -2824,10 +2829,10 @@
static constexpr PointF WINDOW_LOCATION = {20, 20};
void tapOnWindow() {
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
WINDOW_LOCATION));
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
WINDOW_LOCATION));
}
@@ -2844,7 +2849,7 @@
// Send a regular key and respond, which should not cause an ANR.
TEST_F(InputDispatcherSingleWindowAnr, WhenKeyIsConsumed_NoAnr) {
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher));
mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
ASSERT_TRUE(mDispatcher->waitForIdle());
mFakePolicy->assertNotifyAnrWasNotCalled();
@@ -2855,10 +2860,10 @@
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
mWindow->consumeFocusEvent(false);
- int32_t result =
+ InputEventInjectionResult result =
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
- INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
+ InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/);
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result);
// Key will not go to window because we have no focused window.
// The 'no focused window' ANR timer should start instead.
@@ -2874,7 +2879,7 @@
// When ANR is raised, policy will tell the dispatcher to cancel the events for that window.
// So InputDispatcher will enqueue ACTION_CANCEL event as well.
TEST_F(InputDispatcherSingleWindowAnr, OnPointerDown_BasicAnr) {
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
WINDOW_LOCATION));
@@ -2893,7 +2898,7 @@
// Send a key to the app and have the app not respond right away.
TEST_F(InputDispatcherSingleWindowAnr, OnKeyDown_BasicAnr) {
// Inject a key, and don't respond - expect that ANR is called.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher));
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher));
std::optional<uint32_t> sequenceNum = mWindow->receiveEvent();
ASSERT_TRUE(sequenceNum);
const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
@@ -2908,7 +2913,7 @@
mWindow->consumeFocusEvent(false);
// taps on the window work as normal
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
WINDOW_LOCATION));
ASSERT_NO_FATAL_FAILURE(mWindow->consumeMotionDown());
@@ -2918,10 +2923,10 @@
// Once a focused event arrives, we get an ANR for this application
// We specify the injection timeout to be smaller than the application timeout, to ensure that
// injection times out (instead of failing).
- const int32_t result =
+ const InputEventInjectionResult result =
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
- INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
+ InputEventInjectionSync::WAIT_FOR_RESULT, 10ms);
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result);
const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
ASSERT_TRUE(mDispatcher->waitForIdle());
@@ -2940,10 +2945,10 @@
// Once a focused event arrives, we get an ANR for this application
// We specify the injection timeout to be smaller than the application timeout, to ensure that
// injection times out (instead of failing).
- const int32_t result =
+ const InputEventInjectionResult result =
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
- INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
+ InputEventInjectionSync::WAIT_FOR_RESULT, 10ms);
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result);
const std::chrono::duration appTimeout =
mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
mFakePolicy->assertNotifyAnrWasCalled(appTimeout, mApplication, nullptr /*windowToken*/);
@@ -2964,16 +2969,16 @@
mWindow->consumeFocusEvent(false);
// Once a focused event arrives, we get an ANR for this application
- const int32_t result =
+ const InputEventInjectionResult result =
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
- INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
+ InputEventInjectionSync::WAIT_FOR_RESULT, 10ms);
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result);
const std::chrono::duration timeout = mApplication->getDispatchingTimeout(DISPATCHING_TIMEOUT);
mFakePolicy->assertNotifyAnrWasCalled(timeout, mApplication, nullptr /*windowToken*/);
// Future focused events get dropped right away
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, injectKeyDown(mDispatcher));
+ ASSERT_EQ(InputEventInjectionResult::FAILED, injectKeyDown(mDispatcher));
ASSERT_TRUE(mDispatcher->waitForIdle());
mWindow->assertNoEvents();
}
@@ -2993,14 +2998,14 @@
ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
{AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION},
- 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
+ 500ms, InputEventInjectionSync::WAIT_FOR_RESULT, currentTime);
// Now send ACTION_UP, with identical timestamp
injectMotionEvent(mDispatcher, AMOTION_EVENT_ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN,
ADISPLAY_ID_DEFAULT, WINDOW_LOCATION,
{AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION},
- 500ms, INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, currentTime);
+ 500ms, InputEventInjectionSync::WAIT_FOR_RESULT, currentTime);
// We have now sent down and up. Let's consume first event and then ANR on the second.
mWindow->consumeMotionDown(ADISPLAY_ID_DEFAULT);
@@ -3015,9 +3020,10 @@
FakeMonitorReceiver(mDispatcher, "Gesture monitor", ADISPLAY_ID_DEFAULT,
true /*isGestureMonitor*/);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT));
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectKeyDown(mDispatcher, ADISPLAY_ID_DEFAULT));
mWindow->consumeKeyDown(ADISPLAY_ID_DEFAULT);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher, ADISPLAY_ID_DEFAULT));
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher, ADISPLAY_ID_DEFAULT));
// Stuck on the ACTION_UP
const std::chrono::duration timeout = mWindow->getDispatchingTimeout(DISPATCHING_TIMEOUT);
@@ -3093,7 +3099,7 @@
const std::chrono::duration timeout = 5ms;
mFakePolicy->setAnrTimeout(timeout);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
WINDOW_LOCATION));
@@ -3141,10 +3147,10 @@
// window even if motions are still being processed. But because the injection timeout is short,
// we will receive INJECTION_TIMED_OUT as the result.
- int32_t result =
+ InputEventInjectionResult result =
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */, ADISPLAY_ID_DEFAULT,
- INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT, 10ms);
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, result);
+ InputEventInjectionSync::WAIT_FOR_RESULT, 10ms);
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, result);
// Key will not be sent to the window, yet, because the window is still processing events
// and the key remains pending, waiting for the touch events to be processed
std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
@@ -3176,9 +3182,9 @@
ASSERT_TRUE(upSequenceNum);
// Don't finish the events yet, and send a key
// Injection is async, so it will succeed
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
- ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
+ ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE));
// At this point, key is still pending, and should not be sent to the application yet.
std::optional<uint32_t> keySequenceNum = mWindow->receiveEvent();
ASSERT_FALSE(keySequenceNum);
@@ -3248,10 +3254,10 @@
private:
void tap(const PointF& location) {
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
location));
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
location));
}
@@ -3260,10 +3266,10 @@
// If we have 2 windows that are both unresponsive, the one with the shortest timeout
// should be ANR'd first.
TEST_F(InputDispatcherMultiWindowAnr, TwoWindows_BothUnresponsive) {
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
FOCUSED_WINDOW_LOCATION))
- << "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ << "Inject motion event should return InputEventInjectionResult::SUCCEEDED";
mFocusedWindow->consumeMotionDown();
mUnfocusedWindow->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_OUTSIDE,
ADISPLAY_ID_DEFAULT, 0 /*flags*/);
@@ -3271,7 +3277,7 @@
ASSERT_TRUE(mDispatcher->waitForIdle());
mFakePolicy->assertNotifyAnrWasNotCalled();
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
FOCUSED_WINDOW_LOCATION));
std::optional<uint32_t> unfocusedSequenceNum = mUnfocusedWindow->receiveEvent();
@@ -3333,10 +3339,10 @@
// Tap once again
// We cannot use "tapOnFocusedWindow" because it asserts the injection result to be success
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
FOCUSED_WINDOW_LOCATION));
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
injectMotionUp(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
FOCUSED_WINDOW_LOCATION));
// Unfocused window does not receive ACTION_OUTSIDE because the tapped window is not a
@@ -3355,7 +3361,7 @@
// If you tap outside of all windows, there will not be ANR
TEST_F(InputDispatcherMultiWindowAnr, TapOutsideAllWindows_DoesNotAnr) {
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
LOCATION_OUTSIDE_ALL_WINDOWS));
ASSERT_TRUE(mDispatcher->waitForIdle());
@@ -3367,7 +3373,7 @@
mFocusedWindow->setPaused(true);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
- ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED,
+ ASSERT_EQ(InputEventInjectionResult::FAILED,
injectMotionDown(mDispatcher, AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT,
FOCUSED_WINDOW_LOCATION));
@@ -3407,10 +3413,10 @@
// Injection will succeed because we will eventually give up and send the key to the focused
// window even if motions are still being processed.
- int32_t result =
+ InputEventInjectionResult result =
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
- INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
+ InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/);
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result);
// Key will not be sent to the window, yet, because the window is still processing events
// and the key remains pending, waiting for the touch events to be processed
std::optional<uint32_t> keySequenceNum = mFocusedWindow->receiveEvent();
@@ -3510,10 +3516,10 @@
// Send a key. The ANR timer should start because there is no focused window.
// 'focusedApplication' will get blamed if this timer completes.
// Key will not be sent anywhere because we have no focused window. It will remain pending.
- int32_t result =
+ InputEventInjectionResult result =
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /*repeatCount*/, ADISPLAY_ID_DEFAULT,
- INPUT_EVENT_INJECTION_SYNC_NONE, 10ms /*injectionTimeout*/);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, result);
+ InputEventInjectionSync::NONE, 10ms /*injectionTimeout*/);
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, result);
// Wait until dispatcher starts the "no focused window" timer. If we don't wait here,
// then the injected touches won't cause the focused event to get dropped.
@@ -3645,8 +3651,8 @@
// window gets focused
mWindow->consumeFocusEvent(true);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
}
@@ -3657,11 +3663,11 @@
// window gets focused
mWindow->consumeFocusEvent(true);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
mMirror->setFocusable(false);
@@ -3670,8 +3676,8 @@
// window loses focus since one of the windows associated with the token in not focusable
mWindow->consumeFocusEvent(false);
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
mWindow->assertNoEvents();
}
@@ -3682,21 +3688,21 @@
// window gets focused
mWindow->consumeFocusEvent(true);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
mMirror->setVisible(false);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
mWindow->setVisible(false);
@@ -3705,8 +3711,8 @@
// window loses focus only after all windows associated with the token become invisible.
mWindow->consumeFocusEvent(false);
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
mWindow->assertNoEvents();
}
@@ -3716,29 +3722,29 @@
// window gets focused
mWindow->consumeFocusEvent(true);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
// single window is removed but the window token remains focused
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mMirror}}});
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyDown(ADISPLAY_ID_NONE);
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyUp(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED, injectKeyUp(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::SUCCEEDED";
mWindow->consumeKeyUp(ADISPLAY_ID_NONE);
// Both windows are removed
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {}}});
mWindow->consumeFocusEvent(false);
- ASSERT_EQ(INPUT_EVENT_INJECTION_TIMED_OUT, injectKeyDown(mDispatcher))
- << "Inject key event should return INPUT_EVENT_INJECTION_TIMED_OUT";
+ ASSERT_EQ(InputEventInjectionResult::TIMED_OUT, injectKeyDown(mDispatcher))
+ << "Inject key event should return InputEventInjectionResult::TIMED_OUT";
mWindow->assertNoEvents();
}
@@ -3751,9 +3757,9 @@
setFocusedWindow(mMirror);
// Injected key goes to pending queue.
- ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED,
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
injectKey(mDispatcher, AKEY_EVENT_ACTION_DOWN, 0 /* repeatCount */,
- ADISPLAY_ID_DEFAULT, INPUT_EVENT_INJECTION_SYNC_NONE));
+ ADISPLAY_ID_DEFAULT, InputEventInjectionSync::NONE));
mMirror->setVisible(true);
mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow, mMirror}}});
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 54a36a9..211b49e 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1330,22 +1330,27 @@
}
};
-TEST_F(InputReaderTest, GetInputDevices) {
+TEST_F(InputReaderTest, ReaderGetInputDevices) {
ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored", Flags<InputDeviceClass>(0),
nullptr)); // no classes so device will be ignored
- std::vector<InputDeviceInfo> inputDevices;
- mReader->getInputDevices(inputDevices);
+ const std::vector<InputDeviceInfo> inputDevices = mReader->getInputDevices();
ASSERT_EQ(1U, inputDevices.size());
ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
+}
+
+TEST_F(InputReaderTest, PolicyGetInputDevices) {
+ ASSERT_NO_FATAL_FAILURE(addDevice(1, "keyboard", InputDeviceClass::KEYBOARD, nullptr));
+ ASSERT_NO_FATAL_FAILURE(addDevice(2, "ignored", Flags<InputDeviceClass>(0),
+ nullptr)); // no classes so device will be ignored
// Should also have received a notification describing the new input devices.
- inputDevices = mFakePolicy->getInputDevices();
+ const std::vector<InputDeviceInfo>& inputDevices = mFakePolicy->getInputDevices();
ASSERT_EQ(1U, inputDevices.size());
ASSERT_EQ(END_RESERVED_ID + 1, inputDevices[0].getId());
ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.c_str());
@@ -1372,9 +1377,7 @@
addDevice(eventHubIds[1], "fake2", InputDeviceClass::KEYBOARD, nullptr));
// Two devices will be merged to one input device as they have same identifier
- std::vector<InputDeviceInfo> inputDevices;
- mReader->getInputDevices(inputDevices);
- ASSERT_EQ(1U, inputDevices.size());
+ ASSERT_EQ(1U, mReader->getInputDevices().size());
}
TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
@@ -1815,20 +1818,17 @@
ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
// Find the test device by its name.
- std::vector<InputDeviceInfo> inputDevices;
- mReader->getInputDevices(inputDevices);
- InputDeviceInfo* keyboardInfo = nullptr;
- const char* keyboardName = keyboard->getName();
- for (unsigned int i = 0; i < initialNumDevices + 1; i++) {
- if (!strcmp(inputDevices[i].getIdentifier().name.c_str(), keyboardName)) {
- keyboardInfo = &inputDevices[i];
- break;
- }
- }
- ASSERT_NE(keyboardInfo, nullptr);
- ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, keyboardInfo->getKeyboardType());
- ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyboardInfo->getSources());
- ASSERT_EQ(0U, keyboardInfo->getMotionRanges().size());
+ const std::vector<InputDeviceInfo> inputDevices = mReader->getInputDevices();
+ const auto& it =
+ std::find_if(inputDevices.begin(), inputDevices.end(),
+ [&keyboard](const InputDeviceInfo& info) {
+ return info.getIdentifier().name == keyboard->getName();
+ });
+
+ ASSERT_NE(it, inputDevices.end());
+ ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, it->getKeyboardType());
+ ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, it->getSources());
+ ASSERT_EQ(0U, it->getMotionRanges().size());
keyboard.reset();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
@@ -3059,15 +3059,17 @@
mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
- device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
- AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+ KeyboardInputMapper& mapper2 =
+ device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD,
+ AINPUT_KEYBOARD_TYPE_ALPHABETIC);
device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/);
device2->reset(ARBITRARY_TIME);
ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_CAPSL));
ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_NUML));
ASSERT_TRUE(mFakeEventHub->getLedState(SECOND_EVENTHUB_ID, LED_SCROLLL));
- ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper.getMetaState());
+ ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON,
+ mapper2.getMetaState());
}
// --- KeyboardInputMapperTest_ExternalDevice ---
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index cf60b71..c77298e 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -366,7 +366,7 @@
mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
} else if (!display) {
// Do nothing.
- } else if (const auto displayId = display->getId();
+ } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId());
displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 07817b5..aac6c91 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -79,18 +79,18 @@
status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags, const sp<IBinder>& parentHandle,
LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outId,
+ sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
uint32_t* outTransformHint) {
// We rely on createLayer to check permissions.
return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
- parentHandle, nullptr, outId, outTransformHint);
+ parentHandle, outLayerId, nullptr, outTransformHint);
}
status_t Client::createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags,
const sp<IGraphicBufferProducer>& parent,
LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outId,
+ sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
uint32_t* outTransformHint) {
if (mFlinger->authenticateSurfaceTexture(parent) == false) {
ALOGE("failed to authenticate surface texture");
@@ -104,12 +104,12 @@
}
return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
- nullptr, layer, outId, outTransformHint);
+ nullptr, outLayerId, layer, outTransformHint);
}
status_t Client::mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle,
- int32_t* outId) {
- return mFlinger->mirrorLayer(this, mirrorFromHandle, outHandle, outId);
+ int32_t* outLayerId) {
+ return mFlinger->mirrorLayer(this, mirrorFromHandle, outHandle, outLayerId);
}
status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 9462f1a..15cd763 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -50,18 +50,18 @@
virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags, const sp<IBinder>& parent,
LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outId,
+ sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
uint32_t* outTransformHint = nullptr);
virtual status_t createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags,
const sp<IGraphicBufferProducer>& parent,
LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outId,
+ sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
uint32_t* outTransformHint = nullptr);
status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* handle,
- int32_t* outId);
+ int32_t* outLayerId);
virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
index a38d1f3..01dd534 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
@@ -34,8 +34,8 @@
*/
class Display : public virtual Output {
public:
- // Gets the HWC DisplayId for the display if there is one
- virtual const std::optional<DisplayId>& getId() const = 0;
+ // Gets the DisplayId for the display
+ virtual DisplayId getId() const = 0;
// True if the display is secure
virtual bool isSecure() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 6bc677d..95ba9f0 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
@@ -20,12 +20,14 @@
#include <optional>
#include <string>
+#include <ui/DisplayId.h>
#include <ui/DisplayInfo.h>
#include <ui/PixelFormat.h>
#include <ui/Size.h>
#include "DisplayHardware/DisplayIdentification.h"
#include "DisplayHardware/PowerAdvisor.h"
+#include "DisplayIdGenerator.h"
namespace android::compositionengine {
@@ -65,6 +67,9 @@
// Debugging. Human readable name for the display.
std::string name;
+
+ // Generator for IDs of virtual displays, which are backed by the GPU.
+ DisplayIdGenerator<GpuVirtualDisplayId>* gpuVirtualDisplayIdGenerator;
};
/**
@@ -95,6 +100,12 @@
return *this;
}
+ DisplayCreationArgsBuilder& setGpuVirtualDisplayIdGenerator(
+ DisplayIdGenerator<GpuVirtualDisplayId>& generator) {
+ mArgs.gpuVirtualDisplayIdGenerator = &generator;
+ return *this;
+ }
+
DisplayCreationArgsBuilder& setIsSecure(bool isSecure) {
mArgs.isSecure = isSecure;
return *this;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index 7a4f738..54e91ae 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -57,7 +57,7 @@
void finishFrame(const CompositionRefreshArgs&) override;
// compositionengine::Display overrides
- const std::optional<DisplayId>& getId() const override;
+ DisplayId getId() const override;
bool isSecure() const override;
bool isVirtual() const override;
void disconnect() override;
@@ -85,12 +85,14 @@
std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;
// Testing
- void setDisplayIdForTesting(std::optional<DisplayId> displayId);
+ void setDisplayIdForTesting(DisplayId displayId);
private:
bool mIsVirtual = false;
- std::optional<DisplayId> mId;
+ bool mIsDisconnected = false;
+ DisplayId mId;
Hwc2::PowerAdvisor* mPowerAdvisor = nullptr;
+ DisplayIdGenerator<GpuVirtualDisplayId>* mGpuVirtualDisplayIdGenerator;
};
// This template factory function standardizes the implementation details of the
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
index 3a4c70f..08a8b84 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
@@ -32,7 +32,7 @@
Display();
virtual ~Display();
- MOCK_CONST_METHOD0(getId, const std::optional<DisplayId>&());
+ MOCK_CONST_METHOD0(getId, DisplayId());
MOCK_CONST_METHOD0(isSecure, bool());
MOCK_CONST_METHOD0(isVirtual, bool());
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 5459861..0b0b8d5 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -51,19 +51,26 @@
void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) {
mIsVirtual = !args.physical;
- mId = args.physical ? std::make_optional(args.physical->id) : std::nullopt;
mPowerAdvisor = args.powerAdvisor;
-
editState().isSecure = args.isSecure;
editState().displaySpace.bounds = Rect(args.pixels);
-
setLayerStackFilter(args.layerStackId,
- args.physical ? args.physical->type == DisplayConnectionType::Internal
- : false);
+ args.physical && args.physical->type == DisplayConnectionType::Internal);
setName(args.name);
+ mGpuVirtualDisplayIdGenerator = args.gpuVirtualDisplayIdGenerator;
- if (!args.physical && args.useHwcVirtualDisplays) {
- mId = maybeAllocateDisplayIdForVirtualDisplay(args.pixels, args.pixelFormat);
+ if (args.physical) {
+ mId = args.physical->id;
+ } else {
+ std::optional<DisplayId> id;
+ if (args.useHwcVirtualDisplays) {
+ id = maybeAllocateDisplayIdForVirtualDisplay(args.pixels, args.pixelFormat);
+ }
+ if (!id) {
+ id = mGpuVirtualDisplayIdGenerator->nextId();
+ }
+ LOG_ALWAYS_FATAL_IF(!id, "Failed to generate display ID");
+ mId = *id;
}
}
@@ -78,7 +85,7 @@
return Output::isValid() && mPowerAdvisor;
}
-const std::optional<DisplayId>& Display::getId() const {
+DisplayId Display::getId() const {
return mId;
}
@@ -94,31 +101,36 @@
return mId;
}
-void Display::setDisplayIdForTesting(std::optional<DisplayId> displayId) {
+void Display::setDisplayIdForTesting(DisplayId displayId) {
mId = displayId;
}
void Display::disconnect() {
- if (!mId) {
+ if (mIsDisconnected) {
return;
}
- auto& hwc = getCompositionEngine().getHwComposer();
- hwc.disconnectDisplay(*mId);
- mId.reset();
+ mIsDisconnected = true;
+ if (const auto id = GpuVirtualDisplayId::tryCast(mId)) {
+ mGpuVirtualDisplayIdGenerator->markUnused(*id);
+ return;
+ }
+ const auto halDisplayId = HalDisplayId::tryCast(mId);
+ LOG_FATAL_IF(!halDisplayId);
+ getCompositionEngine().getHwComposer().disconnectDisplay(*halDisplayId);
}
void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
Output::setColorTransform(args);
-
- if (!mId || CC_LIKELY(!args.colorTransformMatrix)) {
+ const auto halDisplayId = HalDisplayId::tryCast(mId);
+ if (mIsDisconnected || !halDisplayId || CC_LIKELY(!args.colorTransformMatrix)) {
return;
}
auto& hwc = getCompositionEngine().getHwComposer();
- status_t result = hwc.setColorTransform(*mId, *args.colorTransformMatrix);
+ status_t result = hwc.setColorTransform(*halDisplayId, *args.colorTransformMatrix);
ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display \"%s\": %d",
- mId ? to_string(*mId).c_str() : "", result);
+ to_string(mId).c_str(), result);
}
void Display::setColorProfile(const ColorProfile& colorProfile) {
@@ -140,8 +152,10 @@
Output::setColorProfile(colorProfile);
- auto& hwc = getCompositionEngine().getHwComposer();
- hwc.setActiveColorMode(*mId, colorProfile.mode, colorProfile.renderIntent);
+ const auto physicalId = PhysicalDisplayId::tryCast(mId);
+ LOG_FATAL_IF(!physicalId);
+ getCompositionEngine().getHwComposer().setActiveColorMode(*physicalId, colorProfile.mode,
+ colorProfile.renderIntent);
}
void Display::dump(std::string& out) const {
@@ -150,14 +164,8 @@
StringAppendF(&out, " Composition Display State: [\"%s\"]", getName().c_str());
out.append("\n ");
-
dumpVal(out, "isVirtual", mIsVirtual);
- if (mId) {
- dumpVal(out, "hwcId", to_string(*mId));
- } else {
- StringAppendF(&out, "no hwcId, ");
- }
-
+ dumpVal(out, "DisplayId", to_string(mId));
out.append("\n");
Output::dumpBase(out);
@@ -178,31 +186,33 @@
std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
const sp<compositionengine::LayerFE>& layerFE) const {
- auto result = impl::createOutputLayer(*this, layerFE);
+ auto outputLayer = impl::createOutputLayer(*this, layerFE);
- if (result && mId) {
+ if (const auto halDisplayId = HalDisplayId::tryCast(mId);
+ outputLayer && !mIsDisconnected && halDisplayId) {
auto& hwc = getCompositionEngine().getHwComposer();
- auto displayId = *mId;
// Note: For the moment we ensure it is safe to take a reference to the
// HWComposer implementation by destroying all the OutputLayers (and
// hence the HWC2::Layers they own) before setting a new HWComposer. See
// for example SurfaceFlinger::updateVrFlinger().
// TODO(b/121291683): Make this safer.
- auto hwcLayer = std::shared_ptr<HWC2::Layer>(hwc.createLayer(displayId),
- [&hwc, displayId](HWC2::Layer* layer) {
- hwc.destroyLayer(displayId, layer);
- });
+ auto hwcLayer =
+ std::shared_ptr<HWC2::Layer>(hwc.createLayer(*halDisplayId),
+ [&hwc, id = *halDisplayId](HWC2::Layer* layer) {
+ hwc.destroyLayer(id, layer);
+ });
ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
getName().c_str());
- result->setHwcLayer(std::move(hwcLayer));
+ outputLayer->setHwcLayer(std::move(hwcLayer));
}
- return result;
+ return outputLayer;
}
void Display::setReleasedLayers(const compositionengine::CompositionRefreshArgs& refreshArgs) {
Output::setReleasedLayers(refreshArgs);
- if (!mId || refreshArgs.layersWithQueuedFrames.empty()) {
+ if (mIsDisconnected || GpuVirtualDisplayId::tryCast(mId) ||
+ refreshArgs.layersWithQueuedFrames.empty()) {
return;
}
@@ -238,19 +248,25 @@
ATRACE_CALL();
ALOGV(__FUNCTION__);
+ if (mIsDisconnected) {
+ return;
+ }
+
// Default to the base settings -- client composition only.
Output::chooseCompositionStrategy();
- // If we don't have a HWC display, then we are done
- if (!mId) {
+ // If we don't have a HWC display, then we are done.
+ const auto halDisplayId = HalDisplayId::tryCast(mId);
+ if (!halDisplayId) {
return;
}
// Get any composition changes requested by the HWC device, and apply them.
std::optional<android::HWComposer::DeviceRequestedChanges> changes;
auto& hwc = getCompositionEngine().getHwComposer();
- if (status_t result = hwc.getDeviceCompositionChanges(*mId, anyLayersRequireClientComposition(),
- &changes);
+ if (status_t result =
+ hwc.getDeviceCompositionChanges(*halDisplayId, anyLayersRequireClientComposition(),
+ &changes);
result != NO_ERROR) {
ALOGE("chooseCompositionStrategy failed for %s: %d (%s)", getName().c_str(), result,
strerror(-result));
@@ -271,8 +287,12 @@
bool Display::getSkipColorTransform() const {
const auto& hwc = getCompositionEngine().getHwComposer();
- return mId ? hwc.hasDisplayCapability(*mId, hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM)
- : hwc.hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM);
+ if (const auto halDisplayId = HalDisplayId::tryCast(mId)) {
+ return hwc.hasDisplayCapability(*halDisplayId,
+ hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
+ }
+
+ return hwc.hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM);
}
bool Display::anyLayersRequireClientComposition() const {
@@ -339,16 +359,17 @@
}
compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
- auto result = impl::Output::presentAndGetFrameFences();
+ auto fences = impl::Output::presentAndGetFrameFences();
- if (!mId) {
- return result;
+ const auto halDisplayIdOpt = HalDisplayId::tryCast(mId);
+ if (mIsDisconnected || !halDisplayIdOpt) {
+ return fences;
}
auto& hwc = getCompositionEngine().getHwComposer();
- hwc.presentAndGetReleaseFences(*mId);
+ hwc.presentAndGetReleaseFences(*halDisplayIdOpt);
- result.presentFence = hwc.getPresentFence(*mId);
+ fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
// TODO(b/121291683): Change HWComposer call to return entire map
for (const auto* layer : getOutputLayersOrderedByZ()) {
@@ -357,19 +378,19 @@
continue;
}
- result.layerFences.emplace(hwcLayer, hwc.getLayerReleaseFence(*mId, hwcLayer));
+ fences.layerFences.emplace(hwcLayer, hwc.getLayerReleaseFence(*halDisplayIdOpt, hwcLayer));
}
- hwc.clearReleaseFences(*mId);
+ hwc.clearReleaseFences(*halDisplayIdOpt);
- return result;
+ return fences;
}
void Display::setExpensiveRenderingExpected(bool enabled) {
Output::setExpensiveRenderingExpected(enabled);
- if (mPowerAdvisor && mId) {
- mPowerAdvisor->setExpensiveRenderingExpected(*mId, enabled);
+ if (mPowerAdvisor && !GpuVirtualDisplayId::tryCast(mId)) {
+ mPowerAdvisor->setExpensiveRenderingExpected(mId, enabled);
}
}
@@ -378,11 +399,10 @@
// 1) It is being handled by hardware composer, which may need this to
// keep its virtual display state machine in sync, or
// 2) There is work to be done (the dirty region isn't empty)
- if (!mId) {
- if (getDirtyRegion(refreshArgs.repaintEverything).isEmpty()) {
- ALOGV("Skipping display composition");
- return;
- }
+ if (GpuVirtualDisplayId::tryCast(mId) &&
+ getDirtyRegion(refreshArgs.repaintEverything).isEmpty()) {
+ ALOGV("Skipping display composition");
+ return;
}
impl::Output::finishFrame(refreshArgs);
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 4519a9d..6d01bf1 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -176,6 +176,7 @@
DisplayCreationArgs getDisplayCreationArgsForNonHWCVirtualDisplay() {
return DisplayCreationArgsBuilder()
.setUseHwcVirtualDisplays(false)
+ .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator)
.setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT})
.setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888))
.setIsSecure(false)
@@ -189,6 +190,7 @@
StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
StrictMock<mock::CompositionEngine> mCompositionEngine;
sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>();
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> mGpuDisplayIdGenerator;
};
struct PartialMockDisplayTestCommon : public DisplayTestCommon {
@@ -245,7 +247,7 @@
getDisplayCreationArgsForNonHWCVirtualDisplay());
EXPECT_FALSE(display->isSecure());
EXPECT_TRUE(display->isVirtual());
- EXPECT_EQ(std::nullopt, display->getId());
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(display->getId()));
}
/*
@@ -332,6 +334,7 @@
mDisplay->setConfiguration(
DisplayCreationArgsBuilder()
.setUseHwcVirtualDisplays(true)
+ .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator)
.setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH))
.setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888))
.setIsSecure(false)
@@ -340,7 +343,7 @@
.setName(getDisplayNameFromCurrentTest())
.build());
- EXPECT_EQ(std::nullopt, mDisplay->getId());
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(mDisplay->getId()));
EXPECT_FALSE(mDisplay->isSecure());
EXPECT_TRUE(mDisplay->isVirtual());
EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId);
@@ -352,6 +355,7 @@
mDisplay->setConfiguration(
DisplayCreationArgsBuilder()
.setUseHwcVirtualDisplays(false)
+ .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator)
.setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH))
.setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888))
.setIsSecure(false)
@@ -360,7 +364,7 @@
.setName(getDisplayNameFromCurrentTest())
.build());
- EXPECT_EQ(std::nullopt, mDisplay->getId());
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(mDisplay->getId()));
EXPECT_FALSE(mDisplay->isSecure());
EXPECT_TRUE(mDisplay->isVirtual());
EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId);
@@ -375,16 +379,13 @@
using DisplayDisconnectTest = PartialMockDisplayTestCommon;
TEST_F(DisplayDisconnectTest, disconnectsDisplay) {
- // The first call to disconnect will disconnect the display with the HWC and
- // set mHwcId to -1.
- EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(1);
+ // The first call to disconnect will disconnect the display with the HWC.
+ EXPECT_CALL(mHwComposer, disconnectDisplay(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(1);
mDisplay->disconnect();
- EXPECT_FALSE(mDisplay->getId());
// Subsequent calls will do nothing,
- EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(0);
+ EXPECT_CALL(mHwComposer, disconnectDisplay(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(0);
mDisplay->disconnect();
- EXPECT_FALSE(mDisplay->getId());
}
/*
@@ -402,7 +403,8 @@
// Identity matrix sets an identity state value
const mat4 kIdentity;
- EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kIdentity)).Times(1);
+ EXPECT_CALL(mHwComposer, setColorTransform(HalDisplayId(DEFAULT_DISPLAY_ID), kIdentity))
+ .Times(1);
refreshArgs.colorTransformMatrix = kIdentity;
mDisplay->setColorTransform(refreshArgs);
@@ -410,7 +412,8 @@
// Non-identity matrix sets a non-identity state value
const mat4 kNonIdentity = mat4() * 2;
- EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kNonIdentity)).Times(1);
+ EXPECT_CALL(mHwComposer, setColorTransform(HalDisplayId(DEFAULT_DISPLAY_ID), kNonIdentity))
+ .Times(1);
refreshArgs.colorTransformMatrix = kNonIdentity;
mDisplay->setColorTransform(refreshArgs);
@@ -527,13 +530,14 @@
sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
StrictMock<HWC2::mock::Layer> hwcLayer;
- EXPECT_CALL(mHwComposer, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
+ EXPECT_CALL(mHwComposer, createLayer(HalDisplayId(DEFAULT_DISPLAY_ID)))
+ .WillOnce(Return(&hwcLayer));
auto outputLayer = mDisplay->createOutputLayer(layerFE);
EXPECT_EQ(&hwcLayer, outputLayer->getHwcLayer());
- EXPECT_CALL(mHwComposer, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
+ EXPECT_CALL(mHwComposer, destroyLayer(HalDisplayId(DEFAULT_DISPLAY_ID), &hwcLayer));
outputLayer.reset();
}
@@ -606,7 +610,7 @@
auto args = getDisplayCreationArgsForNonHWCVirtualDisplay();
std::shared_ptr<Display> nonHwcDisplay =
createPartialMockDisplay<Display>(mCompositionEngine, args);
- EXPECT_FALSE(nonHwcDisplay->getId());
+ EXPECT_TRUE(GpuVirtualDisplayId::tryCast(nonHwcDisplay->getId()));
nonHwcDisplay->chooseCompositionStrategy();
@@ -617,7 +621,8 @@
TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) {
EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false));
- EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, false, _))
+ EXPECT_CALL(mHwComposer,
+ getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), false, _))
.WillOnce(Return(INVALID_OPERATION));
mDisplay->chooseCompositionStrategy();
@@ -639,7 +644,7 @@
.InSequence(s)
.WillOnce(Return(false));
- EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
+ EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _))
.WillOnce(Return(NO_ERROR));
EXPECT_CALL(*mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
@@ -669,7 +674,7 @@
.InSequence(s)
.WillOnce(Return(false));
- EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
+ EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _))
.WillOnce(DoAll(SetArgPointee<2>(changes), Return(NO_ERROR)));
EXPECT_CALL(*mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1);
EXPECT_CALL(*mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1);
@@ -699,7 +704,7 @@
TEST_F(DisplayGetSkipColorTransformTest, checksDisplayCapability) {
EXPECT_CALL(mHwComposer,
- hasDisplayCapability(DEFAULT_DISPLAY_ID,
+ hasDisplayCapability(HalDisplayId(DEFAULT_DISPLAY_ID),
hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM))
.WillOnce(Return(true));
EXPECT_TRUE(mDisplay->getSkipColorTransform());
@@ -857,13 +862,16 @@
sp<Fence> layer1Fence = new Fence();
sp<Fence> layer2Fence = new Fence();
- EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
- EXPECT_CALL(mHwComposer, getPresentFence(DEFAULT_DISPLAY_ID)).WillOnce(Return(presentFence));
- EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mLayer1.hwc2Layer))
+ EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(1);
+ EXPECT_CALL(mHwComposer, getPresentFence(HalDisplayId(DEFAULT_DISPLAY_ID)))
+ .WillOnce(Return(presentFence));
+ EXPECT_CALL(mHwComposer,
+ getLayerReleaseFence(HalDisplayId(DEFAULT_DISPLAY_ID), &mLayer1.hwc2Layer))
.WillOnce(Return(layer1Fence));
- EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mLayer2.hwc2Layer))
+ EXPECT_CALL(mHwComposer,
+ getLayerReleaseFence(HalDisplayId(DEFAULT_DISPLAY_ID), &mLayer2.hwc2Layer))
.WillOnce(Return(layer2Fence));
- EXPECT_CALL(mHwComposer, clearReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
+ EXPECT_CALL(mHwComposer, clearReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(1);
auto result = mDisplay->presentAndGetFrameFences();
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 1dd5df4..b5cda68 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -42,63 +42,68 @@
MOCK_CONST_METHOD3(getDisplayIdentificationData,
bool(hal::HWDisplayId, uint8_t*, DisplayIdentificationData*));
MOCK_CONST_METHOD1(hasCapability, bool(hal::Capability));
- MOCK_CONST_METHOD2(hasDisplayCapability, bool(DisplayId, hal::DisplayCapability));
+ MOCK_CONST_METHOD2(hasDisplayCapability, bool(HalDisplayId, hal::DisplayCapability));
MOCK_METHOD3(allocateVirtualDisplay,
std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId));
- MOCK_METHOD1(createLayer, HWC2::Layer*(DisplayId));
- MOCK_METHOD2(destroyLayer, void(DisplayId, HWC2::Layer*));
+ MOCK_METHOD1(createLayer, HWC2::Layer*(HalDisplayId));
+ MOCK_METHOD2(destroyLayer, void(HalDisplayId, HWC2::Layer*));
MOCK_METHOD3(getDeviceCompositionChanges,
- status_t(DisplayId, bool,
+ status_t(HalDisplayId, bool,
std::optional<android::HWComposer::DeviceRequestedChanges>*));
MOCK_METHOD5(setClientTarget,
- status_t(DisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
+ status_t(HalDisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
ui::Dataspace));
- MOCK_METHOD1(presentAndGetReleaseFences, status_t(DisplayId));
- MOCK_METHOD2(setPowerMode, status_t(DisplayId, hal::PowerMode));
- MOCK_METHOD2(setActiveConfig, status_t(DisplayId, size_t));
- MOCK_METHOD2(setColorTransform, status_t(DisplayId, const mat4&));
- MOCK_METHOD1(disconnectDisplay, void(DisplayId));
+ MOCK_METHOD1(presentAndGetReleaseFences, status_t(HalDisplayId));
+ MOCK_METHOD2(setPowerMode, status_t(PhysicalDisplayId, hal::PowerMode));
+ MOCK_METHOD2(setActiveConfig, status_t(HalDisplayId, size_t));
+ MOCK_METHOD2(setColorTransform, status_t(HalDisplayId, const mat4&));
+ MOCK_METHOD1(disconnectDisplay, void(HalDisplayId));
MOCK_CONST_METHOD1(hasDeviceComposition, bool(const std::optional<DisplayId>&));
- MOCK_CONST_METHOD1(getPresentFence, sp<Fence>(DisplayId));
- MOCK_CONST_METHOD2(getLayerReleaseFence, sp<Fence>(DisplayId, HWC2::Layer*));
- MOCK_METHOD3(setOutputBuffer, status_t(DisplayId, const sp<Fence>&, const sp<GraphicBuffer>&));
- MOCK_METHOD1(clearReleaseFences, void(DisplayId));
- MOCK_METHOD2(getHdrCapabilities, status_t(DisplayId, HdrCapabilities*));
- MOCK_CONST_METHOD1(getSupportedPerFrameMetadata, int32_t(DisplayId));
- MOCK_CONST_METHOD2(getRenderIntents, std::vector<ui::RenderIntent>(DisplayId, ui::ColorMode));
- MOCK_METHOD2(getDataspaceSaturationMatrix, mat4(DisplayId, ui::Dataspace));
+ MOCK_CONST_METHOD1(getPresentFence, sp<Fence>(HalDisplayId));
+ MOCK_CONST_METHOD2(getLayerReleaseFence, sp<Fence>(HalDisplayId, HWC2::Layer*));
+ MOCK_METHOD3(setOutputBuffer,
+ status_t(HalVirtualDisplayId, const sp<Fence>&, const sp<GraphicBuffer>&));
+ MOCK_METHOD1(clearReleaseFences, void(HalDisplayId));
+ MOCK_METHOD2(getHdrCapabilities, status_t(HalDisplayId, HdrCapabilities*));
+ MOCK_CONST_METHOD1(getSupportedPerFrameMetadata, int32_t(HalDisplayId));
+ MOCK_CONST_METHOD2(getRenderIntents,
+ std::vector<ui::RenderIntent>(HalDisplayId, ui::ColorMode));
+ MOCK_METHOD2(getDataspaceSaturationMatrix, mat4(HalDisplayId, ui::Dataspace));
MOCK_METHOD4(getDisplayedContentSamplingAttributes,
- status_t(DisplayId, ui::PixelFormat*, ui::Dataspace*, uint8_t*));
- MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(DisplayId, bool, uint8_t, uint64_t));
+ status_t(HalDisplayId, ui::PixelFormat*, ui::Dataspace*, uint8_t*));
+ MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(HalDisplayId, bool, uint8_t, uint64_t));
MOCK_METHOD4(getDisplayedContentSample,
- status_t(DisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
- MOCK_METHOD2(setDisplayBrightness, std::future<status_t>(DisplayId, float));
- MOCK_METHOD2(getDisplayBrightnessSupport, status_t(DisplayId, bool*));
+ status_t(HalDisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
+ MOCK_METHOD2(setDisplayBrightness, std::future<status_t>(PhysicalDisplayId, float));
+ MOCK_METHOD2(getDisplayBrightnessSupport, status_t(PhysicalDisplayId, bool*));
MOCK_METHOD2(onHotplug,
std::optional<DisplayIdentificationInfo>(hal::HWDisplayId, hal::Connection));
MOCK_METHOD2(onVsync, bool(hal::HWDisplayId, int64_t));
- MOCK_METHOD2(setVsyncEnabled, void(DisplayId, hal::Vsync));
- MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(DisplayId));
- MOCK_CONST_METHOD1(isConnected, bool(DisplayId));
- MOCK_CONST_METHOD1(getConfigs,
- std::vector<std::shared_ptr<const HWC2::Display::Config>>(DisplayId));
- MOCK_CONST_METHOD1(getActiveConfig, std::shared_ptr<const HWC2::Display::Config>(DisplayId));
- MOCK_CONST_METHOD1(getActiveConfigIndex, int(DisplayId));
- MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(DisplayId));
- MOCK_METHOD3(setActiveColorMode, status_t(DisplayId, ui::ColorMode, ui::RenderIntent));
+ MOCK_METHOD2(setVsyncEnabled, void(PhysicalDisplayId, hal::Vsync));
+ MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(isConnected, bool(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(
+ getConfigs,
+ std::vector<std::shared_ptr<const HWC2::Display::Config>>(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getActiveConfig,
+ std::shared_ptr<const HWC2::Display::Config>(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getActiveConfigIndex, int(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(PhysicalDisplayId));
+ MOCK_METHOD3(setActiveColorMode, status_t(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent));
MOCK_CONST_METHOD0(isUsingVrComposer, bool());
- MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(DisplayId));
- MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(DisplayId));
- MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(DisplayId));
+ MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(PhysicalDisplayId));
+ MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(PhysicalDisplayId));
MOCK_METHOD4(setActiveConfigWithConstraints,
- status_t(DisplayId, size_t, const hal::VsyncPeriodChangeConstraints&,
+ status_t(PhysicalDisplayId, size_t, const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline*));
- MOCK_METHOD2(setAutoLowLatencyMode, status_t(DisplayId, bool));
- MOCK_METHOD2(getSupportedContentTypes, status_t(DisplayId, std::vector<hal::ContentType>*));
- MOCK_METHOD2(setContentType, status_t(DisplayId, hal::ContentType));
+ MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool));
+ MOCK_METHOD2(getSupportedContentTypes,
+ status_t(PhysicalDisplayId, std::vector<hal::ContentType>*));
+ MOCK_METHOD2(setContentType, status_t(PhysicalDisplayId, hal::ContentType));
MOCK_CONST_METHOD0(getSupportedLayerGenericMetadata,
const std::unordered_map<std::string, bool>&());
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 8d1eb36..6ce8a6b 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -33,7 +33,7 @@
constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920;
constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080;
-constexpr std::optional<DisplayId> DEFAULT_DISPLAY_ID = {PhysicalDisplayId(123u)};
+constexpr DisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId(123u);
const std::string DEFAULT_DISPLAY_NAME = "Mock Display";
using testing::_;
@@ -48,7 +48,7 @@
class RenderSurfaceTest : public testing::Test {
public:
RenderSurfaceTest() {
- EXPECT_CALL(mDisplay, getId()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_ID));
+ EXPECT_CALL(mDisplay, getId()).WillRepeatedly(Return(DEFAULT_DISPLAY_ID));
EXPECT_CALL(mDisplay, getName()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_NAME));
EXPECT_CALL(mCompositionEngine, getRenderEngine).WillRepeatedly(ReturnRef(mRenderEngine));
EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL))
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 3b7cfb9..5bd7a1f 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -195,17 +195,12 @@
}
std::string DisplayDevice::getDebugName() const {
- std::string displayId;
- if (const auto id = getId()) {
- displayId = to_string(*id) + ", ";
- }
-
const char* type = "virtual";
if (mConnectionType) {
type = *mConnectionType == DisplayConnectionType::Internal ? "internal" : "external";
}
- return base::StringPrintf("DisplayDevice{%s%s%s, \"%s\"}", displayId.c_str(), type,
+ return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type,
isPrimary() ? ", primary" : "", mDisplayName.c_str());
}
@@ -229,9 +224,7 @@
return mCompositionDisplay->getDisplayColorProfile()->hasRenderIntent(intent);
}
-// ----------------------------------------------------------------------------
-
-const std::optional<DisplayId>& DisplayDevice::getId() const {
+DisplayId DisplayDevice::getId() const {
return mCompositionDisplay->getId();
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 35a8b62..fa684c0 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -27,6 +27,7 @@
#include <math/mat4.h>
#include <renderengine/RenderEngine.h>
#include <system/window.h>
+#include <ui/DisplayId.h>
#include <ui/DisplayInfo.h>
#include <ui/DisplayState.h>
#include <ui/GraphicTypes.h>
@@ -104,7 +105,15 @@
bool needsFiltering() const;
ui::LayerStack getLayerStack() const;
- const std::optional<DisplayId>& getId() const;
+ // Returns the physical ID of this display. This function asserts the ID is physical and it
+ // shouldn't be called for other display types, e.g. virtual.
+ PhysicalDisplayId getPhysicalId() const {
+ const auto displayIdOpt = PhysicalDisplayId::tryCast(getId());
+ LOG_FATAL_IF(!displayIdOpt);
+ return *displayIdOpt;
+ }
+
+ DisplayId getId() const;
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
int32_t getSequenceId() const { return mSequenceId; }
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 4c3b3e5..14b54cd 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -56,7 +56,7 @@
*
*/
-FramebufferSurface::FramebufferSurface(HWComposer& hwc, DisplayId displayId,
+FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
const sp<IGraphicBufferConsumer>& consumer,
uint32_t maxWidth, uint32_t maxHeight)
: ConsumerBase(consumer),
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index a1859f3..759943a 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -23,6 +23,7 @@
#include <compositionengine/DisplaySurface.h>
#include <compositionengine/impl/HwcBufferCache.h>
#include <gui/ConsumerBase.h>
+#include <ui/DisplayId.h>
#include <ui/Size.h>
#include "DisplayIdentification.h"
@@ -39,7 +40,7 @@
class FramebufferSurface : public ConsumerBase, public compositionengine::DisplaySurface {
public:
- FramebufferSurface(HWComposer& hwc, DisplayId displayId,
+ FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
const sp<IGraphicBufferConsumer>& consumer, uint32_t maxWidth,
uint32_t maxHeight);
@@ -69,7 +70,7 @@
status_t nextBuffer(uint32_t& outSlot, sp<GraphicBuffer>& outBuffer,
sp<Fence>& outFence, ui::Dataspace& outDataspace);
- const DisplayId mDisplayId;
+ const PhysicalDisplayId mDisplayId;
// Framebuffer size has a dimension limitation in pixels based on the graphics capabilities of
// the device.
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 1f03787..89df84b 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -240,15 +240,14 @@
class Display : public HWC2::Display {
public:
- Display(android::Hwc2::Composer& composer,
- const std::unordered_set<hal::Capability>& capabilities, hal::HWDisplayId id,
- hal::DisplayType type);
+ Display(android::Hwc2::Composer&, const std::unordered_set<hal::Capability>&, hal::HWDisplayId,
+ hal::DisplayType);
~Display() override;
// Required by HWC2
hal::Error acceptChanges() override;
hal::Error createLayer(Layer** outLayer) override;
- hal::Error destroyLayer(Layer* layer) override;
+ hal::Error destroyLayer(Layer*) override;
hal::Error getActiveConfig(std::shared_ptr<const Config>* outConfig) const override;
hal::Error getActiveConfigIndex(int* outIndex) const override;
hal::Error getChangedCompositionTypes(
@@ -258,8 +257,7 @@
int32_t getSupportedPerFrameMetadata() const override;
hal::Error getRenderIntents(hal::ColorMode colorMode,
std::vector<hal::RenderIntent>* outRenderIntents) const override;
- hal::Error getDataspaceSaturationMatrix(hal::Dataspace dataspace,
- android::mat4* outMatrix) override;
+ hal::Error getDataspaceSaturationMatrix(hal::Dataspace, android::mat4* outMatrix) override;
// Doesn't call into the HWC2 device, so no errors are possible
std::vector<std::shared_ptr<const Config>> getConfigs() const override;
@@ -285,11 +283,11 @@
hal::Error setClientTarget(uint32_t slot, const android::sp<android::GraphicBuffer>& target,
const android::sp<android::Fence>& acquireFence,
hal::Dataspace dataspace) override;
- hal::Error setColorMode(hal::ColorMode mode, hal::RenderIntent renderIntent) override;
+ hal::Error setColorMode(hal::ColorMode, hal::RenderIntent) override;
hal::Error setColorTransform(const android::mat4& matrix, hal::ColorTransform hint) override;
- hal::Error setOutputBuffer(const android::sp<android::GraphicBuffer>& buffer,
+ hal::Error setOutputBuffer(const android::sp<android::GraphicBuffer>&,
const android::sp<android::Fence>& releaseFence) override;
- hal::Error setPowerMode(hal::PowerMode mode) override;
+ hal::Error setPowerMode(hal::PowerMode) override;
hal::Error setVsyncEnabled(hal::Vsync enabled) override;
hal::Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests) override;
hal::Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
@@ -317,13 +315,13 @@
virtual bool isVsyncPeriodSwitchSupported() const override;
private:
- int32_t getAttribute(hal::HWConfigId configId, hal::Attribute attribute);
- void loadConfig(hal::HWConfigId configId);
+ int32_t getAttribute(hal::HWConfigId, hal::Attribute);
+ void loadConfig(hal::HWConfigId);
void loadConfigs();
// This may fail (and return a null pointer) if no layer with this ID exists
// on this display
- Layer* getLayerById(hal::HWLayerId id) const;
+ Layer* getLayerById(hal::HWLayerId) const;
friend android::TestableSurfaceFlinger;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 195182a..2fdbd3a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -186,7 +186,7 @@
return mCapabilities.count(capability) > 0;
}
-bool HWComposer::hasDisplayCapability(DisplayId displayId,
+bool HWComposer::hasDisplayCapability(HalDisplayId displayId,
hal::DisplayCapability capability) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
return mDisplayData.at(displayId).hwcDisplay->getCapabilities().count(capability) > 0;
@@ -214,10 +214,8 @@
RETURN_IF_INVALID_DISPLAY(*displayId, false);
auto& displayData = mDisplayData[*displayId];
- if (displayData.isVirtual) {
- LOG_DISPLAY_ERROR(*displayId, "Invalid operation on virtual display");
- return false;
- }
+ LOG_FATAL_IF(displayData.isVirtual, "%s: Invalid operation on virtual display with ID %s",
+ __FUNCTION__, to_string(*displayId).c_str());
{
std::lock_guard lock(displayData.lastHwVsyncLock);
@@ -244,11 +242,6 @@
std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
ui::PixelFormat* format) {
- if (mRemainingHwcVirtualDisplays == 0) {
- ALOGE("%s: No remaining virtual displays", __FUNCTION__);
- return {};
- }
-
if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
(width > SurfaceFlinger::maxVirtualDisplaySize ||
height > SurfaceFlinger::maxVirtualDisplaySize)) {
@@ -256,31 +249,28 @@
height, SurfaceFlinger::maxVirtualDisplaySize);
return {};
}
+
+ const auto displayId = mVirtualIdGenerator.nextId();
+ if (!displayId) {
+ ALOGE("%s: No remaining virtual displays", __FUNCTION__);
+ return {};
+ }
+
hal::HWDisplayId hwcDisplayId = 0;
const auto error = static_cast<hal::Error>(
mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId));
if (error != hal::Error::NONE) {
ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__);
+ mVirtualIdGenerator.markUnused(*displayId);
return {};
}
auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
hwcDisplayId, hal::DisplayType::VIRTUAL);
display->setConnected(true);
-
- DisplayId displayId;
- if (mFreeVirtualDisplayIds.empty()) {
- displayId = getVirtualDisplayId(mNextVirtualDisplayId++);
- } else {
- displayId = *mFreeVirtualDisplayIds.begin();
- mFreeVirtualDisplayIds.erase(displayId);
- }
-
- auto& displayData = mDisplayData[displayId];
+ auto& displayData = mDisplayData[*displayId];
displayData.hwcDisplay = std::move(display);
displayData.isVirtual = true;
-
- --mRemainingHwcVirtualDisplays;
return displayId;
}
@@ -301,7 +291,7 @@
mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
}
-HWC2::Layer* HWComposer::createLayer(DisplayId displayId) {
+HWC2::Layer* HWComposer::createLayer(HalDisplayId displayId) {
RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
HWC2::Layer* layer;
@@ -310,14 +300,14 @@
return layer;
}
-void HWComposer::destroyLayer(DisplayId displayId, HWC2::Layer* layer) {
+void HWComposer::destroyLayer(HalDisplayId displayId, HWC2::Layer* layer) {
RETURN_IF_INVALID_DISPLAY(displayId);
auto error = mDisplayData[displayId].hwcDisplay->destroyLayer(layer);
RETURN_IF_HWC_ERROR(error, displayId);
}
-nsecs_t HWComposer::getRefreshTimestamp(DisplayId displayId) const {
+nsecs_t HWComposer::getRefreshTimestamp(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, 0);
const auto& displayData = mDisplayData.at(displayId);
// this returns the last refresh timestamp.
@@ -329,13 +319,13 @@
return now - ((now - displayData.lastHwVsync) % vsyncPeriodNanos);
}
-bool HWComposer::isConnected(DisplayId displayId) const {
+bool HWComposer::isConnected(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
return mDisplayData.at(displayId).hwcDisplay->isConnected();
}
std::vector<std::shared_ptr<const HWC2::Display::Config>> HWComposer::getConfigs(
- DisplayId displayId) const {
+ PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, {});
const auto& displayData = mDisplayData.at(displayId);
@@ -349,7 +339,7 @@
}
std::shared_ptr<const HWC2::Display::Config> HWComposer::getActiveConfig(
- DisplayId displayId) const {
+ PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
std::shared_ptr<const HWC2::Display::Config> config;
@@ -371,7 +361,7 @@
// Composer 2.4
-DisplayConnectionType HWComposer::getDisplayConnectionType(DisplayId displayId) const {
+DisplayConnectionType HWComposer::getDisplayConnectionType(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, DisplayConnectionType::Internal);
const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
@@ -386,12 +376,12 @@
return type;
}
-bool HWComposer::isVsyncPeriodSwitchSupported(DisplayId displayId) const {
+bool HWComposer::isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
return mDisplayData.at(displayId).hwcDisplay->isVsyncPeriodSwitchSupported();
}
-nsecs_t HWComposer::getDisplayVsyncPeriod(DisplayId displayId) const {
+nsecs_t HWComposer::getDisplayVsyncPeriod(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, 0);
nsecs_t vsyncPeriodNanos;
@@ -400,7 +390,7 @@
return vsyncPeriodNanos;
}
-int HWComposer::getActiveConfigIndex(DisplayId displayId) const {
+int HWComposer::getActiveConfigIndex(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, -1);
int index;
@@ -420,7 +410,7 @@
return index;
}
-std::vector<ui::ColorMode> HWComposer::getColorModes(DisplayId displayId) const {
+std::vector<ui::ColorMode> HWComposer::getColorModes(PhysicalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, {});
std::vector<ui::ColorMode> modes;
@@ -429,7 +419,7 @@
return modes;
}
-status_t HWComposer::setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
+status_t HWComposer::setActiveColorMode(PhysicalDisplayId displayId, ui::ColorMode mode,
ui::RenderIntent renderIntent) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -443,14 +433,12 @@
return NO_ERROR;
}
-void HWComposer::setVsyncEnabled(DisplayId displayId, hal::Vsync enabled) {
+void HWComposer::setVsyncEnabled(PhysicalDisplayId displayId, hal::Vsync enabled) {
RETURN_IF_INVALID_DISPLAY(displayId);
auto& displayData = mDisplayData[displayId];
- if (displayData.isVirtual) {
- LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
- return;
- }
+ LOG_FATAL_IF(displayData.isVirtual, "%s: Invalid operation on virtual display with ID %s",
+ __FUNCTION__, to_string(displayId).c_str());
// NOTE: we use our own internal lock here because we have to call
// into the HWC with the lock held, and we want to make sure
@@ -471,7 +459,7 @@
ATRACE_INT(tag.c_str(), enabled == hal::Vsync::ENABLE ? 1 : 0);
}
-status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
+status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot,
const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
ui::Dataspace dataspace) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -484,7 +472,7 @@
}
status_t HWComposer::getDeviceCompositionChanges(
- DisplayId displayId, bool frameUsesClientComposition,
+ HalDisplayId displayId, bool frameUsesClientComposition,
std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
ATRACE_CALL();
@@ -554,12 +542,12 @@
return NO_ERROR;
}
-sp<Fence> HWComposer::getPresentFence(DisplayId displayId) const {
+sp<Fence> HWComposer::getPresentFence(HalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
return mDisplayData.at(displayId).lastPresentFence;
}
-sp<Fence> HWComposer::getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const {
+sp<Fence> HWComposer::getLayerReleaseFence(HalDisplayId displayId, HWC2::Layer* layer) const {
RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
const auto& displayFences = mDisplayData.at(displayId).releaseFences;
auto fence = displayFences.find(layer);
@@ -570,7 +558,7 @@
return fence->second;
}
-status_t HWComposer::presentAndGetReleaseFences(DisplayId displayId) {
+status_t HWComposer::presentAndGetReleaseFences(HalDisplayId displayId) {
ATRACE_CALL();
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -598,14 +586,12 @@
return NO_ERROR;
}
-status_t HWComposer::setPowerMode(DisplayId displayId, hal::PowerMode mode) {
+status_t HWComposer::setPowerMode(PhysicalDisplayId displayId, hal::PowerMode mode) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto& displayData = mDisplayData[displayId];
- if (displayData.isVirtual) {
- LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
- return INVALID_OPERATION;
- }
+ LOG_FATAL_IF(displayData.isVirtual, "%s: Invalid operation on virtual display with ID %s",
+ __FUNCTION__, to_string(displayId).c_str());
if (mode == hal::PowerMode::OFF) {
setVsyncEnabled(displayId, hal::Vsync::DISABLE);
@@ -654,7 +640,8 @@
}
status_t HWComposer::setActiveConfigWithConstraints(
- DisplayId displayId, size_t configId, const hal::VsyncPeriodChangeConstraints& constraints,
+ PhysicalDisplayId displayId, size_t configId,
+ const hal::VsyncPeriodChangeConstraints& constraints,
hal::VsyncPeriodChangeTimeline* outTimeline) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -671,7 +658,7 @@
return NO_ERROR;
}
-status_t HWComposer::setColorTransform(DisplayId displayId, const mat4& transform) {
+status_t HWComposer::setColorTransform(HalDisplayId displayId, const mat4& transform) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
auto& displayData = mDisplayData[displayId];
@@ -684,15 +671,14 @@
return NO_ERROR;
}
-void HWComposer::disconnectDisplay(DisplayId displayId) {
+void HWComposer::disconnectDisplay(HalDisplayId displayId) {
RETURN_IF_INVALID_DISPLAY(displayId);
auto& displayData = mDisplayData[displayId];
// If this was a virtual display, add its slot back for reuse by future
// virtual displays
if (displayData.isVirtual) {
- mFreeVirtualDisplayIds.insert(displayId);
- ++mRemainingHwcVirtualDisplays;
+ mVirtualIdGenerator.markUnused(*HalVirtualDisplayId::tryCast(displayId));
}
const auto hwcDisplayId = displayData.hwcDisplay->getId();
@@ -707,27 +693,25 @@
mDisplayData.erase(displayId);
}
-status_t HWComposer::setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
+status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& buffer) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto& displayData = mDisplayData[displayId];
- if (!displayData.isVirtual) {
- LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display");
- return INVALID_OPERATION;
- }
+ LOG_FATAL_IF(!displayData.isVirtual, "%s: Invalid operation on physical display with ID %s",
+ __FUNCTION__, to_string(displayId).c_str());
auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
return NO_ERROR;
}
-void HWComposer::clearReleaseFences(DisplayId displayId) {
+void HWComposer::clearReleaseFences(HalDisplayId displayId) {
RETURN_IF_INVALID_DISPLAY(displayId);
mDisplayData[displayId].releaseFences.clear();
}
-status_t HWComposer::getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) {
+status_t HWComposer::getHdrCapabilities(HalDisplayId displayId, HdrCapabilities* outCapabilities) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
@@ -736,12 +720,12 @@
return NO_ERROR;
}
-int32_t HWComposer::getSupportedPerFrameMetadata(DisplayId displayId) const {
+int32_t HWComposer::getSupportedPerFrameMetadata(HalDisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, 0);
return mDisplayData.at(displayId).hwcDisplay->getSupportedPerFrameMetadata();
}
-std::vector<ui::RenderIntent> HWComposer::getRenderIntents(DisplayId displayId,
+std::vector<ui::RenderIntent> HWComposer::getRenderIntents(HalDisplayId displayId,
ui::ColorMode colorMode) const {
RETURN_IF_INVALID_DISPLAY(displayId, {});
@@ -751,7 +735,7 @@
return renderIntents;
}
-mat4 HWComposer::getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) {
+mat4 HWComposer::getDataspaceSaturationMatrix(HalDisplayId displayId, ui::Dataspace dataspace) {
RETURN_IF_INVALID_DISPLAY(displayId, {});
mat4 matrix;
@@ -761,7 +745,7 @@
return matrix;
}
-status_t HWComposer::getDisplayedContentSamplingAttributes(DisplayId displayId,
+status_t HWComposer::getDisplayedContentSamplingAttributes(HalDisplayId displayId,
ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask) {
@@ -775,7 +759,7 @@
return NO_ERROR;
}
-status_t HWComposer::setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
+status_t HWComposer::setDisplayContentSamplingEnabled(HalDisplayId displayId, bool enabled,
uint8_t componentMask, uint64_t maxFrames) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error =
@@ -789,7 +773,7 @@
return NO_ERROR;
}
-status_t HWComposer::getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames,
+status_t HWComposer::getDisplayedContentSample(HalDisplayId displayId, uint64_t maxFrames,
uint64_t timestamp, DisplayedFrameStats* outStats) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error =
@@ -799,7 +783,8 @@
return NO_ERROR;
}
-std::future<status_t> HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
+std::future<status_t> HWComposer::setDisplayBrightness(PhysicalDisplayId displayId,
+ float brightness) {
RETURN_IF_INVALID_DISPLAY(displayId, promise::yield<status_t>(BAD_INDEX));
auto& display = mDisplayData[displayId].hwcDisplay;
@@ -816,7 +801,7 @@
});
}
-status_t HWComposer::setAutoLowLatencyMode(DisplayId displayId, bool on) {
+status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
if (error == hal::Error::UNSUPPORTED) {
@@ -830,7 +815,7 @@
}
status_t HWComposer::getSupportedContentTypes(
- DisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) {
+ PhysicalDisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error =
mDisplayData[displayId].hwcDisplay->getSupportedContentTypes(outSupportedContentTypes);
@@ -840,7 +825,7 @@
return NO_ERROR;
}
-status_t HWComposer::setContentType(DisplayId displayId, hal::ContentType contentType) {
+status_t HWComposer::setContentType(PhysicalDisplayId displayId, hal::ContentType contentType) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error = mDisplayData[displayId].hwcDisplay->setContentType(contentType);
if (error == hal::Error::UNSUPPORTED) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 488cdc5..028a9a4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -38,6 +38,7 @@
#include <utils/StrongPointer.h>
#include <utils/Timers.h>
+#include "DisplayIdGenerator.h"
#include "DisplayIdentification.h"
#include "HWC2.h"
#include "Hal.h"
@@ -88,7 +89,7 @@
DisplayIdentificationData* outData) const = 0;
virtual bool hasCapability(hal::Capability) const = 0;
- virtual bool hasDisplayCapability(DisplayId, hal::DisplayCapability) const = 0;
+ virtual bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const = 0;
// Attempts to allocate a virtual display and returns its ID if created on the HWC device.
virtual std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
@@ -97,9 +98,9 @@
virtual void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) = 0;
// Attempts to create a new layer on this display
- virtual HWC2::Layer* createLayer(DisplayId) = 0;
+ virtual HWC2::Layer* createLayer(HalDisplayId) = 0;
// Destroy a previously created layer
- virtual void destroyLayer(DisplayId, HWC2::Layer*) = 0;
+ virtual void destroyLayer(HalDisplayId, HWC2::Layer*) = 0;
// Gets any required composition change requests from the HWC device.
//
@@ -109,61 +110,60 @@
// with fewer handshakes, but this does not work if client composition is
// expected.
virtual status_t getDeviceCompositionChanges(
- DisplayId, bool frameUsesClientComposition,
+ HalDisplayId, bool frameUsesClientComposition,
std::optional<DeviceRequestedChanges>* outChanges) = 0;
- virtual status_t setClientTarget(DisplayId, uint32_t slot, const sp<Fence>& acquireFence,
+ virtual status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& target, ui::Dataspace) = 0;
// Present layers to the display and read releaseFences.
- virtual status_t presentAndGetReleaseFences(DisplayId) = 0;
+ virtual status_t presentAndGetReleaseFences(HalDisplayId) = 0;
// set power mode
- virtual status_t setPowerMode(DisplayId, hal::PowerMode) = 0;
+ virtual status_t setPowerMode(PhysicalDisplayId, hal::PowerMode) = 0;
// Sets a color transform to be applied to the result of composition
- virtual status_t setColorTransform(DisplayId, const mat4& transform) = 0;
+ virtual status_t setColorTransform(HalDisplayId, const mat4& transform) = 0;
- // reset state when an external, non-virtual display is disconnected
- virtual void disconnectDisplay(DisplayId) = 0;
+ // reset state when a display is disconnected
+ virtual void disconnectDisplay(HalDisplayId) = 0;
// get the present fence received from the last call to present.
- virtual sp<Fence> getPresentFence(DisplayId) const = 0;
+ virtual sp<Fence> getPresentFence(HalDisplayId) const = 0;
// Get last release fence for the given layer
- virtual sp<Fence> getLayerReleaseFence(DisplayId, HWC2::Layer*) const = 0;
+ virtual sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const = 0;
// Set the output buffer and acquire fence for a virtual display.
- // Returns INVALID_OPERATION if displayId is not a virtual display.
- virtual status_t setOutputBuffer(DisplayId, const sp<Fence>& acquireFence,
+ virtual status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& buffer) = 0;
// After SurfaceFlinger has retrieved the release fences for all the frames,
// it can call this to clear the shared pointers in the release fence map
- virtual void clearReleaseFences(DisplayId) = 0;
+ virtual void clearReleaseFences(HalDisplayId) = 0;
// Fetches the HDR capabilities of the given display
- virtual status_t getHdrCapabilities(DisplayId, HdrCapabilities* outCapabilities) = 0;
+ virtual status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) = 0;
- virtual int32_t getSupportedPerFrameMetadata(DisplayId) const = 0;
+ virtual int32_t getSupportedPerFrameMetadata(HalDisplayId) const = 0;
// Returns the available RenderIntent of the given display.
- virtual std::vector<ui::RenderIntent> getRenderIntents(DisplayId, ui::ColorMode) const = 0;
+ virtual std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const = 0;
- virtual mat4 getDataspaceSaturationMatrix(DisplayId, ui::Dataspace) = 0;
+ virtual mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) = 0;
// Returns the attributes of the color sampling engine.
- virtual status_t getDisplayedContentSamplingAttributes(DisplayId, ui::PixelFormat* outFormat,
+ virtual status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask) = 0;
- virtual status_t setDisplayContentSamplingEnabled(DisplayId, bool enabled,
+ virtual status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled,
uint8_t componentMask,
uint64_t maxFrames) = 0;
- virtual status_t getDisplayedContentSample(DisplayId, uint64_t maxFrames, uint64_t timestamp,
+ virtual status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
DisplayedFrameStats* outStats) = 0;
// Sets the brightness of a display.
- virtual std::future<status_t> setDisplayBrightness(DisplayId, float brightness) = 0;
+ virtual std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) = 0;
// Events handling ---------------------------------------------------------
@@ -174,33 +174,35 @@
hal::Connection) = 0;
virtual bool onVsync(hal::HWDisplayId, int64_t timestamp) = 0;
- virtual void setVsyncEnabled(DisplayId, hal::Vsync enabled) = 0;
+ virtual void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0;
- virtual nsecs_t getRefreshTimestamp(DisplayId) const = 0;
- virtual bool isConnected(DisplayId) const = 0;
+ virtual nsecs_t getRefreshTimestamp(PhysicalDisplayId) const = 0;
+ virtual bool isConnected(PhysicalDisplayId) const = 0;
// Non-const because it can update configMap inside of mDisplayData
virtual std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
- DisplayId) const = 0;
+ PhysicalDisplayId) const = 0;
- virtual std::shared_ptr<const HWC2::Display::Config> getActiveConfig(DisplayId) const = 0;
- virtual int getActiveConfigIndex(DisplayId) const = 0;
+ virtual std::shared_ptr<const HWC2::Display::Config> getActiveConfig(
+ PhysicalDisplayId) const = 0;
+ virtual int getActiveConfigIndex(PhysicalDisplayId) const = 0;
- virtual std::vector<ui::ColorMode> getColorModes(DisplayId) const = 0;
+ virtual std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const = 0;
- virtual status_t setActiveColorMode(DisplayId, ui::ColorMode mode, ui::RenderIntent) = 0;
+ virtual status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode mode,
+ ui::RenderIntent) = 0;
// Composer 2.4
- virtual DisplayConnectionType getDisplayConnectionType(DisplayId) const = 0;
- virtual bool isVsyncPeriodSwitchSupported(DisplayId) const = 0;
- virtual nsecs_t getDisplayVsyncPeriod(DisplayId) const = 0;
+ virtual DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const = 0;
+ virtual bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const = 0;
+ virtual nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId) const = 0;
virtual status_t setActiveConfigWithConstraints(
- DisplayId, size_t configId, const hal::VsyncPeriodChangeConstraints&,
+ PhysicalDisplayId, size_t configId, const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
- virtual status_t setAutoLowLatencyMode(DisplayId, bool on) = 0;
+ virtual status_t setAutoLowLatencyMode(PhysicalDisplayId, bool on) = 0;
virtual status_t getSupportedContentTypes(
- DisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
- virtual status_t setContentType(DisplayId, hal::ContentType) = 0;
+ PhysicalDisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
+ virtual status_t setContentType(PhysicalDisplayId, hal::ContentType) = 0;
virtual const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata()
const = 0;
@@ -232,7 +234,7 @@
DisplayIdentificationData* outData) const override;
bool hasCapability(hal::Capability) const override;
- bool hasDisplayCapability(DisplayId, hal::DisplayCapability) const override;
+ bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const override;
// Attempts to allocate a virtual display and returns its ID if created on the HWC device.
std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
@@ -242,63 +244,62 @@
void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) override;
// Attempts to create a new layer on this display
- HWC2::Layer* createLayer(DisplayId) override;
+ HWC2::Layer* createLayer(HalDisplayId) override;
// Destroy a previously created layer
- void destroyLayer(DisplayId, HWC2::Layer*) override;
+ void destroyLayer(HalDisplayId, HWC2::Layer*) override;
status_t getDeviceCompositionChanges(
- DisplayId, bool frameUsesClientComposition,
+ HalDisplayId, bool frameUsesClientComposition,
std::optional<DeviceRequestedChanges>* outChanges) override;
- status_t setClientTarget(DisplayId, uint32_t slot, const sp<Fence>& acquireFence,
+ status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& target, ui::Dataspace) override;
// Present layers to the display and read releaseFences.
- status_t presentAndGetReleaseFences(DisplayId) override;
+ status_t presentAndGetReleaseFences(HalDisplayId) override;
// set power mode
- status_t setPowerMode(DisplayId, hal::PowerMode mode) override;
+ status_t setPowerMode(PhysicalDisplayId, hal::PowerMode mode) override;
// Sets a color transform to be applied to the result of composition
- status_t setColorTransform(DisplayId, const mat4& transform) override;
+ status_t setColorTransform(HalDisplayId, const mat4& transform) override;
- // reset state when an external, non-virtual display is disconnected
- void disconnectDisplay(DisplayId) override;
+ // reset state when a display is disconnected
+ void disconnectDisplay(HalDisplayId) override;
// get the present fence received from the last call to present.
- sp<Fence> getPresentFence(DisplayId) const override;
+ sp<Fence> getPresentFence(HalDisplayId) const override;
// Get last release fence for the given layer
- sp<Fence> getLayerReleaseFence(DisplayId, HWC2::Layer*) const override;
+ sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const override;
// Set the output buffer and acquire fence for a virtual display.
- // Returns INVALID_OPERATION if displayId is not a virtual display.
- status_t setOutputBuffer(DisplayId, const sp<Fence>& acquireFence,
+ status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
const sp<GraphicBuffer>& buffer) override;
// After SurfaceFlinger has retrieved the release fences for all the frames,
// it can call this to clear the shared pointers in the release fence map
- void clearReleaseFences(DisplayId) override;
+ void clearReleaseFences(HalDisplayId) override;
// Fetches the HDR capabilities of the given display
- status_t getHdrCapabilities(DisplayId, HdrCapabilities* outCapabilities) override;
+ status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) override;
- int32_t getSupportedPerFrameMetadata(DisplayId) const override;
+ int32_t getSupportedPerFrameMetadata(HalDisplayId) const override;
// Returns the available RenderIntent of the given display.
- std::vector<ui::RenderIntent> getRenderIntents(DisplayId, ui::ColorMode) const override;
+ std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const override;
- mat4 getDataspaceSaturationMatrix(DisplayId, ui::Dataspace) override;
+ mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) override;
// Returns the attributes of the color sampling engine.
- status_t getDisplayedContentSamplingAttributes(DisplayId, ui::PixelFormat* outFormat,
+ status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask) override;
- status_t setDisplayContentSamplingEnabled(DisplayId, bool enabled, uint8_t componentMask,
+ status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled, uint8_t componentMask,
uint64_t maxFrames) override;
- status_t getDisplayedContentSample(DisplayId, uint64_t maxFrames, uint64_t timestamp,
+ status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
DisplayedFrameStats* outStats) override;
- std::future<status_t> setDisplayBrightness(DisplayId, float brightness) override;
+ std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) override;
// Events handling ---------------------------------------------------------
@@ -307,31 +308,32 @@
std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, hal::Connection) override;
bool onVsync(hal::HWDisplayId, int64_t timestamp) override;
- void setVsyncEnabled(DisplayId, hal::Vsync enabled) override;
+ void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) override;
- nsecs_t getRefreshTimestamp(DisplayId) const override;
- bool isConnected(DisplayId) const override;
+ nsecs_t getRefreshTimestamp(PhysicalDisplayId) const override;
+ bool isConnected(PhysicalDisplayId) const override;
// Non-const because it can update configMap inside of mDisplayData
- std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(DisplayId) const override;
+ std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
+ PhysicalDisplayId) const override;
- std::shared_ptr<const HWC2::Display::Config> getActiveConfig(DisplayId) const override;
- int getActiveConfigIndex(DisplayId) const override;
+ std::shared_ptr<const HWC2::Display::Config> getActiveConfig(PhysicalDisplayId) const override;
+ int getActiveConfigIndex(PhysicalDisplayId) const override;
- std::vector<ui::ColorMode> getColorModes(DisplayId) const override;
+ std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const override;
- status_t setActiveColorMode(DisplayId, ui::ColorMode, ui::RenderIntent) override;
+ status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent) override;
// Composer 2.4
- DisplayConnectionType getDisplayConnectionType(DisplayId) const override;
- bool isVsyncPeriodSwitchSupported(DisplayId) const override;
- nsecs_t getDisplayVsyncPeriod(DisplayId) const override;
- status_t setActiveConfigWithConstraints(DisplayId, size_t configId,
+ DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const override;
+ bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const override;
+ nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId) const override;
+ status_t setActiveConfigWithConstraints(PhysicalDisplayId, size_t configId,
const hal::VsyncPeriodChangeConstraints&,
hal::VsyncPeriodChangeTimeline* outTimeline) override;
- status_t setAutoLowLatencyMode(DisplayId, bool) override;
- status_t getSupportedContentTypes(DisplayId, std::vector<hal::ContentType>*) override;
- status_t setContentType(DisplayId, hal::ContentType) override;
+ status_t setAutoLowLatencyMode(PhysicalDisplayId, bool) override;
+ status_t getSupportedContentTypes(PhysicalDisplayId, std::vector<hal::ContentType>*) override;
+ status_t setContentType(PhysicalDisplayId, hal::ContentType) override;
const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override;
@@ -385,7 +387,7 @@
nsecs_t lastHwVsync GUARDED_BY(lastHwVsyncLock) = 0;
};
- std::unordered_map<DisplayId, DisplayData> mDisplayData;
+ std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
std::unique_ptr<android::Hwc2::Composer> mComposer;
std::unordered_set<hal::Capability> mCapabilities;
@@ -397,9 +399,7 @@
std::optional<hal::HWDisplayId> mExternalHwcDisplayId;
bool mHasMultiDisplaySupport = false;
- std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
- uint32_t mNextVirtualDisplayId = 0;
- uint32_t mRemainingHwcVirtualDisplays{getMaxVirtualDisplayCount()};
+ RandomDisplayIdGenerator<HalVirtualDisplayId> mVirtualIdGenerator{getMaxVirtualDisplayCount()};
};
} // namespace impl
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index fba3261..247ee23 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -57,8 +57,7 @@
}
}
-VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc,
- const std::optional<DisplayId>& displayId,
+VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, VirtualDisplayId displayId,
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer,
@@ -125,7 +124,7 @@
}
status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return NO_ERROR;
}
@@ -139,7 +138,7 @@
}
status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return NO_ERROR;
}
@@ -187,7 +186,7 @@
}
status_t VirtualDisplaySurface::advanceFrame() {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return NO_ERROR;
}
@@ -219,9 +218,11 @@
mFbProducerSlot, fbBuffer.get(),
mOutputProducerSlot, outBuffer.get());
+ const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
+ LOG_FATAL_IF(!halDisplayId);
// At this point we know the output buffer acquire fence,
// so update HWC state with it.
- mHwc.setOutputBuffer(*mDisplayId, mOutputFence, outBuffer);
+ mHwc.setOutputBuffer(*halDisplayId, mOutputFence, outBuffer);
status_t result = NO_ERROR;
if (fbBuffer != nullptr) {
@@ -230,7 +231,7 @@
mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer, &hwcSlot, &hwcBuffer);
// TODO: Correctly propagate the dataspace from GL composition
- result = mHwc.setClientTarget(*mDisplayId, hwcSlot, mFbFence, hwcBuffer,
+ result = mHwc.setClientTarget(*halDisplayId, hwcSlot, mFbFence, hwcBuffer,
ui::Dataspace::UNKNOWN);
}
@@ -238,7 +239,8 @@
}
void VirtualDisplaySurface::onFrameCommitted() {
- if (!mDisplayId) {
+ const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
+ if (!halDisplayId) {
return;
}
@@ -246,7 +248,7 @@
"Unexpected onFrameCommitted() in %s state", dbgStateStr());
mDbgState = DBG_STATE_IDLE;
- sp<Fence> retireFence = mHwc.getPresentFence(*mDisplayId);
+ sp<Fence> retireFence = mHwc.getPresentFence(*halDisplayId);
if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) {
// release the scratch buffer back to the pool
Mutex::Autolock lock(mMutex);
@@ -301,7 +303,7 @@
status_t VirtualDisplaySurface::requestBuffer(int pslot,
sp<GraphicBuffer>* outBuf) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf);
}
@@ -323,7 +325,7 @@
status_t VirtualDisplaySurface::dequeueBuffer(Source source,
PixelFormat format, uint64_t usage, int* sslot, sp<Fence>* fence) {
- LOG_FATAL_IF(!mDisplayId);
+ LOG_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId));
status_t result =
mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight,
@@ -369,7 +371,7 @@
PixelFormat format, uint64_t usage,
uint64_t* outBufferAge,
FrameEventHistoryDelta* outTimestamps) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, w, h, format, usage, outBufferAge,
outTimestamps);
}
@@ -456,7 +458,7 @@
status_t VirtualDisplaySurface::queueBuffer(int pslot,
const QueueBufferInput& input, QueueBufferOutput* output) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output);
}
@@ -514,7 +516,7 @@
status_t VirtualDisplaySurface::cancelBuffer(int pslot,
const sp<Fence>& fence) {
- if (!mDisplayId) {
+ if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence);
}
@@ -626,7 +628,7 @@
}
status_t VirtualDisplaySurface::refreshOutputBuffer() {
- LOG_FATAL_IF(!mDisplayId);
+ LOG_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId));
if (mOutputProducerSlot >= 0) {
mSource[SOURCE_SINK]->cancelBuffer(
@@ -645,7 +647,9 @@
// until after GPU calls queueBuffer(). So here we just set the buffer
// (for use in HWC prepare) but not the fence; we'll call this again with
// the proper fence once we have it.
- result = mHwc.setOutputBuffer(*mDisplayId, Fence::NO_FENCE,
+ const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
+ LOG_FATAL_IF(!halDisplayId);
+ result = mHwc.setOutputBuffer(*halDisplayId, Fence::NO_FENCE,
mProducerBuffers[mOutputProducerSlot]);
return result;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 3cbad8f..1974625 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -24,6 +24,7 @@
#include <compositionengine/impl/HwcBufferCache.h>
#include <gui/ConsumerBase.h>
#include <gui/IGraphicBufferProducer.h>
+#include <ui/DisplayId.h>
#include "DisplayIdentification.h"
@@ -77,8 +78,7 @@
public BnGraphicBufferProducer,
private ConsumerBase {
public:
- VirtualDisplaySurface(HWComposer& hwc, const std::optional<DisplayId>& displayId,
- const sp<IGraphicBufferProducer>& sink,
+ VirtualDisplaySurface(HWComposer&, VirtualDisplayId, const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer, const std::string& name);
@@ -86,7 +86,7 @@
// DisplaySurface interface
//
virtual status_t beginFrame(bool mustRecompose);
- virtual status_t prepareFrame(CompositionType compositionType);
+ virtual status_t prepareFrame(CompositionType);
virtual status_t advanceFrame();
virtual void onFrameCommitted();
virtual void dumpAsString(String8& result) const;
@@ -104,25 +104,22 @@
virtual status_t requestBuffer(int pslot, sp<GraphicBuffer>* outBuf);
virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers);
virtual status_t setAsyncMode(bool async);
- virtual status_t dequeueBuffer(int* pslot, sp<Fence>* fence, uint32_t w, uint32_t h,
- PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
+ virtual status_t dequeueBuffer(int* pslot, sp<Fence>*, uint32_t w, uint32_t h, PixelFormat,
+ uint64_t usage, uint64_t* outBufferAge,
FrameEventHistoryDelta* outTimestamps);
virtual status_t detachBuffer(int slot);
- virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
- sp<Fence>* outFence);
- virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer);
- virtual status_t queueBuffer(int pslot,
- const QueueBufferInput& input, QueueBufferOutput* output);
- virtual status_t cancelBuffer(int pslot, const sp<Fence>& fence);
+ virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence);
+ virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>&);
+ virtual status_t queueBuffer(int pslot, const QueueBufferInput&, QueueBufferOutput*);
+ virtual status_t cancelBuffer(int pslot, const sp<Fence>&);
virtual int query(int what, int* value);
- virtual status_t connect(const sp<IProducerListener>& listener,
- int api, bool producerControlledByApp, QueueBufferOutput* output);
- virtual status_t disconnect(int api, DisconnectMode mode);
+ virtual status_t connect(const sp<IProducerListener>&, int api, bool producerControlledByApp,
+ QueueBufferOutput*);
+ virtual status_t disconnect(int api, DisconnectMode);
virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
- virtual void allocateBuffers(uint32_t width, uint32_t height,
- PixelFormat format, uint64_t usage);
+ virtual void allocateBuffers(uint32_t width, uint32_t height, PixelFormat, uint64_t usage);
virtual status_t allowAllocation(bool allow);
- virtual status_t setGenerationNumber(uint32_t generationNumber);
+ virtual status_t setGenerationNumber(uint32_t);
virtual String8 getConsumerName() const override;
virtual status_t setSharedBufferMode(bool sharedBufferMode) override;
virtual status_t setAutoRefresh(bool autoRefresh) override;
@@ -135,10 +132,9 @@
//
// Utility methods
//
- static Source fbSourceForCompositionType(CompositionType type);
- status_t dequeueBuffer(Source source, PixelFormat format, uint64_t usage,
- int* sslot, sp<Fence>* fence);
- void updateQueueBufferOutput(QueueBufferOutput&& qbo);
+ static Source fbSourceForCompositionType(CompositionType);
+ status_t dequeueBuffer(Source, PixelFormat, uint64_t usage, int* sslot, sp<Fence>*);
+ void updateQueueBufferOutput(QueueBufferOutput&&);
void resetPerFrameState();
status_t refreshOutputBuffer();
@@ -148,14 +144,14 @@
// internally in the VirtualDisplaySurface. To minimize the number of times
// a producer slot switches which source it comes from, we map source slot
// numbers to producer slot numbers differently for each source.
- static int mapSource2ProducerSlot(Source source, int sslot);
- static int mapProducer2SourceSlot(Source source, int pslot);
+ static int mapSource2ProducerSlot(Source, int sslot);
+ static int mapProducer2SourceSlot(Source, int pslot);
//
// Immutable after construction
//
HWComposer& mHwc;
- const std::optional<DisplayId> mDisplayId;
+ const VirtualDisplayId mDisplayId;
const std::string mDisplayName;
sp<IGraphicBufferProducer> mSource[2]; // indexed by SOURCE_*
uint32_t mDefaultOutputFormat;
diff --git a/services/surfaceflinger/DisplayIdGenerator.h b/services/surfaceflinger/DisplayIdGenerator.h
new file mode 100644
index 0000000..e7c69a8
--- /dev/null
+++ b/services/surfaceflinger/DisplayIdGenerator.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#pragma once
+
+#include <ui/DisplayId.h>
+
+#include <limits>
+#include <optional>
+#include <random>
+#include <unordered_set>
+
+#include <log/log.h>
+
+namespace android {
+
+template <typename T>
+class DisplayIdGenerator {
+public:
+ virtual std::optional<T> nextId() = 0;
+ virtual void markUnused(T id) = 0;
+
+protected:
+ ~DisplayIdGenerator() {}
+};
+
+template <typename T>
+class RandomDisplayIdGenerator final : public DisplayIdGenerator<T> {
+public:
+ explicit RandomDisplayIdGenerator(size_t maxIdsCount = std::numeric_limits<size_t>::max())
+ : mMaxIdsCount(maxIdsCount) {}
+
+ std::optional<T> nextId() override {
+ if (mUsedIds.size() >= mMaxIdsCount) {
+ return std::nullopt;
+ }
+
+ constexpr int kMaxAttempts = 1000;
+
+ for (int attempts = 0; attempts < kMaxAttempts; attempts++) {
+ const auto baseId = mDistribution(mGenerator);
+ const T id(baseId);
+ if (mUsedIds.count(id) == 0) {
+ mUsedIds.insert(id);
+ return id;
+ }
+ }
+
+ LOG_ALWAYS_FATAL("Couldn't generate ID after %d attempts", kMaxAttempts);
+ }
+
+ void markUnused(T id) override { mUsedIds.erase(id); }
+
+private:
+ const size_t mMaxIdsCount;
+
+ std::unordered_set<T> mUsedIds;
+ std::default_random_engine mGenerator{std::random_device()()};
+ std::uniform_int_distribution<typename T::BaseId> mDistribution;
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index a79cbe4..d9faec4 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -778,7 +778,12 @@
bool Layer::isSecure() const {
const State& s(mDrawingState);
- return (s.flags & layer_state_t::eLayerSecure);
+ if (s.flags & layer_state_t::eLayerSecure) {
+ return true;
+ }
+
+ const auto p = mDrawingParent.promote();
+ return (p != nullptr) ? p->isSecure() : false;
}
// ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 99d061d..f676d5b 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -176,12 +176,13 @@
}
bool RefreshRateOverlay::createLayer() {
+ int32_t layerId;
const status_t ret =
mFlinger.createLayer(String8("RefreshRateOverlay"), mClient,
SevenSegmentDrawer::getWidth(), SevenSegmentDrawer::getHeight(),
PIXEL_FORMAT_RGBA_8888,
ISurfaceComposerClient::eFXSurfaceBufferState, LayerMetadata(),
- &mIBinder, &mGbp, nullptr);
+ &mIBinder, &mGbp, nullptr, &layerId);
if (ret) {
ALOGE("failed to create buffer state layer");
return false;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bf33e5e..575da26 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -717,7 +717,8 @@
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();
LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
- LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
+ const auto displayId = display->getPhysicalId();
+ LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),
"Internal display is disconnected.");
// initialize our drawing state
@@ -1078,8 +1079,8 @@
const nsecs_t vsyncPeriod =
mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId)
.getVsyncPeriod();
- mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle,
- static_cast<PhysicalDisplayId>(*display->getId()),
+ const auto physicalId = display->getPhysicalId();
+ mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, physicalId,
mUpcomingActiveConfig.configId, vsyncPeriod);
}
}
@@ -1128,8 +1129,7 @@
}
mUpcomingActiveConfig = *desiredActiveConfig;
- const auto displayId = display->getId();
- LOG_ALWAYS_FATAL_IF(!displayId);
+ const auto displayId = display->getPhysicalId();
ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.getFps());
@@ -1140,7 +1140,7 @@
hal::VsyncPeriodChangeTimeline outTimeline;
auto status =
- getHwComposer().setActiveConfigWithConstraints(*displayId,
+ getHwComposer().setActiveConfigWithConstraints(displayId,
mUpcomingActiveConfig.configId.value(),
constraints, &outTimeline);
if (status != NO_ERROR) {
@@ -1665,7 +1665,7 @@
if (const auto display = getDefaultDisplayDeviceLocked();
display && display->isPoweredOn()) {
- getHwComposer().setVsyncEnabled(*display->getId(), mHWCVsyncPendingState);
+ getHwComposer().setVsyncEnabled(display->getPhysicalId(), mHWCVsyncPendingState);
}
}));
}
@@ -2120,7 +2120,7 @@
getBE().mDisplayTimeline.updateSignalTimes();
mPreviousPresentFences[1] = mPreviousPresentFences[0];
mPreviousPresentFences[0] =
- display ? getHwComposer().getPresentFence(*display->getId()) : Fence::NO_FENCE;
+ display ? getHwComposer().getPresentFence(display->getPhysicalId()) : Fence::NO_FENCE;
auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]);
getBE().mDisplayTimeline.push(presentFenceTime);
@@ -2154,7 +2154,8 @@
mScheduler->addPresentFence(presentFenceTime);
}
- const bool isDisplayConnected = display && getHwComposer().isConnected(*display->getId());
+ const bool isDisplayConnected =
+ display && getHwComposer().isConnected(display->getPhysicalId());
if (!hasSyncFramework) {
if (isDisplayConnected && display->isPoweredOn()) {
@@ -2171,7 +2172,8 @@
} else if (isDisplayConnected) {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
- const nsecs_t presentTime = getHwComposer().getRefreshTimestamp(*display->getId());
+ const nsecs_t presentTime =
+ getHwComposer().getRefreshTimestamp(display->getPhysicalId());
mAnimFrameTracker.setActualPresentTime(presentTime);
}
mAnimFrameTracker.advanceFrame();
@@ -2273,7 +2275,7 @@
void SurfaceFlinger::postFrame() {
const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
- if (display && getHwComposer().isConnected(*display->getId())) {
+ if (display && getHwComposer().isConnected(display->getPhysicalId())) {
uint32_t flipCount = display->getPageFlipCount();
if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
logFrameStats();
@@ -2378,7 +2380,6 @@
const DisplayDeviceState& state,
const sp<compositionengine::DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& producer) {
- auto displayId = compositionDisplay->getDisplayId();
DisplayDeviceCreationArgs creationArgs(this, displayToken, compositionDisplay);
creationArgs.sequenceId = state.sequenceId;
creationArgs.isSecure = state.isSecure;
@@ -2390,26 +2391,26 @@
creationArgs.connectionType = physical->type;
}
- const bool isInternalDisplay = displayId && displayId == getInternalDisplayIdLocked();
- creationArgs.isPrimary = isInternalDisplay;
+ if (const auto id = PhysicalDisplayId::tryCast(compositionDisplay->getId())) {
+ creationArgs.isPrimary = id == getInternalDisplayIdLocked();
- if (useColorManagement && displayId) {
- std::vector<ColorMode> modes = getHwComposer().getColorModes(*displayId);
- for (ColorMode colorMode : modes) {
- if (isWideColorMode(colorMode)) {
- creationArgs.hasWideColorGamut = true;
+ if (useColorManagement) {
+ std::vector<ColorMode> modes = getHwComposer().getColorModes(*id);
+ for (ColorMode colorMode : modes) {
+ if (isWideColorMode(colorMode)) {
+ creationArgs.hasWideColorGamut = true;
+ }
+
+ std::vector<RenderIntent> renderIntents =
+ getHwComposer().getRenderIntents(*id, colorMode);
+ creationArgs.hwcColorModes.emplace(colorMode, renderIntents);
}
-
- std::vector<RenderIntent> renderIntents =
- getHwComposer().getRenderIntents(*displayId, colorMode);
- creationArgs.hwcColorModes.emplace(colorMode, renderIntents);
}
}
- if (displayId) {
- getHwComposer().getHdrCapabilities(*displayId, &creationArgs.hdrCapabilities);
- creationArgs.supportedPerFrameMetadata =
- getHwComposer().getSupportedPerFrameMetadata(*displayId);
+ if (const auto id = HalDisplayId::tryCast(compositionDisplay->getId())) {
+ getHwComposer().getHdrCapabilities(*id, &creationArgs.hdrCapabilities);
+ creationArgs.supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(*id);
}
auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
@@ -2424,7 +2425,7 @@
}
creationArgs.physicalOrientation =
- isInternalDisplay ? internalDisplayOrientation : ui::ROTATION_0;
+ creationArgs.isPrimary ? internalDisplayOrientation : ui::ROTATION_0;
// virtual displays are always considered enabled
creationArgs.initialPowerMode = state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
@@ -2446,8 +2447,8 @@
RenderIntent::COLORIMETRIC,
Dataspace::UNKNOWN});
if (!state.isVirtual()) {
- LOG_ALWAYS_FATAL_IF(!displayId);
- auto activeConfigId = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(*displayId));
+ const auto physicalId = display->getPhysicalId();
+ auto activeConfigId = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(physicalId));
display->setActiveConfig(activeConfigId);
display->setDeviceProductInfo(state.physical->deviceProductInfo);
}
@@ -2497,6 +2498,7 @@
builder.setLayerStackId(state.layerStack);
builder.setPowerAdvisor(&mPowerAdvisor);
builder.setUseHwcVirtualDisplays(mUseHwcVirtualDisplays);
+ builder.setGpuVirtualDisplayIdGenerator(mGpuVirtualDisplayIdGenerator);
builder.setName(state.displayName);
const auto compositionDisplay = getCompositionEngine().createDisplay(builder.build());
@@ -2506,11 +2508,13 @@
sp<IGraphicBufferConsumer> bqConsumer;
getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
- std::optional<DisplayId> displayId = compositionDisplay->getId();
+ DisplayId displayId = compositionDisplay->getId();
if (state.isVirtual()) {
+ const auto virtualId = VirtualDisplayId::tryCast(displayId);
+ LOG_FATAL_IF(!virtualId);
sp<VirtualDisplaySurface> vds =
- new VirtualDisplaySurface(getHwComposer(), displayId, state.surface, bqProducer,
+ new VirtualDisplaySurface(getHwComposer(), *virtualId, state.surface, bqProducer,
bqConsumer, state.displayName);
displaySurface = vds;
@@ -2520,9 +2524,9 @@
"adding a supported display, but rendering "
"surface is provided (%p), ignoring it",
state.surface.get());
-
- LOG_ALWAYS_FATAL_IF(!displayId);
- displaySurface = new FramebufferSurface(getHwComposer(), *displayId, bqConsumer,
+ const auto physicalId = PhysicalDisplayId::tryCast(displayId);
+ LOG_FATAL_IF(!physicalId);
+ displaySurface = new FramebufferSurface(getHwComposer(), *physicalId, bqConsumer,
maxGraphicsWidth, maxGraphicsHeight);
producer = bqProducer;
}
@@ -2532,8 +2536,7 @@
displaySurface, producer);
mDisplays.emplace(displayToken, display);
if (!state.isVirtual()) {
- LOG_FATAL_IF(!displayId);
- dispatchDisplayHotplugEvent(static_cast<PhysicalDisplayId>(*displayId), true);
+ dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
}
if (display->isPrimary()) {
@@ -2543,13 +2546,9 @@
void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
if (const auto display = getDisplayDeviceLocked(displayToken)) {
- // Save display ID before disconnecting.
- const auto displayId = display->getId();
display->disconnect();
-
if (!display->isVirtual()) {
- LOG_FATAL_IF(!displayId);
- dispatchDisplayHotplugEvent(static_cast<PhysicalDisplayId>(*displayId), false);
+ dispatchDisplayHotplugEvent(display->getPhysicalId(), false);
}
}
@@ -2825,7 +2824,7 @@
void SurfaceFlinger::updateCursorAsync() {
compositionengine::CompositionRefreshArgs refreshArgs;
for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
- if (display->getId()) {
+ if (HalDisplayId::tryCast(display->getId())) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
}
}
@@ -3846,7 +3845,7 @@
}
status_t SurfaceFlinger::mirrorLayer(const sp<Client>& client, const sp<IBinder>& mirrorFromHandle,
- sp<IBinder>* outHandle, int32_t* outId) {
+ sp<IBinder>* outHandle, int32_t* outLayerId) {
if (!mirrorFromHandle) {
return NAME_NOT_FOUND;
}
@@ -3871,7 +3870,7 @@
mirrorLayer->mClonedChild = mirrorFrom->createClone();
}
- *outId = mirrorLayer->sequence;
+ *outLayerId = mirrorLayer->sequence;
return addClientLayer(client, *outHandle, nullptr, mirrorLayer, nullptr, nullptr, false,
nullptr /* outTransformHint */);
}
@@ -3880,8 +3879,8 @@
uint32_t h, PixelFormat format, uint32_t flags,
LayerMetadata metadata, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp,
- const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer,
- int32_t* outId, uint32_t* outTransformHint) {
+ const sp<IBinder>& parentHandle, int32_t* outLayerId,
+ const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
if (int32_t(w|h) < 0) {
ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
int(w), int(h));
@@ -3947,9 +3946,7 @@
mInterceptor->saveSurfaceCreation(layer);
setTransactionFlags(eTransactionNeeded);
- if (outId) {
- *outId = layer->sequence;
- }
+ *outLayerId = layer->sequence;
return result;
}
@@ -4127,10 +4124,8 @@
return;
}
- const auto displayId = display->getId();
- LOG_ALWAYS_FATAL_IF(!displayId);
-
- ALOGD("Setting power mode %d on display %s", mode, to_string(*displayId).c_str());
+ const auto displayId = display->getPhysicalId();
+ ALOGD("Setting power mode %d on display %s", mode, to_string(displayId).c_str());
const hal::PowerMode currentMode = display->getPowerMode();
if (mode == currentMode) {
@@ -4147,9 +4142,9 @@
if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
}
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
if (display->isPrimary() && mode != hal::PowerMode::DOZE_SUSPEND) {
- getHwComposer().setVsyncEnabled(*displayId, mHWCVsyncPendingState);
+ getHwComposer().setVsyncEnabled(displayId, mHWCVsyncPendingState);
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
}
@@ -4168,14 +4163,14 @@
}
// Make sure HWVsync is disabled before turning off the display
- getHwComposer().setVsyncEnabled(*displayId, hal::Vsync::DISABLE);
+ getHwComposer().setVsyncEnabled(displayId, hal::Vsync::DISABLE);
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
} else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
// Update display while dozing
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
if (display->isPrimary() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
@@ -4186,10 +4181,10 @@
mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
} else {
ALOGE("Attempting to set unknown power mode: %d\n", mode);
- getHwComposer().setPowerMode(*displayId, mode);
+ getHwComposer().setPowerMode(displayId, mode);
}
if (display->isPrimary()) {
@@ -4198,7 +4193,7 @@
mScheduler->setDisplayPowerState(mode == hal::PowerMode::ON);
}
- ALOGD("Finished setting power mode %d on display %s", mode, to_string(*displayId).c_str());
+ ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str());
}
void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
@@ -4461,12 +4456,11 @@
void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const {
for (const auto& [token, display] : mDisplays) {
- const auto displayId = display->getId();
+ const auto displayId = PhysicalDisplayId::tryCast(display->getId());
if (!displayId) {
continue;
}
- const auto hwcDisplayId =
- getHwComposer().fromPhysicalDisplayId(static_cast<PhysicalDisplayId>(*displayId));
+ const auto hwcDisplayId = getHwComposer().fromPhysicalDisplayId(*displayId);
if (!hwcDisplayId) {
continue;
}
@@ -4519,7 +4513,7 @@
// TODO: print out if wide-color mode is active or not
for (const auto& [token, display] : mDisplays) {
- const auto displayId = display->getId();
+ const auto displayId = PhysicalDisplayId::tryCast(display->getId());
if (!displayId) {
continue;
}
@@ -4733,7 +4727,7 @@
* HWC layer minidump
*/
for (const auto& [token, display] : mDisplays) {
- const auto displayId = display->getId();
+ const auto displayId = HalDisplayId::tryCast(display->getId());
if (!displayId) {
continue;
}
@@ -5252,18 +5246,12 @@
// Inject a hotplug connected event for the primary display. This will deallocate and
// reallocate the display state including framebuffers.
case 1037: {
- const auto token = getInternalDisplayToken();
-
- sp<DisplayDevice> display;
+ std::optional<hal::HWDisplayId> hwcId;
{
Mutex::Autolock lock(mStateLock);
- display = getDisplayDeviceLocked(token);
+ hwcId = getHwComposer().getInternalHwcDisplayId();
}
- const auto hwcId =
- getHwComposer().fromPhysicalDisplayId(PhysicalDisplayId(*display->getId()));
-
onHotplugReceived(getBE().mComposerSequenceId, *hwcId, hal::Connection::CONNECTED);
-
return NO_ERROR;
}
// Modify the max number of display frames stored within FrameTimeline
@@ -5426,9 +5414,8 @@
// (ex. displayP3) to enhance the content, but some cases are checking native RGB in bytes,
// and failed if display is not in native mode. This provide a way to force using native
// colors when capture.
- if (args.useRGBColorSpace) {
- dataspace = Dataspace::V0_SRGB;
- } else {
+ dataspace = args.dataspace;
+ if (dataspace == ui::Dataspace::UNKNOWN) {
const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode;
dataspace = pickDataspaceFromColorMode(colorMode);
}
@@ -5592,9 +5579,8 @@
// (ex. displayP3) to enhance the content, but some cases are checking native RGB in bytes,
// and failed if display is not in native mode. This provide a way to force using native
// colors when capture.
- if (args.useRGBColorSpace) {
- dataspace = Dataspace::V0_SRGB;
- } else {
+ dataspace = args.dataspace;
+ if (dataspace == ui::Dataspace::UNKNOWN) {
const ui::ColorMode colorMode = display->getCompositionDisplay()->getState().colorMode;
dataspace = pickDataspaceFromColorMode(colorMode);
}
@@ -5885,16 +5871,14 @@
// as well. For now, just call directly to setActiveConfigWithConstraints but ideally
// it should go thru setDesiredActiveConfig, similar to primary display.
ALOGV("setAllowedDisplayConfigsInternal for non-primary display");
- const auto displayId = display->getId();
- LOG_ALWAYS_FATAL_IF(!displayId);
+ const auto displayId = display->getPhysicalId();
hal::VsyncPeriodChangeConstraints constraints;
constraints.desiredTimeNanos = systemTime();
constraints.seamlessRequired = false;
hal::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
- if (getHwComposer().setActiveConfigWithConstraints(*displayId,
- policy->defaultConfig.value(),
+ if (getHwComposer().setActiveConfigWithConstraints(displayId, policy->defaultConfig.value(),
constraints, &timeline) < 0) {
return BAD_VALUE;
}
@@ -5904,11 +5888,9 @@
display->setActiveConfig(policy->defaultConfig);
const nsecs_t vsyncPeriod = getHwComposer()
- .getConfigs(*displayId)[policy->defaultConfig.value()]
+ .getConfigs(displayId)[policy->defaultConfig.value()]
->getVsyncPeriod();
- mScheduler->onNonPrimaryDisplayConfigChanged(mAppConnectionHandle,
- static_cast<PhysicalDisplayId>(
- *display->getId()),
+ mScheduler->onNonPrimaryDisplayConfigChanged(mAppConnectionHandle, displayId,
policy->defaultConfig, vsyncPeriod);
return NO_ERROR;
}
@@ -5940,8 +5922,8 @@
const nsecs_t vsyncPeriod =
mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig())
.getVsyncPeriod();
- mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle,
- static_cast<PhysicalDisplayId>(*display->getId()),
+ const auto physicalId = display->getPhysicalId();
+ mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, physicalId,
display->getActiveConfig(), vsyncPeriod);
toggleKernelIdleTimer();
@@ -6032,11 +6014,9 @@
} else if (display->isVirtual()) {
return INVALID_OPERATION;
} else {
- const auto displayId = display->getId();
- LOG_FATAL_IF(!displayId);
-
- *outDefaultConfig = getHwComposer().getActiveConfigIndex(*displayId);
- auto vsyncPeriod = getHwComposer().getActiveConfig(*displayId)->getVsyncPeriod();
+ const auto displayId = display->getPhysicalId();
+ *outDefaultConfig = getHwComposer().getActiveConfigIndex(displayId);
+ auto vsyncPeriod = getHwComposer().getActiveConfig(displayId)->getVsyncPeriod();
*outPrimaryRefreshRateMin = 1e9f / vsyncPeriod;
*outPrimaryRefreshRateMax = 1e9f / vsyncPeriod;
*outAppRequestRefreshRateMin = 1e9f / vsyncPeriod;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e50ecf0..f55dd90 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -52,6 +52,7 @@
#include "DisplayDevice.h"
#include "DisplayHardware/HWC2.h"
#include "DisplayHardware/PowerAdvisor.h"
+#include "DisplayIdGenerator.h"
#include "Effects/Daltonizer.h"
#include "FrameTracker.h"
#include "LayerVector.h"
@@ -752,8 +753,9 @@
status_t createLayer(const String8& name, const sp<Client>& client, uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags, LayerMetadata metadata,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,
- const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer = nullptr,
- int32_t* outId = nullptr, uint32_t* outTransformHint = nullptr);
+ const sp<IBinder>& parentHandle, int32_t* outLayerId,
+ const sp<Layer>& parentLayer = nullptr,
+ uint32_t* outTransformHint = nullptr);
status_t createBufferQueueLayer(const sp<Client>& client, std::string name, uint32_t w,
uint32_t h, uint32_t flags, LayerMetadata metadata,
@@ -773,7 +775,7 @@
sp<IBinder>* outHandle, sp<Layer>* outLayer);
status_t mirrorLayer(const sp<Client>& client, const sp<IBinder>& mirrorFromHandle,
- sp<IBinder>* outHandle, int32_t* outId);
+ sp<IBinder>* outHandle, int32_t* outLayerId);
std::string getUniqueLayerName(const char* name);
@@ -950,8 +952,8 @@
return it != mPhysicalDisplayTokens.end() ? it->second : nullptr;
}
- std::optional<DisplayId> getPhysicalDisplayIdLocked(const sp<IBinder>& displayToken) const
- REQUIRES(mStateLock) {
+ std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked(
+ const sp<IBinder>& displayToken) const REQUIRES(mStateLock) {
for (const auto& [id, token] : mPhysicalDisplayTokens) {
if (token == displayToken) {
return id;
@@ -1115,6 +1117,8 @@
std::unordered_map<PhysicalDisplayId, sp<IBinder>> mPhysicalDisplayTokens
GUARDED_BY(mStateLock);
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> mGpuVirtualDisplayIdGenerator;
+
std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock);
// don't use a lock for these, we don't care
diff --git a/services/surfaceflinger/layerproto/Android.bp b/services/surfaceflinger/layerproto/Android.bp
index d03cb7b..0a73b23 100644
--- a/services/surfaceflinger/layerproto/Android.bp
+++ b/services/surfaceflinger/layerproto/Android.bp
@@ -1,5 +1,5 @@
-cc_library_shared {
- name: "liblayers_proto",
+cc_defaults {
+ name: "liblayers_proto_defaults",
export_include_dirs: ["include"],
srcs: [
@@ -19,7 +19,7 @@
proto: {
export_proto_headers: true,
},
-
+
cppflags: [
"-Werror",
"-Wno-unused-parameter",
@@ -33,7 +33,20 @@
"-Wno-old-style-cast",
"-Wno-undef",
],
+}
+cc_library_shared {
+ name: "liblayers_proto",
+ defaults: [
+ "liblayers_proto_defaults",
+ ],
+}
+
+cc_library_static {
+ name: "liblayers_proto_static",
+ defaults: [
+ "liblayers_proto_defaults",
+ ],
}
java_library_static {
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index b7edb84..db5d820 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -46,18 +46,19 @@
data: ["SurfaceFlinger_test.filter"],
static_libs: [
"libtrace_proto",
+ "liblayers_proto_static",
+ "android.hardware.graphics.composer@2.1",
],
shared_libs: [
"android.hardware.graphics.common-ndk_platform",
"android.hardware.graphics.common@1.2",
- "android.hardware.graphics.composer@2.1",
"libandroid",
+ "libbase",
"libbinder",
"libcutils",
"libEGL",
"libGLESv2",
"libgui",
- "liblayers_proto",
"liblog",
"libnativewindow",
"libprotobuf-cpp-full",
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index e173996..7df3711 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -109,6 +109,41 @@
sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
}
+TEST_F(ScreenCaptureTest, CaptureChildSetParentFlagsSecureEUidSystem) {
+ sp<SurfaceControl> parentLayer;
+ ASSERT_NO_FATAL_FAILURE(
+ parentLayer = createLayer("parent-test", 32, 32,
+ ISurfaceComposerClient::eSecure |
+ ISurfaceComposerClient::eFXSurfaceBufferQueue));
+ ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(parentLayer, Color::RED, 32, 32));
+
+ sp<SurfaceControl> childLayer;
+ ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("child-test", 10, 10,
+ ISurfaceComposerClient::eFXSurfaceBufferQueue,
+ parentLayer.get()));
+ ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(childLayer, Color::BLUE, 10, 10));
+
+ Transaction().show(parentLayer).setLayer(parentLayer, INT32_MAX).show(childLayer).apply(true);
+
+ UIDFaker f(AID_SYSTEM);
+
+ {
+ SCOPED_TRACE("as system");
+ auto shot = screenshot();
+ shot->expectColor(Rect(0, 0, 10, 10), Color::BLACK);
+ }
+
+ // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
+ // to receive them...we are expected to take care with the results.
+ DisplayCaptureArgs args;
+ args.displayToken = mDisplay;
+ args.captureSecureLayers = true;
+ ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, mCaptureResults));
+ ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
+ ScreenCapture sc(mCaptureResults.buffer);
+ sc.expectColor(Rect(0, 0, 10, 10), Color::BLUE);
+}
+
TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
LayerCaptureArgs captureArgs;
captureArgs.layerHandle = mBGSurfaceControl->getHandle();
@@ -801,4 +836,4 @@
verify([&] { screenshot()->expectChildColor(80, 80); });
}
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index cf3a4c2..9655cf3 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -39,6 +39,7 @@
"CompositionTest.cpp",
"DispSyncSourceTest.cpp",
"DisplayIdentificationTest.cpp",
+ "DisplayIdGeneratorTest.cpp",
"DisplayTransactionTest.cpp",
"EventThreadTest.cpp",
"FrameTimelineTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 8a0b551..a4f7449 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -35,6 +35,7 @@
#include <utils/String8.h>
#include "BufferQueueLayer.h"
+#include "ContainerLayer.h"
#include "DisplayRenderArea.h"
#include "EffectLayer.h"
#include "Layer.h"
@@ -188,6 +189,7 @@
sp<compositionengine::mock::DisplaySurface> mDisplaySurface =
new compositionengine::mock::DisplaySurface();
mock::NativeWindow* mNativeWindow = new mock::NativeWindow();
+ std::vector<sp<Layer>> mAuxiliaryLayers;
sp<GraphicBuffer> mBuffer = new GraphicBuffer();
ANativeWindowBuffer* mNativeWindowBuffer = mBuffer->getNativeBuffer();
@@ -762,10 +764,9 @@
static void setupREBufferCompositionCommonCallExpectations(CompositionTest* /*test*/) {}
};
-struct SecureLayerProperties : public BaseLayerProperties<SecureLayerProperties> {
- using Base = BaseLayerProperties<SecureLayerProperties>;
-
- static constexpr uint32_t LAYER_FLAGS = ISurfaceComposerClient::eSecure;
+template <typename LayerProperties>
+struct CommonSecureLayerProperties : public BaseLayerProperties<LayerProperties> {
+ using Base = BaseLayerProperties<LayerProperties>;
static void setupInsecureREBufferCompositionCommonCallExpectations(CompositionTest* test) {
EXPECT_CALL(*test->mRenderEngine, drawLayers)
@@ -806,6 +807,13 @@
}
};
+struct ParentSecureLayerProperties
+ : public CommonSecureLayerProperties<ParentSecureLayerProperties> {};
+
+struct SecureLayerProperties : public CommonSecureLayerProperties<SecureLayerProperties> {
+ static constexpr uint32_t LAYER_FLAGS = ISurfaceComposerClient::eSecure;
+};
+
struct CursorLayerProperties : public BaseLayerProperties<CursorLayerProperties> {
using Base = BaseLayerProperties<CursorLayerProperties>;
@@ -841,6 +849,13 @@
Mock::VerifyAndClear(test->mRenderEngine);
Mock::VerifyAndClearExpectations(test->mMessageQueue);
+ initLayerDrawingStateAndComputeBounds(test, layer);
+
+ return layer;
+ }
+
+ template <typename L>
+ static void initLayerDrawingStateAndComputeBounds(CompositionTest* test, sp<L> layer) {
auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
layerDrawingState.layerStack = DEFAULT_LAYER_STACK;
layerDrawingState.active.w = 100;
@@ -848,8 +863,6 @@
layerDrawingState.color = half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
LayerProperties::COLOR[2], LayerProperties::COLOR[3]);
layer->computeBounds(FloatRect(0, 0, 100, 100), ui::Transform(), 0.f /* shadowRadius */);
-
- return layer;
}
static void injectLayer(CompositionTest* test, sp<Layer> layer) {
@@ -970,6 +983,49 @@
}
};
+template <typename LayerProperties>
+struct ContainerLayerVariant : public BaseLayerVariant<LayerProperties> {
+ using Base = BaseLayerVariant<LayerProperties>;
+ using FlingerLayerType = sp<ContainerLayer>;
+
+ static FlingerLayerType createLayer(CompositionTest* test) {
+ LayerCreationArgs args(test->mFlinger.flinger(), sp<Client>(), "test-container-layer",
+ LayerProperties::WIDTH, LayerProperties::HEIGHT,
+ LayerProperties::LAYER_FLAGS, LayerMetadata());
+ FlingerLayerType layer = new ContainerLayer(args);
+ Base::template initLayerDrawingStateAndComputeBounds(test, layer);
+ return layer;
+ }
+};
+
+template <typename LayerVariant, typename ParentLayerVariant>
+struct ChildLayerVariant : public LayerVariant {
+ using Base = LayerVariant;
+ using FlingerLayerType = typename LayerVariant::FlingerLayerType;
+ using ParentBase = ParentLayerVariant;
+
+ static FlingerLayerType createLayer(CompositionTest* test) {
+ // Need to create child layer first. Otherwise layer history size will be 2.
+ FlingerLayerType layer = Base::createLayer(test);
+
+ typename ParentBase::FlingerLayerType parentLayer = ParentBase::createLayer(test);
+ parentLayer->addChild(layer);
+ test->mFlinger.setLayerDrawingParent(layer, parentLayer);
+
+ test->mAuxiliaryLayers.push_back(parentLayer);
+
+ return layer;
+ }
+
+ static void cleanupInjectedLayers(CompositionTest* test) {
+ // Clear auxiliary layers first so that child layer can be successfully destroyed in the
+ // following call.
+ test->mAuxiliaryLayers.clear();
+
+ Base::cleanupInjectedLayers(test);
+ }
+};
+
/* ------------------------------------------------------------------------
* Variants to control how the composition type is changed
*/
@@ -1359,6 +1415,38 @@
}
/* ------------------------------------------------------------------------
+ * Layers with a parent layer with ISurfaceComposerClient::eSecure, on a non-secure display
+ */
+
+TEST_F(CompositionTest,
+ HWCComposedBufferLayerWithSecureParentLayerOnInsecureDisplayWithDirtyGeometry) {
+ displayRefreshCompositionDirtyGeometry<
+ CompositionCase<InsecureDisplaySetupVariant,
+ ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
+ ContainerLayerVariant<SecureLayerProperties>>,
+ KeepCompositionTypeVariant<IComposerClient::Composition::CLIENT>,
+ ForcedClientCompositionResultVariant>>();
+}
+
+TEST_F(CompositionTest,
+ HWCComposedBufferLayerWithSecureParentLayerOnInsecureDisplayWithDirtyFrame) {
+ displayRefreshCompositionDirtyFrame<
+ CompositionCase<InsecureDisplaySetupVariant,
+ ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
+ ContainerLayerVariant<SecureLayerProperties>>,
+ KeepCompositionTypeVariant<IComposerClient::Composition::CLIENT>,
+ ForcedClientCompositionResultVariant>>();
+}
+
+TEST_F(CompositionTest, captureScreenBufferLayerWithSecureParentLayerOnInsecureDisplay) {
+ captureScreenComposition<
+ CompositionCase<InsecureDisplaySetupVariant,
+ ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
+ ContainerLayerVariant<SecureLayerProperties>>,
+ NoCompositionTypeVariant, REScreenshotResultVariant>>();
+}
+
+/* ------------------------------------------------------------------------
* Cursor layers
*/
diff --git a/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp b/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp
new file mode 100644
index 0000000..be7609a
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#include <gtest/gtest.h>
+
+#include <vector>
+
+#include <ui/DisplayId.h>
+#include "DisplayIdGenerator.h"
+
+namespace android {
+
+template <typename T>
+void testNextId(DisplayIdGenerator<T>& generator) {
+ constexpr int kNumIds = 5;
+ std::vector<T> ids;
+ for (int i = 0; i < kNumIds; i++) {
+ const auto id = generator.nextId();
+ ASSERT_TRUE(id);
+ ids.push_back(*id);
+ }
+
+ // All IDs should be different.
+ for (size_t i = 0; i < kNumIds; i++) {
+ for (size_t j = i + 1; j < kNumIds; j++) {
+ EXPECT_NE(ids[i], ids[j]);
+ }
+ }
+}
+
+TEST(DisplayIdGeneratorTest, nextIdGpuVirtual) {
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> generator;
+ testNextId(generator);
+}
+
+TEST(DisplayIdGeneratorTest, nextIdHalVirtual) {
+ RandomDisplayIdGenerator<HalVirtualDisplayId> generator;
+ testNextId(generator);
+}
+
+TEST(DisplayIdGeneratorTest, markUnused) {
+ constexpr size_t kMaxIdsCount = 5;
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount);
+
+ const auto id = generator.nextId();
+ EXPECT_TRUE(id);
+
+ for (int i = 1; i < kMaxIdsCount; i++) {
+ EXPECT_TRUE(generator.nextId());
+ }
+
+ EXPECT_FALSE(generator.nextId());
+
+ generator.markUnused(*id);
+ EXPECT_TRUE(generator.nextId());
+}
+
+TEST(DisplayIdGeneratorTest, maxIdsCount) {
+ constexpr size_t kMaxIdsCount = 5;
+ RandomDisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount);
+
+ for (int i = 0; i < kMaxIdsCount; i++) {
+ EXPECT_TRUE(generator.nextId());
+ }
+
+ EXPECT_FALSE(generator.nextId());
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 5864d02..e055e95 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -338,9 +338,9 @@
struct PhysicalDisplayIdType {};
template <uint64_t displayId>
-using VirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
+using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
-struct NoDisplayId {};
+struct GpuVirtualDisplayIdType {};
template <typename>
struct IsPhysicalDisplayId : std::bool_constant<false> {};
@@ -353,7 +353,7 @@
template <typename PhysicalDisplay>
struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
- static std::optional<PhysicalDisplayId> get() {
+ static PhysicalDisplayId get() {
if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY)
? LEGACY_DISPLAY_TYPE_PRIMARY
@@ -363,19 +363,18 @@
const auto info =
parseDisplayIdentificationData(PhysicalDisplay::PORT,
PhysicalDisplay::GET_IDENTIFICATION_DATA());
- return info ? std::make_optional(info->id) : std::nullopt;
+ return info ? info->id : PhysicalDisplayId::fromPort(PhysicalDisplay::PORT);
}
};
template <uint64_t displayId>
-struct DisplayIdGetter<VirtualDisplayIdType<displayId>> {
- // TODO(b/160679868) Use VirtualDisplayId
- static std::optional<PhysicalDisplayId> get() { return PhysicalDisplayId{displayId}; }
+struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
+ static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
};
template <>
-struct DisplayIdGetter<NoDisplayId> {
- static std::optional<DisplayId> get() { return {}; }
+struct DisplayIdGetter<GpuVirtualDisplayIdType> {
+ static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); }
};
template <typename>
@@ -396,7 +395,7 @@
constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
template <uint64_t displayId>
-struct HwcDisplayIdGetter<VirtualDisplayIdType<displayId>> {
+struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
};
@@ -407,8 +406,8 @@
// DisplayIdType can be:
// 1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC.
-// 2) VirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
-// 3) NoDisplayId for virtual display without HWC backing.
+// 2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
+// 3) GpuVirtualDisplayIdType for virtual display without HWC backing.
template <typename DisplayIdType, int width, int height, Critical critical, Async async,
Secure secure, Primary primary, int grallocUsage>
struct DisplayVariant {
@@ -440,17 +439,36 @@
static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
- if (auto displayId = DISPLAY_ID::get()) {
+ if (auto displayId = PhysicalDisplayId::tryCast(DISPLAY_ID::get())) {
ceDisplayArgs.setPhysical({*displayId, DisplayConnectionType::Internal});
} else {
+ // We turn off the use of HwcVirtualDisplays, to prevent Composition Engine
+ // from calling into HWComposer. This way all virtual displays will get
+ // a GpuVirtualDisplayId, even if we are in the HwcVirtualDisplayVariant.
+ // In this case we later override it by calling display.setDisplayIdForTesting().
ceDisplayArgs.setUseHwcVirtualDisplays(false);
+
+ GpuVirtualDisplayId desiredDisplayId = GpuVirtualDisplayId::tryCast(DISPLAY_ID::get())
+ .value_or(GpuVirtualDisplayId(0));
+
+ ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
+ .WillByDefault(Return(desiredDisplayId));
+
+ auto& generator = test->mFlinger.gpuVirtualDisplayIdGenerator();
+ ceDisplayArgs.setGpuVirtualDisplayIdGenerator(generator);
}
- ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor).build();
+ ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor);
auto compositionDisplay =
compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
ceDisplayArgs.build());
+ if (HalVirtualDisplayId::tryCast(DISPLAY_ID::get())) {
+ // CompositionEngine has assigned a placeholder GpuVirtualDisplayId and we need to
+ // override it with the correct HalVirtualDisplayId.
+ compositionDisplay->setDisplayIdForTesting(DISPLAY_ID::get());
+ }
+
auto injector = FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
CONNECTION_TYPE::value, HWC_DISPLAY_ID_OPT::value,
static_cast<bool>(PRIMARY));
@@ -532,8 +550,8 @@
// Called by tests to inject a HWC display setup
static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
const auto displayId = DisplayVariant::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- FakeHwcDisplayInjector(*displayId, HWC_DISPLAY_TYPE,
+ ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
+ FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
static_cast<bool>(DisplayVariant::PRIMARY))
.setHwcDisplayId(HWC_DISPLAY_ID)
.setWidth(DisplayVariant::WIDTH)
@@ -559,7 +577,7 @@
::testing::UnitTest::GetInstance()->current_test_info();
auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
- .setPhysical({*DisplayVariant::DISPLAY_ID::get(),
+ .setPhysical({DisplayVariant::DISPLAY_ID::get(),
PhysicalDisplay::CONNECTION_TYPE})
.setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT})
.setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
@@ -686,10 +704,11 @@
template <int width, int height, Secure secure>
struct NonHwcVirtualDisplayVariant
- : DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
+ : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY> {
- using Base = DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
- Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
+ using Base =
+ DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE,
+ secure, Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
static void injectHwcDisplay(DisplayTransactionTest*) {}
@@ -698,12 +717,17 @@
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
+ ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
+ .WillByDefault(Return(Base::DISPLAY_ID::get()));
+
auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
.setPixels({Base::WIDTH, Base::HEIGHT})
.setIsSecure(static_cast<bool>(Base::SECURE))
.setPowerAdvisor(&test->mPowerAdvisor)
.setName(std::string("Injected display for ") +
test_info->test_case_name() + "." + test_info->name())
+ .setGpuVirtualDisplayIdGenerator(
+ test->mFlinger.gpuVirtualDisplayIdGenerator())
.build();
return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
@@ -725,13 +749,13 @@
template <int width, int height, Secure secure>
struct HwcVirtualDisplayVariant
- : DisplayVariant<VirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
+ : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
HwcDisplayVariant<HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
- DisplayVariant<VirtualDisplayIdType<42>, width, height, Critical::FALSE,
- Async::TRUE, secure, Primary::FALSE,
+ DisplayVariant<HalVirtualDisplayIdType<42>, width, height,
+ Critical::FALSE, Async::TRUE, secure, Primary::FALSE,
GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
- using Base = DisplayVariant<VirtualDisplayIdType<42>, width, height, Critical::FALSE,
+ using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>;
using Self = HwcVirtualDisplayVariant<width, height, secure>;
@@ -740,6 +764,14 @@
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
+ // In order to prevent compostition engine calling into HWComposer, we
+ // 1. turn off the use of HWC virtual displays,
+ // 2. provide a GpuVirtualDisplayIdGenerator which always returns some fake ID
+ // 3. override the ID by calling setDisplayIdForTesting()
+
+ ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
+ .WillByDefault(Return(GpuVirtualDisplayId(0)));
+
auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
.setUseHwcVirtualDisplays(false)
.setPixels({Base::WIDTH, Base::HEIGHT})
@@ -747,6 +779,8 @@
.setPowerAdvisor(&test->mPowerAdvisor)
.setName(std::string("Injected display for ") +
test_info->test_case_name() + "." + test_info->name())
+ .setGpuVirtualDisplayIdGenerator(
+ test->mFlinger.gpuVirtualDisplayIdGenerator())
.build();
auto compositionDisplay =
@@ -755,8 +789,9 @@
compositionDisplay->setDisplayIdForTesting(Base::DISPLAY_ID::get());
// Insert display data so that the HWC thinks it created the virtual display.
- if (const auto displayId = Base::DISPLAY_ID::get()) {
- test->mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
+ if (const auto displayId = Base::DISPLAY_ID::get();
+ HalVirtualDisplayId::tryCast(displayId)) {
+ test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
}
return compositionDisplay;
@@ -1776,13 +1811,11 @@
DisplayDeviceState state;
if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
- const auto displayId = Case::Display::DISPLAY_ID::get();
+ const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
ASSERT_TRUE(displayId);
const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
ASSERT_TRUE(hwcDisplayId);
- state.physical = {.id = static_cast<PhysicalDisplayId>(*displayId),
- .type = *connectionType,
- .hwcDisplayId = *hwcDisplayId};
+ state.physical = {.id = *displayId, .type = *connectionType, .hwcDisplayId = *hwcDisplayId};
}
state.isSecure = static_cast<bool>(Case::Display::SECURE);
@@ -1954,11 +1987,11 @@
std::optional<DisplayDeviceState::Physical> expectedPhysical;
if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
- const auto displayId = Case::Display::DISPLAY_ID::get();
+ const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
ASSERT_TRUE(displayId);
const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
ASSERT_TRUE(hwcDisplayId);
- expectedPhysical = {.id = static_cast<PhysicalDisplayId>(*displayId),
+ expectedPhysical = {.id = *displayId,
.type = *connectionType,
.hwcDisplayId = *hwcDisplayId};
}
@@ -1983,9 +2016,9 @@
// SF should have a display token.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
- auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[*displayId];
+ ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 1);
+ auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[displayId];
verifyDisplayIsConnected<Case>(displayToken);
}
@@ -2088,8 +2121,8 @@
// SF should not have a display token.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
+ ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 0);
// The existing token should have been removed
verifyDisplayIsNotConnected(existing.token());
@@ -2174,8 +2207,8 @@
// SF should not have a display token.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
+ ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 0);
}
TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
@@ -2213,9 +2246,9 @@
// The existing token should have been removed
verifyDisplayIsNotConnected(existing.token());
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
- EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[*displayId]);
+ ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 1);
+ EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[displayId]);
// A new display should be connected in its place
@@ -2349,8 +2382,8 @@
// A virtual display is set up but is removed from the current state.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
+ ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId));
+ mFlinger.mutableHwcDisplayData().try_emplace(displayId);
Case::Display::injectHwcDisplay(this);
auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
existing.inject();
@@ -3485,8 +3518,8 @@
// Insert display data so that the HWC thinks it created the virtual display.
const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(displayId);
- mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
+ ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId));
+ mFlinger.mutableHwcDisplayData().try_emplace(displayId);
// A virtual display device is set up
Case::Display::injectHwcDisplay(this);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 96e4f5b..6ce738a 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -40,6 +40,7 @@
#include "SurfaceInterceptor.h"
#include "TestableScheduler.h"
#include "mock/DisplayHardware/MockDisplay.h"
+#include "mock/MockDisplayIdGenerator.h"
namespace android {
@@ -171,6 +172,9 @@
SurfaceFlinger* flinger() { return mFlinger.get(); }
TestableScheduler* scheduler() { return mScheduler; }
+ mock::DisplayIdGenerator<GpuVirtualDisplayId>& gpuVirtualDisplayIdGenerator() {
+ return mGpuVirtualDisplayIdGenerator;
+ }
// Extend this as needed for accessing SurfaceFlinger private (and public)
// functions.
@@ -273,6 +277,10 @@
layer->mPotentialCursor = potentialCursor;
}
+ static void setLayerDrawingParent(const sp<Layer>& layer, const sp<Layer>& drawingParent) {
+ layer->mDrawingParent = drawingParent;
+ }
+
/* ------------------------------------------------------------------------
* Forwarding for functions being tested
*/
@@ -463,7 +471,8 @@
static constexpr hal::HWConfigId DEFAULT_ACTIVE_CONFIG = 0;
static constexpr hal::PowerMode DEFAULT_POWER_MODE = hal::PowerMode::ON;
- FakeHwcDisplayInjector(DisplayId displayId, hal::DisplayType hwcDisplayType, bool isPrimary)
+ FakeHwcDisplayInjector(HalDisplayId displayId, hal::DisplayType hwcDisplayType,
+ bool isPrimary)
: mDisplayId(displayId), mHwcDisplayType(hwcDisplayType), mIsPrimary(isPrimary) {}
auto& setHwcDisplayId(hal::HWDisplayId displayId) {
@@ -536,14 +545,16 @@
flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = std::move(display);
if (mHwcDisplayType == hal::DisplayType::PHYSICAL) {
- flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, mDisplayId);
+ const auto physicalId = PhysicalDisplayId::tryCast(mDisplayId);
+ LOG_ALWAYS_FATAL_IF(!physicalId);
+ flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, *physicalId);
(mIsPrimary ? flinger->mutableInternalHwcDisplayId()
: flinger->mutableExternalHwcDisplayId()) = mHwcDisplayId;
}
}
private:
- const DisplayId mDisplayId;
+ const HalDisplayId mDisplayId;
const hal::DisplayType mHwcDisplayType;
const bool mIsPrimary;
@@ -635,10 +646,10 @@
DisplayDeviceState state;
if (const auto type = mCreationArgs.connectionType) {
LOG_ALWAYS_FATAL_IF(!displayId);
+ const auto physicalId = PhysicalDisplayId::tryCast(*displayId);
+ LOG_ALWAYS_FATAL_IF(!physicalId);
LOG_ALWAYS_FATAL_IF(!mHwcDisplayId);
- state.physical = {.id = static_cast<PhysicalDisplayId>(*displayId),
- .type = *type,
- .hwcDisplayId = *mHwcDisplayId};
+ state.physical = {.id = *physicalId, .type = *type, .hwcDisplayId = *mHwcDisplayId};
}
state.isSecure = mCreationArgs.isSecure;
@@ -672,6 +683,7 @@
sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization);
TestableScheduler* mScheduler = nullptr;
Hwc2::mock::Display mDisplay;
+ mock::DisplayIdGenerator<GpuVirtualDisplayId> mGpuVirtualDisplayIdGenerator;
};
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
index 0780af1..251ab36 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
@@ -20,17 +20,13 @@
#include "mock/DisplayHardware/MockComposer.h"
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
// Explicit default instantiation is recommended.
Composer::Composer() = default;
Composer::~Composer() = default;
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
+} // namespace android::Hwc2::mock
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index cd9b87a..1ba3c0f 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -24,8 +24,7 @@
class GraphicBuffer;
-namespace Hwc2 {
-namespace mock {
+namespace Hwc2::mock {
using android::hardware::graphics::common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Transform;
@@ -140,6 +139,5 @@
MOCK_METHOD2(getClientTargetProperty, Error(Display, IComposerClient::ClientTargetProperty*));
};
-} // namespace mock
-} // namespace Hwc2
+} // namespace Hwc2::mock
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp
index 2ec37c1..c9788af 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp
@@ -16,14 +16,10 @@
#include "mock/DisplayHardware/MockDisplay.h"
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
// Explicit default instantiation is recommended.
Display::Display() = default;
Display::~Display() = default;
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
\ No newline at end of file
+} // namespace android::Hwc2::mock
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index fe99e77..a96d9db 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -22,9 +22,7 @@
using android::HWC2::Layer;
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
namespace hal = android::hardware::graphics::composer::hal;
@@ -98,6 +96,4 @@
MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool());
};
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
+} // namespace android::Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp
index 8be7077..1ba38a8 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp
@@ -16,14 +16,10 @@
#include "MockPowerAdvisor.h"
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
// Explicit default instantiation is recommended.
PowerAdvisor::PowerAdvisor() = default;
PowerAdvisor::~PowerAdvisor() = default;
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
+} // namespace android::Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
index e22d0cf..7450b5d 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
@@ -20,9 +20,7 @@
#include "DisplayHardware/PowerAdvisor.h"
-namespace android {
-namespace Hwc2 {
-namespace mock {
+namespace android::Hwc2::mock {
class PowerAdvisor : public android::Hwc2::PowerAdvisor {
public:
@@ -34,6 +32,4 @@
MOCK_METHOD0(notifyDisplayUpdateImminent, void());
};
-} // namespace mock
-} // namespace Hwc2
-} // namespace android
+} // namespace android::Hwc2::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h b/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h
new file mode 100644
index 0000000..cfc37ea
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 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.
+ */
+
+#pragma once
+
+#include <gmock/gmock.h>
+
+#include "DisplayIdGenerator.h"
+
+namespace android::mock {
+
+template <typename T>
+class DisplayIdGenerator : public android::DisplayIdGenerator<T> {
+public:
+ // Explicit default instantiation is recommended.
+ DisplayIdGenerator() = default;
+ virtual ~DisplayIdGenerator() = default;
+
+ MOCK_METHOD0(nextId, std::optional<T>());
+ MOCK_METHOD1(markUnused, void(T));
+};
+
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp b/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
index 408cd35..302dc01 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
@@ -16,12 +16,10 @@
#include "mock/MockEventThread.h"
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
EventThread::EventThread() = default;
EventThread::~EventThread() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index eefdec1..b4594c1 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -20,8 +20,7 @@
#include "Scheduler/EventThread.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class EventThread : public android::EventThread {
public:
@@ -47,5 +46,4 @@
MOCK_METHOD0(getEventThreadConnectionCount, size_t());
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp
index 358dfdb..417dcb0 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp
@@ -16,12 +16,10 @@
#include "mock/MockFrameTracer.h"
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
FrameTracer::FrameTracer() = default;
FrameTracer::~FrameTracer() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h
index f768b81..305cb1c 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h
@@ -20,8 +20,7 @@
#include "FrameTracer/FrameTracer.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class FrameTracer : public android::FrameTracer {
public:
@@ -39,5 +38,4 @@
MOCK_METHOD0(miniDump, std::string());
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
index 7e925b9..0a0e7b5 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
@@ -20,15 +20,13 @@
#include "mock/MockSurfaceInterceptor.h"
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
SurfaceInterceptor::SurfaceInterceptor() = default;
SurfaceInterceptor::~SurfaceInterceptor() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
index 03a04a9..b085027 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
@@ -20,8 +20,7 @@
#include "SurfaceInterceptor.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class SurfaceInterceptor : public android::SurfaceInterceptor {
public:
@@ -48,5 +47,4 @@
MOCK_METHOD1(saveVSyncEvent, void(nsecs_t));
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp
index d686939..f8e76b2 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp
@@ -16,12 +16,10 @@
#include "mock/MockTimeStats.h"
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
TimeStats::TimeStats() = default;
TimeStats::~TimeStats() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
index 4186e2b..ff37ec8 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
@@ -20,8 +20,7 @@
#include "TimeStats/TimeStats.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class TimeStats : public android::TimeStats {
public:
@@ -59,5 +58,4 @@
MOCK_METHOD1(setPresentFenceGlobal, void(const std::shared_ptr<FenceTime>&));
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp
index 8a18123..bcccae5 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp
@@ -15,15 +15,11 @@
*/
#include "mock/MockVSyncTracker.h"
-#include <thread>
-using namespace std::chrono_literals;
-namespace android {
-namespace mock {
+namespace android::mock {
// Explicit default instantiation is recommended.
VSyncTracker::VSyncTracker() = default;
VSyncTracker::~VSyncTracker() = default;
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h b/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
index 1d87546..94d9966 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
@@ -20,8 +20,7 @@
#include "Scheduler/VsyncController.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class VsyncController : public android::scheduler::VsyncController {
public:
@@ -36,5 +35,4 @@
MOCK_CONST_METHOD1(dump, void(std::string&));
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/utils/ScreenshotUtils.h b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
index ca3551e..a13f93b 100644
--- a/services/surfaceflinger/tests/utils/ScreenshotUtils.h
+++ b/services/surfaceflinger/tests/utils/ScreenshotUtils.h
@@ -34,7 +34,7 @@
const auto sf = ComposerService::getComposerService();
SurfaceComposerClient::Transaction().apply(true);
- captureArgs.useRGBColorSpace = true;
+ captureArgs.dataspace = ui::Dataspace::V0_SRGB;
const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
status_t status = sf->captureDisplay(captureArgs, captureListener);
@@ -67,7 +67,7 @@
const auto sf = ComposerService::getComposerService();
SurfaceComposerClient::Transaction().apply(true);
- captureArgs.useRGBColorSpace = true;
+ captureArgs.dataspace = ui::Dataspace::V0_SRGB;
const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
status_t status = sf->captureLayers(captureArgs, captureListener);
if (status != NO_ERROR) {