Merge "Revert "Add RefreshRateRangeTest to presubmit""
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 20bfe65..4a84884 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -14,10 +14,12 @@
libs/renderengine/
libs/ui/
libs/vr/
+ opengl/libs/
services/bufferhub/
services/inputflinger/
services/surfaceflinger/
services/vr/
+ vulkan/
[Hook Scripts]
owners_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "OWNERS$"
diff --git a/data/etc/android.hardware.telephony.cdma.xml b/data/etc/android.hardware.telephony.cdma.xml
index 082378d..b598f68 100644
--- a/data/etc/android.hardware.telephony.cdma.xml
+++ b/data/etc/android.hardware.telephony.cdma.xml
@@ -18,4 +18,5 @@
<permissions>
<feature name="android.hardware.telephony" />
<feature name="android.hardware.telephony.cdma" />
+ <feature name="android.hardware.telephony.data" />
</permissions>
diff --git a/data/etc/android.hardware.telephony.gsm.xml b/data/etc/android.hardware.telephony.gsm.xml
index 7927fa8..fe8a5cf 100644
--- a/data/etc/android.hardware.telephony.gsm.xml
+++ b/data/etc/android.hardware.telephony.gsm.xml
@@ -18,4 +18,5 @@
<permissions>
<feature name="android.hardware.telephony" />
<feature name="android.hardware.telephony.gsm" />
+ <feature name="android.hardware.telephony.data" />
</permissions>
diff --git a/libs/android_runtime_lazy/android_runtime_lazy.cpp b/libs/android_runtime_lazy/android_runtime_lazy.cpp
index 98d8e8a..8062be6 100644
--- a/libs/android_runtime_lazy/android_runtime_lazy.cpp
+++ b/libs/android_runtime_lazy/android_runtime_lazy.cpp
@@ -15,6 +15,7 @@
*/
#define LOG_TAG "ANDROID_RUNTIME_LAZY"
#include "android_runtime/AndroidRuntime.h"
+#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include <dlfcn.h>
@@ -28,12 +29,18 @@
std::once_flag loadFlag;
typedef JNIEnv* (*getJNIEnv_t)();
+
+// android_util_Binder.h
typedef sp<IBinder> (*ibinderForJavaObject_t)(JNIEnv* env, jobject obj);
typedef jobject (*javaObjectForIBinder_t)(JNIEnv* env, const sp<IBinder>& val);
+// android_os_Parcel.h
+typedef Parcel* (*parcelForJavaObject_t)(JNIEnv* env, jobject obj);
+
getJNIEnv_t _getJNIEnv;
ibinderForJavaObject_t _ibinderForJavaObject;
javaObjectForIBinder_t _javaObjectForIBinder;
+parcelForJavaObject_t _parcelForJavaObject;
void load() {
std::call_once(loadFlag, []() {
@@ -64,6 +71,13 @@
ALOGW("Could not find javaObjectForIBinder.");
// no return
}
+
+ _parcelForJavaObject = reinterpret_cast<parcelForJavaObject_t>(
+ dlsym(handle, "_ZN7android19parcelForJavaObjectEP7_JNIEnvP8_jobject"));
+ if (_parcelForJavaObject == nullptr) {
+ ALOGW("Could not find parcelForJavaObject.");
+ // no return
+ }
});
}
@@ -95,4 +109,12 @@
return _javaObjectForIBinder(env, val);
}
+Parcel* parcelForJavaObject(JNIEnv* env, jobject obj) {
+ load();
+ if (_parcelForJavaObject == nullptr) {
+ return nullptr;
+ }
+ return _parcelForJavaObject(env, obj);
+}
+
} // namespace android
diff --git a/libs/android_runtime_lazy/include/android_os_Parcel.h b/libs/android_runtime_lazy/include/android_os_Parcel.h
new file mode 100644
index 0000000..19b094d
--- /dev/null
+++ b/libs/android_runtime_lazy/include/android_os_Parcel.h
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <binder/Parcel.h>
+#include "jni.h"
+
+namespace android {
+
+// The name of this file is same with the file in frameworks/base/core/jni/
+// This is intentional to make the client use these exported functions
+// in the same way with the original.
+
+Parcel* parcelForJavaObject(JNIEnv* env, jobject obj);
+
+} // namespace android
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index fa07d04..b37db43 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -50,6 +50,7 @@
"ibinder.cpp",
"ibinder_jni.cpp",
"parcel.cpp",
+ "parcel_jni.cpp",
"process.cpp",
"stability.cpp",
"status.cpp",
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h b/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
index be3029c..cd1ff1f 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
@@ -36,13 +36,13 @@
/**
* Converts an android.os.IBinder object into an AIBinder* object.
*
- * If either env or the binder is null, null is returned. If this binder object was originally an
+ * If the binder is null, null is returned. If this binder object was originally an
* AIBinder object, the original object is returned. The returned object has one refcount
* associated with it, and so this should be accompanied with an AIBinder_decStrong call.
*
* Available since API level 29.
*
- * \param env Java environment.
+ * \param env Java environment. Must not be null.
* \param binder android.os.IBinder java object.
*
* \return an AIBinder object representing the Java binder object. If either parameter is null, or
@@ -54,12 +54,12 @@
/**
* Converts an AIBinder* object into an android.os.IBinder object.
*
- * If either env or the binder is null, null is returned. If this binder object was originally an
- * IBinder object, the original java object will be returned.
+ * If the binder is null, null is returned. If this binder object was originally an IBinder object,
+ * the original java object will be returned.
*
* Available since API level 29.
*
- * \param env Java environment.
+ * \param env Java environment. Must not be null.
* \param binder the object to convert.
*
* \return an android.os.IBinder object or null if the parameters were null.
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_jni.h b/libs/binder/ndk/include_ndk/android/binder_parcel_jni.h
new file mode 100644
index 0000000..65e1704
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_jni.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+/**
+ * @addtogroup NdkBinder
+ * @{
+ */
+
+/**
+ * @file binder_parcel_jni.h
+ * @brief Conversions between AParcel and android.os.Parcel
+ */
+
+#pragma once
+
+#include <android/binder_parcel.h>
+
+#include <jni.h>
+
+__BEGIN_DECLS
+#if __ANDROID_API__ >= 30
+
+/**
+ * Converts an android.os.Parcel object into an AParcel* object.
+ *
+ * If the parcel is null, null is returned.
+ *
+ * Available since API level 30.
+ *
+ * \param env Java environment. Must not be null.
+ * \param parcel android.os.Parcel java object.
+ *
+ * \return an AParcel object representing the Java parcel object. If either parameter is null, this
+ * will return null. This must be deleted with AParcel_delete. This does not take ownership of the
+ * jobject and is only good for as long as the jobject is alive.
+ */
+__attribute__((warn_unused_result)) AParcel* AParcel_fromJavaParcel(JNIEnv* env, jobject parcel)
+ __INTRODUCED_IN(30);
+
+#endif //__ANDROID_API__ >= 30
+__END_DECLS
+
+/** @} */
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 71d8103..f3158d7 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -105,6 +105,7 @@
AIBinder_setExtension;
AStatus_getDescription;
AStatus_deleteDescription;
+ AParcel_fromJavaParcel;
AIBinder_markSystemStability; # apex
AIBinder_markVendorStability; # llndk
diff --git a/libs/binder/ndk/parcel_jni.cpp b/libs/binder/ndk/parcel_jni.cpp
new file mode 100644
index 0000000..53b2d7c
--- /dev/null
+++ b/libs/binder/ndk/parcel_jni.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#include <android/binder_parcel_jni.h>
+#include "parcel_internal.h"
+
+#include <android_os_Parcel.h>
+
+using ::android::Parcel;
+using ::android::parcelForJavaObject;
+
+AParcel* AParcel_fromJavaParcel(JNIEnv* env, jobject jbinder) {
+ if (jbinder == nullptr) {
+ return nullptr;
+ }
+
+ Parcel* parcel = parcelForJavaObject(env, jbinder);
+
+ if (parcel == nullptr) {
+ return nullptr;
+ }
+
+ return new AParcel(nullptr /*binder*/, parcel, false /*shouldOwn*/);
+}
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 354703b..f07c231 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -145,6 +145,12 @@
void GraphicsEnv::hintActivityLaunch() {
ATRACE_CALL();
+ {
+ std::lock_guard<std::mutex> lock(mStatsLock);
+ if (mActivityLaunched) return;
+ mActivityLaunched = true;
+ }
+
std::thread trySendGpuStatsThread([this]() {
// If there's already graphics driver preloaded in the process, just send
// the stats info to GpuStats directly through async binder.
@@ -228,12 +234,11 @@
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mStatsLock);
- const bool doNotSend = mGpuStats.appPackageName.empty();
if (api == GpuStatsInfo::Api::API_GL) {
- if (doNotSend) mGpuStats.glDriverToSend = true;
+ mGpuStats.glDriverToSend = true;
mGpuStats.glDriverLoadingTime = driverLoadingTime;
} else {
- if (doNotSend) mGpuStats.vkDriverToSend = true;
+ mGpuStats.vkDriverToSend = true;
mGpuStats.vkDriverLoadingTime = driverLoadingTime;
}
@@ -250,10 +255,18 @@
return interface_cast<IGpuService>(binder);
}
+bool GraphicsEnv::readyToSendGpuStatsLocked() {
+ // Only send stats for processes having at least one activity launched and that process doesn't
+ // skip the GraphicsEnvironment setup.
+ return mActivityLaunched && !mGpuStats.appPackageName.empty();
+}
+
void GraphicsEnv::setTargetStats(const GpuStatsInfo::Stats stats, const uint64_t value) {
ATRACE_CALL();
std::lock_guard<std::mutex> lock(mStatsLock);
+ if (!readyToSendGpuStatsLocked()) return;
+
const sp<IGpuService> gpuService = getGpuService();
if (gpuService) {
gpuService->setTargetStats(mGpuStats.appPackageName, mGpuStats.driverVersionCode, stats,
@@ -265,8 +278,7 @@
int64_t driverLoadingTime) {
ATRACE_CALL();
- // Do not sendGpuStats for those skipping the GraphicsEnvironment setup
- if (mGpuStats.appPackageName.empty()) return;
+ if (!readyToSendGpuStatsLocked()) return;
ALOGV("sendGpuStats:\n"
"\tdriverPackageName[%s]\n"
diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
index c6dc1f8..2219074 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -131,6 +131,8 @@
void updateUseAngle();
// Link updatable driver namespace with llndk and vndk-sp libs.
bool linkDriverNamespaceLocked(android_namespace_t* vndkNamespace);
+ // Check whether this process is ready to send stats.
+ bool readyToSendGpuStatsLocked();
// Send the initial complete GpuStats to GpuService.
void sendGpuStatsLocked(GpuStatsInfo::Api api, bool isDriverLoaded, int64_t driverLoadingTime);
@@ -141,6 +143,8 @@
std::string mSphalLibraries;
// This mutex protects mGpuStats and get gpuservice call.
std::mutex mStatsLock;
+ // Cache the activity launch info
+ bool mActivityLaunched = false;
// Information bookkept for GpuStats.
GpuStatsInfo mGpuStats;
// Path to ANGLE libs.
diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp
index 0ba01f4..842af18 100644
--- a/libs/nativewindow/ANativeWindow.cpp
+++ b/libs/nativewindow/ANativeWindow.cpp
@@ -138,6 +138,11 @@
static_assert(static_cast<int>(ADATASPACE_SCRGB) == static_cast<int>(HAL_DATASPACE_V0_SCRGB));
static_assert(static_cast<int>(ADATASPACE_DISPLAY_P3) == static_cast<int>(HAL_DATASPACE_DISPLAY_P3));
static_assert(static_cast<int>(ADATASPACE_BT2020_PQ) == static_cast<int>(HAL_DATASPACE_BT2020_PQ));
+ static_assert(static_cast<int>(ADATASPACE_ADOBE_RGB) == static_cast<int>(HAL_DATASPACE_ADOBE_RGB));
+ static_assert(static_cast<int>(ADATASPACE_BT2020) == static_cast<int>(HAL_DATASPACE_BT2020));
+ static_assert(static_cast<int>(ADATASPACE_BT709) == static_cast<int>(HAL_DATASPACE_V0_BT709));
+ static_assert(static_cast<int>(ADATASPACE_DCI_P3) == static_cast<int>(HAL_DATASPACE_DCI_P3));
+ static_assert(static_cast<int>(ADATASPACE_SRGB_LINEAR) == static_cast<int>(HAL_DATASPACE_V0_SRGB_LINEAR));
if (!window || !query(window, NATIVE_WINDOW_IS_VALID) ||
!isDataSpaceValid(window, dataSpace)) {
diff --git a/libs/nativewindow/include/android/data_space.h b/libs/nativewindow/include/android/data_space.h
index 2899bcf..e759513 100644
--- a/libs/nativewindow/include/android/data_space.h
+++ b/libs/nativewindow/include/android/data_space.h
@@ -101,6 +101,56 @@
* Use full range, SMPTE 2084 (PQ) transfer and BT2020 standard
*/
ADATASPACE_BT2020_PQ = 163971072, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_FULL
+
+ /**
+ * Adobe RGB
+ *
+ * Use full range, gamma 2.2 transfer and Adobe RGB primaries
+ * Note: Application is responsible for gamma encoding the data as
+ * a 2.2 gamma encoding is not supported in HW.
+ */
+ ADATASPACE_ADOBE_RGB = 151715840, // STANDARD_ADOBE_RGB | TRANSFER_GAMMA2_2 | RANGE_FULL
+
+ /**
+ * ITU-R Recommendation 2020 (BT.2020)
+ *
+ * Ultra High-definition television
+ *
+ * Use full range, BT.709 transfer and BT2020 standard
+ */
+ ADATASPACE_BT2020 = 147193856, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_FULL
+
+ /**
+ * ITU-R Recommendation 709 (BT.709)
+ *
+ * High-definition television
+ *
+ * Use limited range, BT.709 transfer and BT.709 standard.
+ */
+ ADATASPACE_BT709 = 281083904, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_LIMITED
+
+ /**
+ * SMPTE EG 432-1 and SMPTE RP 431-2.
+ *
+ * Digital Cinema DCI-P3
+ *
+ * Use full range, gamma 2.6 transfer and D65 DCI-P3 standard
+ * Note: Application is responsible for gamma encoding the data as
+ * a 2.6 gamma encoding is not supported in HW.
+ */
+ ADATASPACE_DCI_P3 = 155844608, // STANDARD_DCI_P3 | TRANSFER_GAMMA2_6 | RANGE_FULL
+
+ /**
+ * sRGB linear encoding:
+ *
+ * The red, green, and blue components are stored in sRGB space, but
+ * are linear, not gamma-encoded.
+ * The RGB primaries and the white point are the same as BT.709.
+ *
+ * The values are encoded using the full range ([0,255] for 8-bit) for all
+ * components.
+ */
+ ADATASPACE_SRGB_LINEAR = 138477568, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_FULL
};
__END_DECLS
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 0178811..26c2d3f 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -256,67 +256,6 @@
return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
}
-static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
- EventEntry* eventEntry,
- int32_t inputTargetFlags) {
- if (inputTarget.useDefaultPointerInfo()) {
- const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
- return std::make_unique<DispatchEntry>(eventEntry, // increments ref
- inputTargetFlags, pointerInfo.xOffset,
- pointerInfo.yOffset, inputTarget.globalScaleFactor,
- pointerInfo.windowXScale, pointerInfo.windowYScale);
- }
-
- ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
- const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
-
- PointerCoords pointerCoords[MAX_POINTERS];
-
- // Use the first pointer information to normalize all other pointers. This could be any pointer
- // as long as all other pointers are normalized to the same value and the final DispatchEntry
- // uses the offset and scale for the normalized pointer.
- const PointerInfo& firstPointerInfo =
- inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];
-
- // Iterate through all pointers in the event to normalize against the first.
- for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
- const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
- uint32_t pointerId = uint32_t(pointerProperties.id);
- const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];
-
- // The scale factor is the ratio of the current pointers scale to the normalized scale.
- float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
- float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;
-
- pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
- // First apply the current pointers offset to set the window at 0,0
- pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
- // Next scale the coordinates.
- pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
- // Lastly, offset the coordinates so they're in the normalized pointer's frame.
- pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
- -firstPointerInfo.yOffset);
- }
-
- MotionEntry* combinedMotionEntry =
- new MotionEntry(motionEntry.sequenceNum, motionEntry.eventTime, motionEntry.deviceId,
- motionEntry.source, motionEntry.displayId, motionEntry.policyFlags,
- motionEntry.action, motionEntry.actionButton, motionEntry.flags,
- motionEntry.metaState, motionEntry.buttonState,
- motionEntry.classification, motionEntry.edgeFlags,
- motionEntry.xPrecision, motionEntry.yPrecision,
- motionEntry.xCursorPosition, motionEntry.yCursorPosition,
- motionEntry.downTime, motionEntry.pointerCount,
- motionEntry.pointerProperties, pointerCoords, 0 /* xOffset */,
- 0 /* yOffset */);
-
- return std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
- inputTargetFlags, firstPointerInfo.xOffset,
- firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
- firstPointerInfo.windowXScale,
- firstPointerInfo.windowYScale);
-}
-
// --- InputDispatcherThread ---
class InputDispatcher::InputDispatcherThread : public Thread {
@@ -1172,7 +1111,7 @@
sp<Connection> connection =
getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
if (connection != nullptr) {
- prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
+ prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
} else {
if (DEBUG_FOCUS) {
ALOGD("Dropping event delivery to target with channel '%s' because it "
@@ -1846,34 +1785,23 @@
void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
int32_t targetFlags, BitSet32 pointerIds,
std::vector<InputTarget>& inputTargets) {
- std::vector<InputTarget>::iterator it =
- std::find_if(inputTargets.begin(), inputTargets.end(),
- [&windowHandle](const InputTarget& inputTarget) {
- return inputTarget.inputChannel->getConnectionToken() ==
- windowHandle->getToken();
- });
-
- const InputWindowInfo* windowInfo = windowHandle->getInfo();
-
- if (it == inputTargets.end()) {
- InputTarget inputTarget;
- sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
- if (inputChannel == nullptr) {
- ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
- return;
- }
- inputTarget.inputChannel = inputChannel;
- inputTarget.flags = targetFlags;
- inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
- inputTargets.push_back(inputTarget);
- it = inputTargets.end() - 1;
+ sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
+ if (inputChannel == nullptr) {
+ ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
+ return;
}
- ALOG_ASSERT(it->flags == targetFlags);
- ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);
-
- it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
- windowInfo->windowXScale, windowInfo->windowYScale);
+ const InputWindowInfo* windowInfo = windowHandle->getInfo();
+ InputTarget target;
+ target.inputChannel = inputChannel;
+ target.flags = targetFlags;
+ target.xOffset = -windowInfo->frameLeft;
+ target.yOffset = -windowInfo->frameTop;
+ target.globalScaleFactor = windowInfo->globalScaleFactor;
+ target.windowXScale = windowInfo->windowXScale;
+ target.windowYScale = windowInfo->windowYScale;
+ target.pointerIds = pointerIds;
+ inputTargets.push_back(target);
}
void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
@@ -1896,7 +1824,10 @@
InputTarget target;
target.inputChannel = monitor.inputChannel;
target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
- target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
+ target.xOffset = xOffset;
+ target.yOffset = yOffset;
+ target.pointerIds.clear();
+ target.globalScaleFactor = 1.0f;
inputTargets.push_back(target);
}
@@ -2114,7 +2045,7 @@
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection,
EventEntry* eventEntry,
- const InputTarget& inputTarget) {
+ const InputTarget* inputTarget) {
if (ATRACE_ENABLED()) {
std::string message =
StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
@@ -2125,9 +2056,9 @@
ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
"xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
"windowScaleFactor=(%f, %f), pointerIds=0x%x",
- connection->getInputChannelName().c_str(), inputTarget.flags, inputTarget.xOffset,
- inputTarget.yOffset, inputTarget.globalScaleFactor, inputTarget.windowXScale,
- inputTarget.windowYScale, inputTarget.pointerIds.value);
+ connection->getInputChannelName().c_str(), inputTarget->flags, inputTarget->xOffset,
+ inputTarget->yOffset, inputTarget->globalScaleFactor, inputTarget->windowXScale,
+ inputTarget->windowYScale, inputTarget->pointerIds.value);
#endif
// Skip this event if the connection status is not normal.
@@ -2141,13 +2072,13 @@
}
// Split a motion event if needed.
- if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
+ if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
- if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
+ if (inputTarget->pointerIds.count() != originalMotionEntry.pointerCount) {
MotionEntry* splitMotionEntry =
- splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
+ splitMotionEvent(originalMotionEntry, inputTarget->pointerIds);
if (!splitMotionEntry) {
return; // split event was dropped
}
@@ -2169,7 +2100,7 @@
void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
const sp<Connection>& connection,
EventEntry* eventEntry,
- const InputTarget& inputTarget) {
+ const InputTarget* inputTarget) {
if (ATRACE_ENABLED()) {
std::string message =
StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
@@ -2202,7 +2133,7 @@
void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
EventEntry* eventEntry,
- const InputTarget& inputTarget,
+ const InputTarget* inputTarget,
int32_t dispatchMode) {
if (ATRACE_ENABLED()) {
std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
@@ -2210,7 +2141,7 @@
dispatchModeToString(dispatchMode).c_str());
ATRACE_NAME(message.c_str());
}
- int32_t inputTargetFlags = inputTarget.flags;
+ int32_t inputTargetFlags = inputTarget->flags;
if (!(inputTargetFlags & dispatchMode)) {
return;
}
@@ -2218,8 +2149,11 @@
// This is a new event.
// Enqueue a new dispatch entry onto the outbound queue for this connection.
- std::unique_ptr<DispatchEntry> dispatchEntry =
- createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
+ DispatchEntry* dispatchEntry =
+ new DispatchEntry(eventEntry, // increments ref
+ inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
+ inputTarget->globalScaleFactor, inputTarget->windowXScale,
+ inputTarget->windowYScale);
// Apply target flags and update the connection's input state.
switch (eventEntry->type) {
@@ -2234,6 +2168,7 @@
ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
connection->getInputChannelName().c_str());
#endif
+ delete dispatchEntry;
return; // skip the inconsistent event
}
break;
@@ -2280,11 +2215,12 @@
"event",
connection->getInputChannelName().c_str());
#endif
+ delete dispatchEntry;
return; // skip the inconsistent event
}
dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
- inputTarget.inputChannel->getConnectionToken());
+ inputTarget->inputChannel->getConnectionToken());
break;
}
@@ -2302,7 +2238,7 @@
}
// Enqueue the dispatch entry.
- connection->outboundQueue.push_back(dispatchEntry.release());
+ connection->outboundQueue.push_back(dispatchEntry);
traceOutboundQueueLength(connection);
}
@@ -2675,15 +2611,21 @@
getWindowHandleLocked(connection->inputChannel->getConnectionToken());
if (windowHandle != nullptr) {
const InputWindowInfo* windowInfo = windowHandle->getInfo();
- target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
- windowInfo->windowXScale, windowInfo->windowYScale);
+ target.xOffset = -windowInfo->frameLeft;
+ target.yOffset = -windowInfo->frameTop;
target.globalScaleFactor = windowInfo->globalScaleFactor;
+ target.windowXScale = windowInfo->windowXScale;
+ target.windowYScale = windowInfo->windowYScale;
+ } else {
+ target.xOffset = 0;
+ target.yOffset = 0;
+ target.globalScaleFactor = 1.0f;
}
target.inputChannel = connection->inputChannel;
target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
- target, InputTarget::FLAG_DISPATCH_AS_IS);
+ &target, InputTarget::FLAG_DISPATCH_AS_IS);
cancelationEventEntry->release();
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 50b5250..f9eca01 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -378,13 +378,13 @@
// with the mutex held makes it easier to ensure that connection invariants are maintained.
// If needed, the methods post commands to run later once the critical bits are done.
void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
- EventEntry* eventEntry, const InputTarget& inputTarget)
+ EventEntry* eventEntry, const InputTarget* inputTarget)
REQUIRES(mLock);
void enqueueDispatchEntriesLocked(nsecs_t currentTime, const sp<Connection>& connection,
- EventEntry* eventEntry, const InputTarget& inputTarget)
+ EventEntry* eventEntry, const InputTarget* inputTarget)
REQUIRES(mLock);
void enqueueDispatchEntryLocked(const sp<Connection>& connection, EventEntry* eventEntry,
- const InputTarget& inputTarget, int32_t dispatchMode)
+ const InputTarget* inputTarget, int32_t dispatchMode)
REQUIRES(mLock);
void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection)
REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/InputTarget.cpp b/services/inputflinger/dispatcher/InputTarget.cpp
index bd7cb3e..80fa2cb 100644
--- a/services/inputflinger/dispatcher/InputTarget.cpp
+++ b/services/inputflinger/dispatcher/InputTarget.cpp
@@ -42,43 +42,4 @@
return StringPrintf("%" PRId32, dispatchMode);
}
-void InputTarget::addPointers(BitSet32 newPointerIds, float xOffset, float yOffset,
- float windowXScale, float windowYScale) {
- // The pointerIds can be empty, but still a valid InputTarget. This can happen for Monitors
- // and non splittable windows since we will just use all the pointers from the input event.
- if (newPointerIds.isEmpty()) {
- setDefaultPointerInfo(xOffset, yOffset, windowXScale, windowYScale);
- return;
- }
-
- // Ensure that the new set of pointers doesn't overlap with the current set of pointers.
- ALOG_ASSERT((pointerIds & newPointerIds) == 0);
-
- pointerIds |= newPointerIds;
- while (!newPointerIds.isEmpty()) {
- int32_t pointerId = newPointerIds.clearFirstMarkedBit();
- pointerInfos[pointerId].xOffset = xOffset;
- pointerInfos[pointerId].yOffset = yOffset;
- pointerInfos[pointerId].windowXScale = windowXScale;
- pointerInfos[pointerId].windowYScale = windowYScale;
- }
-}
-
-void InputTarget::setDefaultPointerInfo(float xOffset, float yOffset, float windowXScale,
- float windowYScale) {
- pointerIds.clear();
- pointerInfos[0].xOffset = xOffset;
- pointerInfos[0].yOffset = yOffset;
- pointerInfos[0].windowXScale = windowXScale;
- pointerInfos[0].windowYScale = windowYScale;
-}
-
-bool InputTarget::useDefaultPointerInfo() const {
- return pointerIds.isEmpty();
-}
-
-const PointerInfo& InputTarget::getDefaultPointerInfo() const {
- return pointerInfos[0];
-}
-
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputTarget.h b/services/inputflinger/dispatcher/InputTarget.h
index fd98df1..2e9bca2 100644
--- a/services/inputflinger/dispatcher/InputTarget.h
+++ b/services/inputflinger/dispatcher/InputTarget.h
@@ -24,22 +24,6 @@
namespace android::inputdispatcher {
/*
- * Information about each pointer for an InputTarget. This includes offset and scale so
- * all pointers can be normalized to a single offset and scale.
- */
-struct PointerInfo {
- // The x and y offset to add to a MotionEvent as it is delivered.
- // (ignored for KeyEvents)
- float xOffset = 0.0f;
- float yOffset = 0.0f;
-
- // Scaling factor to apply to MotionEvent as it is delivered.
- // (ignored for KeyEvents)
- float windowXScale = 1.0f;
- float windowYScale = 1.0f;
-};
-
-/*
* An input target specifies how an input event is to be dispatched to a particular window
* including the window's input channel, control flags, a timeout, and an X / Y offset to
* be added to input event coordinates to compensate for the absolute position of the
@@ -111,35 +95,20 @@
// Flags for the input target.
int32_t flags = 0;
+ // The x and y offset to add to a MotionEvent as it is delivered.
+ // (ignored for KeyEvents)
+ float xOffset = 0.0f;
+ float yOffset = 0.0f;
+
// Scaling factor to apply to MotionEvent as it is delivered.
// (ignored for KeyEvents)
float globalScaleFactor = 1.0f;
+ float windowXScale = 1.0f;
+ float windowYScale = 1.0f;
// The subset of pointer ids to include in motion events dispatched to this input target
// if FLAG_SPLIT is set.
- BitSet32 pointerIds;
- // The data is stored by the pointerId. Use the marked bits in pointerIds to look up PointerInfo
- // per pointerId.
- PointerInfo pointerInfos[MAX_POINTERS];
-
- void addPointers(BitSet32 pointerIds, float xOffset, float yOffset, float windowXScale,
- float windowYScale);
- void setDefaultPointerInfo(float xOffset, float yOffset, float windowXScale,
- float windowYScale);
-
- /**
- * Returns whether the default pointer information should be used. This will be true when the
- * InputTarget doesn't have any bits set in the pointerIds bitset. This can happen for monitors
- * and non splittable windows since we want all pointers for the EventEntry to go to this
- * target.
- */
- bool useDefaultPointerInfo() const;
-
- /**
- * Returns the default PointerInfo object. This should be used when useDefaultPointerInfo is
- * true.
- */
- const PointerInfo& getDefaultPointerInfo() const;
+ BitSet32 pointerIds{};
};
std::string dispatchModeToString(int32_t dispatchMode);
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index bd8d2a4..5ffc89d 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -1439,107 +1439,4 @@
consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
}
-TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchDifferentScale) {
- mWindow2->setWindowScale(0.5f, 0.5f);
-
- // Touch Window 1
- std::vector<PointF> touchedPoints = {PointF{10, 10}};
- std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
-
- NotifyMotionArgs motionArgs =
- generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
- ADISPLAY_ID_DEFAULT, touchedPoints);
- mDispatcher->notifyMotion(&motionArgs);
- consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, expectedPoints);
-
- // Touch Window 2
- int32_t actionPointerDown =
- AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
- touchedPoints.emplace_back(PointF{150, 150});
- expectedPoints.emplace_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
-
- motionArgs = generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN,
- ADISPLAY_ID_DEFAULT, touchedPoints);
- mDispatcher->notifyMotion(&motionArgs);
-
- // Consuming from window1 since it's the window that has the InputReceiver
- consumeMotionEvent(mWindow1, actionPointerDown, expectedPoints);
-}
-
-TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchMoveDifferentScale) {
- mWindow2->setWindowScale(0.5f, 0.5f);
-
- // Touch Window 1
- std::vector<PointF> touchedPoints = {PointF{10, 10}};
- std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
-
- NotifyMotionArgs motionArgs =
- generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
- ADISPLAY_ID_DEFAULT, touchedPoints);
- mDispatcher->notifyMotion(&motionArgs);
- consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, expectedPoints);
-
- // Touch Window 2
- int32_t actionPointerDown =
- AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
- touchedPoints.emplace_back(PointF{150, 150});
- expectedPoints.emplace_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
-
- motionArgs = generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN,
- ADISPLAY_ID_DEFAULT, touchedPoints);
- mDispatcher->notifyMotion(&motionArgs);
-
- // Consuming from window1 since it's the window that has the InputReceiver
- consumeMotionEvent(mWindow1, actionPointerDown, expectedPoints);
-
- // Move both windows
- touchedPoints = {{20, 20}, {175, 175}};
- expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
- getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
-
- motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
- ADISPLAY_ID_DEFAULT, touchedPoints);
- mDispatcher->notifyMotion(&motionArgs);
-
- consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_MOVE, expectedPoints);
-}
-
-TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithScale) {
- mWindow1->setWindowScale(0.5f, 0.5f);
-
- // Touch Window 1
- std::vector<PointF> touchedPoints = {PointF{10, 10}};
- std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};
-
- NotifyMotionArgs motionArgs =
- generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
- ADISPLAY_ID_DEFAULT, touchedPoints);
- mDispatcher->notifyMotion(&motionArgs);
- consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, expectedPoints);
-
- // Touch Window 2
- int32_t actionPointerDown =
- AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
- touchedPoints.emplace_back(PointF{150, 150});
- expectedPoints.emplace_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));
-
- motionArgs = generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN,
- ADISPLAY_ID_DEFAULT, touchedPoints);
- mDispatcher->notifyMotion(&motionArgs);
-
- // Consuming from window1 since it's the window that has the InputReceiver
- consumeMotionEvent(mWindow1, actionPointerDown, expectedPoints);
-
- // Move both windows
- touchedPoints = {{20, 20}, {175, 175}};
- expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
- getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};
-
- motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
- ADISPLAY_ID_DEFAULT, touchedPoints);
- mDispatcher->notifyMotion(&motionArgs);
-
- consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_MOVE, expectedPoints);
-}
-
} // namespace android::inputdispatcher
diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc
index aea602b..d3942e8 100644
--- a/services/surfaceflinger/surfaceflinger.rc
+++ b/services/surfaceflinger/surfaceflinger.rc
@@ -2,6 +2,7 @@
class core animation
user system
group graphics drmrpc readproc
+ capabilities SYS_NICE
onrestart restart zygote
writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index a4d9ff3..0403237 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -53,11 +53,15 @@
"libgui",
"liblayers_proto",
"liblog",
+ "libnativewindow",
"libprotobuf-cpp-full",
"libtimestats_proto",
"libui",
"libutils",
- ]
+ ],
+ header_libs: [
+ "libnativewindow_headers",
+ ],
}
cc_defaults {
diff --git a/services/surfaceflinger/tests/CommonTypes_test.cpp b/services/surfaceflinger/tests/CommonTypes_test.cpp
index ab4af09..25b4615 100644
--- a/services/surfaceflinger/tests/CommonTypes_test.cpp
+++ b/services/surfaceflinger/tests/CommonTypes_test.cpp
@@ -16,6 +16,7 @@
#include <aidl/android/hardware/graphics/common/BlendMode.h>
#include <aidl/android/hardware/graphics/common/Dataspace.h>
+#include <android/data_space.h>
#include <android/hardware/graphics/common/1.2/types.h>
#include <android/hardware/graphics/composer/2.1/IComposerClient.h>
@@ -34,6 +35,51 @@
static_assert(static_cast<uint32_t>(AidlBlendMode::COVERAGE) ==
static_cast<uint32_t>(HidlBlendMode::COVERAGE));
+static_assert(static_cast<uint32_t>(ADATASPACE_UNKNOWN) ==
+ static_cast<uint32_t>(AidlDataspace::UNKNOWN));
+static_assert(static_cast<uint32_t>(ADATASPACE_SCRGB_LINEAR) ==
+ static_cast<uint32_t>(AidlDataspace::SCRGB_LINEAR));
+static_assert(static_cast<uint32_t>(ADATASPACE_SRGB) == static_cast<uint32_t>(AidlDataspace::SRGB));
+static_assert(static_cast<uint32_t>(ADATASPACE_SCRGB) ==
+ static_cast<uint32_t>(AidlDataspace::SCRGB));
+static_assert(static_cast<uint32_t>(ADATASPACE_DISPLAY_P3) ==
+ static_cast<uint32_t>(AidlDataspace::DISPLAY_P3));
+static_assert(static_cast<uint32_t>(ADATASPACE_BT2020_PQ) ==
+ static_cast<uint32_t>(AidlDataspace::BT2020_PQ));
+static_assert(static_cast<uint32_t>(ADATASPACE_ADOBE_RGB) ==
+ static_cast<uint32_t>(AidlDataspace::ADOBE_RGB));
+static_assert(static_cast<uint32_t>(ADATASPACE_BT2020) ==
+ static_cast<uint32_t>(AidlDataspace::BT2020));
+static_assert(static_cast<uint32_t>(ADATASPACE_BT709) ==
+ static_cast<uint32_t>(AidlDataspace::BT709));
+static_assert(static_cast<uint32_t>(ADATASPACE_DCI_P3) ==
+ static_cast<uint32_t>(AidlDataspace::DCI_P3));
+static_assert(static_cast<uint32_t>(ADATASPACE_SRGB_LINEAR) ==
+ static_cast<uint32_t>(AidlDataspace::SRGB_LINEAR));
+
+static_assert(static_cast<uint32_t>(ADATASPACE_UNKNOWN) ==
+ static_cast<uint32_t>(HidlDataspace::UNKNOWN));
+static_assert(static_cast<uint32_t>(ADATASPACE_SCRGB_LINEAR) ==
+ static_cast<uint32_t>(HidlDataspace::V0_SCRGB_LINEAR));
+static_assert(static_cast<uint32_t>(ADATASPACE_SRGB) ==
+ static_cast<uint32_t>(HidlDataspace::V0_SRGB));
+static_assert(static_cast<uint32_t>(ADATASPACE_SCRGB) ==
+ static_cast<uint32_t>(HidlDataspace::V0_SCRGB));
+static_assert(static_cast<uint32_t>(ADATASPACE_DISPLAY_P3) ==
+ static_cast<uint32_t>(HidlDataspace::DISPLAY_P3));
+static_assert(static_cast<uint32_t>(ADATASPACE_BT2020_PQ) ==
+ static_cast<uint32_t>(HidlDataspace::BT2020_PQ));
+static_assert(static_cast<uint32_t>(ADATASPACE_ADOBE_RGB) ==
+ static_cast<uint32_t>(HidlDataspace::ADOBE_RGB));
+static_assert(static_cast<uint32_t>(ADATASPACE_BT2020) ==
+ static_cast<uint32_t>(HidlDataspace::BT2020));
+static_assert(static_cast<uint32_t>(ADATASPACE_BT709) ==
+ static_cast<uint32_t>(HidlDataspace::V0_BT709));
+static_assert(static_cast<uint32_t>(ADATASPACE_DCI_P3) ==
+ static_cast<uint32_t>(HidlDataspace::DCI_P3));
+static_assert(static_cast<uint32_t>(ADATASPACE_SRGB_LINEAR) ==
+ static_cast<uint32_t>(HidlDataspace::V0_SRGB_LINEAR));
+
static_assert(static_cast<uint32_t>(AidlDataspace::UNKNOWN) ==
static_cast<uint32_t>(HidlDataspace::UNKNOWN));
static_assert(static_cast<uint32_t>(AidlDataspace::ARBITRARY) ==