Merge "Replace KeyedVector with unordered_map in dispatcher"
diff --git a/include/android/input.h b/include/android/input.h
index dbfd61e..7c39234 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -55,6 +55,7 @@
#include <sys/types.h>
#include <android/keycodes.h>
#include <android/looper.h>
+#include <jni.h>
#if !defined(__INTRODUCED_IN)
#define __INTRODUCED_IN(__api_level) /* nothing */
@@ -931,6 +932,15 @@
/** Get the input event source. */
int32_t AInputEvent_getSource(const AInputEvent* event);
+/**
+ * Releases interface objects created by {@link AKeyEvent_fromJava()}
+ * and {@link AMotionEvent_fromJava()}.
+ * After returning, the specified AInputEvent* object becomes invalid and should no longer be used.
+ * The underlying Java object remains valid and does not change its state.
+ */
+
+void AInputEvent_release(const AInputEvent* event);
+
/*** Accessors for key events only. ***/
/** Get the key event action. */
@@ -977,6 +987,15 @@
*/
int64_t AKeyEvent_getEventTime(const AInputEvent* key_event);
+/**
+ * Creates a native AInputEvent* object associated with the specified Java android.view.KeyEvent.
+ * The result may be used with generic and KeyEvent-specific AInputEvent_* functions.
+ * The object returned by this function must be disposed using {@link AInputEvent_release()}.
+ * User must guarantee that lifetime for object referenced by keyEvent is prolongated
+ * up to release of returned AInputEvent*.
+ */
+const AInputEvent* AKeyEvent_fromJava(JNIEnv* env, jobject keyEvent);
+
/*** Accessors for motion events only. ***/
/** Get the combined motion event action code and pointer index. */
@@ -1292,6 +1311,14 @@
float AMotionEvent_getHistoricalAxisValue(const AInputEvent* motion_event,
int32_t axis, size_t pointer_index, size_t history_index);
+/**
+ * Creates a native AInputEvent* object associated with the specified Java android.view.MotionEvent.
+ * The result may be used with generic and MotionEvent-specific AInputEvent_* functions.
+ * The object returned by this function must be disposed using {@link AInputEvent_release()}.
+ * User must guarantee that object referenced by motionEvent won't be recycled and
+ * its lifetime is prolongated up to release of returned AInputEvent*.
+ */
+const AInputEvent* AMotionEvent_fromJava(JNIEnv* env, jobject motionEvent);
struct AInputQueue;
/**
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index e43af67..9483156 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -793,8 +793,7 @@
}
virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
- uint8_t componentMask,
- uint64_t maxFrames) const {
+ uint8_t componentMask, uint64_t maxFrames) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeStrongBinder(display);
@@ -1036,7 +1035,7 @@
return NO_ERROR;
}
- virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) const {
+ virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) {
Parcel data, reply;
status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
if (error != NO_ERROR) {
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 3cef256..b4a3fbe 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -383,7 +383,7 @@
*/
virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
uint8_t componentMask,
- uint64_t maxFrames) const = 0;
+ uint64_t maxFrames) = 0;
/* Returns statistics on the color profile of the last frame displayed for a given display
*
@@ -468,8 +468,7 @@
* BAD_VALUE if the brightness is invalid, or
* INVALID_OPERATION if brightness operations are not supported.
*/
- virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken,
- float brightness) const = 0;
+ virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) = 0;
/*
* Sends a power hint to the composer. This function is asynchronous.
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index ef1fd02..2de6b69 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -804,7 +804,7 @@
}
status_t setDisplayContentSamplingEnabled(const sp<IBinder>& /*display*/, bool /*enable*/,
uint8_t /*componentMask*/,
- uint64_t /*maxFrames*/) const override {
+ uint64_t /*maxFrames*/) override {
return NO_ERROR;
}
status_t getDisplayedContentSample(const sp<IBinder>& /*display*/, uint64_t /*maxFrames*/,
@@ -822,7 +822,7 @@
return NO_ERROR;
}
status_t setDisplayBrightness(const sp<IBinder>& /*displayToken*/,
- float /*brightness*/) const override {
+ float /*brightness*/) override {
return NO_ERROR;
}
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 1622e77..106efd6 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -93,23 +93,6 @@
return nullptr;
}
-void SensorService::SensorDirectConnection::updateSensorSubscriptions() {
- if (!hasSensorAccess()) {
- stopAll(true /* backupRecord */);
- } else {
- recoverAll();
- }
-}
-
-void SensorService::SensorDirectConnection::setSensorAccess(bool hasAccess) {
- mHasSensorAccess = hasAccess;
- updateSensorSubscriptions();
-}
-
-bool SensorService::SensorDirectConnection::hasSensorAccess() const {
- return mHasSensorAccess && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled();
-}
-
status_t SensorService::SensorDirectConnection::enableDisable(
int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
int reservedFlags) {
diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h
index fa88fbc..ead08d3 100644
--- a/services/sensorservice/SensorDirectConnection.h
+++ b/services/sensorservice/SensorDirectConnection.h
@@ -54,9 +54,6 @@
// called by SensorService when return to NORMAL mode.
void recoverAll();
- void updateSensorSubscriptions();
-
- void setSensorAccess(bool hasAccess);
protected:
virtual ~SensorDirectConnection();
// ISensorEventConnection functions
@@ -69,7 +66,6 @@
virtual int32_t configureChannel(int handle, int rateLevel);
virtual void destroy();
private:
- bool hasSensorAccess() const;
const sp<SensorService> mService;
const uid_t mUid;
const sensors_direct_mem_t mMem;
@@ -80,8 +76,6 @@
std::unordered_map<int, int> mActivated;
std::unordered_map<int, int> mActivatedBackup;
- std::atomic_bool mHasSensorAccess = true;
-
mutable Mutex mDestroyLock;
bool mDestroyed;
};
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 5be4ccd..e799372 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <cinttypes>
#include <sys/socket.h>
#include <utils/threads.h>
@@ -70,16 +69,17 @@
}
bool SensorService::SensorEventConnection::needsWakeLock() {
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
return !mDead && mWakeLockRefCount > 0;
}
void SensorService::SensorEventConnection::resetWakeLockRefCount() {
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
mWakeLockRefCount = 0;
}
void SensorService::SensorEventConnection::dump(String8& result) {
+ Mutex::Autolock _l(mConnectionLock);
result.appendFormat("\tOperating Mode: ");
if (!mService->isWhiteListedPackage(getPackageName())) {
result.append("RESTRICTED\n");
@@ -91,10 +91,8 @@
result.appendFormat("\t %s | WakeLockRefCount %d | uid %d | cache size %d | "
"max cache size %d\n", mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize,
mMaxCacheSize);
-
- std::lock_guard<std::mutex> _l(mConnectionLock);
for (auto& it : mSensorInfo) {
- const FlushInfo& flushInfo = it.second.flushInfo;
+ const FlushInfo& flushInfo = it.second;
result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
mService->getSensorName(it.first).string(),
it.first,
@@ -123,7 +121,7 @@
*/
void SensorService::SensorEventConnection::dump(util::ProtoOutputStream* proto) const {
using namespace service::SensorEventConnectionProto;
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
if (!mService->isWhiteListedPackage(getPackageName())) {
proto->write(OPERATING_MODE, OP_MODE_RESTRICTED);
@@ -138,7 +136,7 @@
proto->write(CACHE_SIZE, int32_t(mCacheSize));
proto->write(MAX_CACHE_SIZE, int32_t(mMaxCacheSize));
for (auto& it : mSensorInfo) {
- const FlushInfo& flushInfo = it.second.flushInfo;
+ const FlushInfo& flushInfo = it.second;
const uint64_t token = proto->start(FLUSH_INFOS);
proto->write(FlushInfoProto::SENSOR_NAME,
std::string(mService->getSensorName(it.first)));
@@ -159,33 +157,28 @@
#endif
}
-bool SensorService::SensorEventConnection::addSensor(
- int32_t handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags) {
- std::lock_guard<std::mutex> _l(mConnectionLock);
+bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
+ Mutex::Autolock _l(mConnectionLock);
sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
if (si == nullptr ||
!canAccessSensor(si->getSensor(), "Tried adding", mOpPackageName) ||
mSensorInfo.count(handle) > 0) {
return false;
}
-
- SensorRequest request = {
- .samplingPeriodNs = samplingPeriodNs,
- .maxBatchReportLatencyNs = maxBatchReportLatencyNs,
- .reservedFlags = reservedFlags
- };
-
- mSensorInfo[handle] = request;
+ mSensorInfo[handle] = FlushInfo();
return true;
}
bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
- std::lock_guard<std::mutex> _l(mConnectionLock);
- return mSensorInfo.erase(handle) > 0;
+ Mutex::Autolock _l(mConnectionLock);
+ if (mSensorInfo.erase(handle) >= 0) {
+ return true;
+ }
+ return false;
}
std::vector<int32_t> SensorService::SensorEventConnection::getActiveSensorHandles() const {
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
std::vector<int32_t> list;
for (auto& it : mSensorInfo) {
list.push_back(it.first);
@@ -194,19 +187,17 @@
}
bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
- std::lock_guard<std::recursive_mutex> _backlock(mBackupLock);
- std::lock_guard<std::mutex> _lock(mConnectionLock);
- return mSensorInfo.count(handle) + mSensorInfoBackup.count(handle) > 0;
+ Mutex::Autolock _l(mConnectionLock);
+ return mSensorInfo.count(handle) > 0;
}
bool SensorService::SensorEventConnection::hasAnySensor() const {
- std::lock_guard<std::recursive_mutex> _backlock(mBackupLock);
- std::lock_guard<std::mutex> _lock(mConnectionLock);
- return mSensorInfo.size() + mSensorInfoBackup.size() ? true : false;
+ Mutex::Autolock _l(mConnectionLock);
+ return mSensorInfo.size() ? true : false;
}
bool SensorService::SensorEventConnection::hasOneShotSensors() const {
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
for (auto &it : mSensorInfo) {
const int handle = it.first;
sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
@@ -223,15 +214,15 @@
void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
bool value) {
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
if (mSensorInfo.count(handle) > 0) {
- FlushInfo& flushInfo = mSensorInfo[handle].flushInfo;
+ FlushInfo& flushInfo = mSensorInfo[handle];
flushInfo.mFirstFlushPending = value;
}
}
void SensorService::SensorEventConnection::updateLooperRegistration(const sp<Looper>& looper) {
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
updateLooperRegistrationLocked(looper);
}
@@ -282,9 +273,9 @@
}
void SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
if (mSensorInfo.count(handle) > 0) {
- FlushInfo& flushInfo = mSensorInfo[handle].flushInfo;
+ FlushInfo& flushInfo = mSensorInfo[handle];
flushInfo.mPendingFlushEventsToSend++;
}
}
@@ -298,7 +289,7 @@
std::unique_ptr<sensors_event_t[]> sanitizedBuffer;
int count = 0;
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
if (scratch) {
size_t i=0;
while (i<numEvents) {
@@ -319,7 +310,7 @@
continue;
}
- FlushInfo& flushInfo = mSensorInfo[sensor_handle].flushInfo;
+ FlushInfo& flushInfo = mSensorInfo[sensor_handle];
// Check if there is a pending flush_complete event for this sensor on this connection.
if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
mapFlushEventsToConnections[i] == this) {
@@ -440,62 +431,9 @@
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
-void SensorService::SensorEventConnection::updateSensorSubscriptions() {
- if (!hasSensorAccess()) {
- stopAll();
- } else {
- recoverAll();
- }
-}
-
void SensorService::SensorEventConnection::setSensorAccess(const bool hasAccess) {
- if (mHasSensorAccess != hasAccess) {
- mHasSensorAccess = hasAccess;
- updateSensorSubscriptions();
- }
-}
-
-void SensorService::SensorEventConnection::stopAll() {
- bool backupPerformed = false;
- std::lock_guard<std::recursive_mutex> _backlock(mBackupLock);
- {
- std::lock_guard<std::mutex> _lock(mConnectionLock);
- if (!mSensorInfo.empty()) {
- mSensorInfoBackup = mSensorInfo;
- mSensorInfo.clear();
- backupPerformed = true;
- }
- }
-
- if (backupPerformed) {
- for (auto& it : mSensorInfoBackup) {
- int32_t handle = it.first;
-
- status_t err = mService->disable(this, handle);
-
- if (err != NO_ERROR) {
- ALOGE("Error disabling sensor %d", handle);
- }
- }
- }
-}
-
-void SensorService::SensorEventConnection::recoverAll() {
- std::lock_guard<std::recursive_mutex> _l(mBackupLock);
- for (auto& it : mSensorInfoBackup) {
- int32_t handle = it.first;
- SensorRequest &request = it.second;
-
- status_t err = mService->enable(
- this, handle, request.samplingPeriodNs, request.maxBatchReportLatencyNs,
- request.reservedFlags, mOpPackageName);
-
- if (err != NO_ERROR) {
- ALOGE("Error recovering sensor %d", handle);
- }
- }
-
- mSensorInfoBackup.clear();
+ Mutex::Autolock _l(mConnectionLock);
+ mHasSensorAccess = hasAccess;
}
bool SensorService::SensorEventConnection::hasSensorAccess() {
@@ -597,7 +535,7 @@
continue;
}
- FlushInfo& flushInfo = it.second.flushInfo;
+ FlushInfo& flushInfo = it.second;
while (flushInfo.mPendingFlushEventsToSend > 0) {
flushCompleteEvent.meta_data.sensor = handle;
bool wakeUpSensor = si->getSensor().isWakeUpSensor();
@@ -622,7 +560,7 @@
// half the size of the socket buffer allocated in BitTube whichever is smaller.
const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
// Send pending flush complete events (if any)
sendPendingFlushEventsLocked();
for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
@@ -689,7 +627,7 @@
continue;
}
- FlushInfo& flushInfo = mSensorInfo[scratch[j].meta_data.sensor].flushInfo;
+ FlushInfo& flushInfo = mSensorInfo[scratch[j].meta_data.sensor];
flushInfo.mPendingFlushEventsToSend++;
ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
flushInfo.mPendingFlushEventsToSend);
@@ -725,21 +663,13 @@
} else {
err = mService->disable(this, handle);
}
-
return err;
}
status_t SensorService::SensorEventConnection::setEventRate(
int handle, nsecs_t samplingPeriodNs)
{
- status_t err = mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
-
- std::lock_guard<std::mutex> _l(mConnectionLock);
- if (err == NO_ERROR && mSensorInfo.count(handle) > 0) {
- mSensorInfo[handle].samplingPeriodNs = samplingPeriodNs;
- }
-
- return err;
+ return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
}
status_t SensorService::SensorEventConnection::flush() {
@@ -760,7 +690,7 @@
// and remove the fd from Looper. Call checkWakeLockState to know if SensorService
// can release the wake-lock.
ALOGD_IF(DEBUG_CONNECTIONS, "%p Looper error %d", this, fd);
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
mDead = true;
mWakeLockRefCount = 0;
updateLooperRegistrationLocked(mService->getLooper());
@@ -779,7 +709,7 @@
unsigned char buf[sizeof(sensors_event_t)];
ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
{
- std::lock_guard<std::mutex> _l(mConnectionLock);
+ Mutex::Autolock _l(mConnectionLock);
if (numBytesRead == sizeof(sensors_event_t)) {
if (!mDataInjectionMode) {
ALOGE("Data injected in normal mode, dropping event"
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 80e7431..1ca35c0 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -57,8 +57,7 @@
bool hasSensor(int32_t handle) const;
bool hasAnySensor() const;
bool hasOneShotSensors() const;
- bool addSensor(
- int32_t handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags);
+ bool addSensor(int32_t handle);
bool removeSensor(int32_t handle);
std::vector<int32_t> getActiveSensorHandles() const;
void setFirstFlushPending(int32_t handle, bool value);
@@ -71,7 +70,7 @@
uid_t getUid() const { return mUid; }
void setSensorAccess(const bool hasAccess);
- void updateSensorSubscriptions();
+
private:
virtual ~SensorEventConnection();
virtual void onFirstRef();
@@ -137,22 +136,13 @@
// privacy not being enabled.
bool hasSensorAccess();
- void stopAll();
- void recoverAll();
-
// Call noteOp for the sensor if the sensor requires a permission
bool noteOpIfRequired(const sensors_event_t& event);
sp<SensorService> const mService;
sp<BitTube> mChannel;
uid_t mUid;
-
- // A lock that should be used when modifying mSensorInfo
- mutable std::mutex mConnectionLock;
-
- // A lock that should be used when modifying mSensorInfoBackup
- mutable std::recursive_mutex mBackupLock;
-
+ mutable Mutex mConnectionLock;
// Number of events from wake up sensors which are still pending and haven't been delivered to
// the corresponding application. It is incremented by one unit for each write to the socket.
uint32_t mWakeLockRefCount;
@@ -179,17 +169,8 @@
FlushInfo() : mPendingFlushEventsToSend(0), mFirstFlushPending(false) {}
};
-
- struct SensorRequest {
- nsecs_t samplingPeriodNs;
- nsecs_t maxBatchReportLatencyNs;
- int reservedFlags;
- FlushInfo flushInfo;
- };
-
// protected by SensorService::mLock. Key for this map is the sensor handle.
- std::unordered_map<int32_t, SensorRequest> mSensorInfo;
- std::unordered_map<int32_t, SensorRequest> mSensorInfoBackup;
+ std::unordered_map<int32_t, FlushInfo> mSensorInfo;
sensors_event_t *mEventCache;
int mCacheSize, mMaxCacheSize;
@@ -204,7 +185,7 @@
mutable Mutex mDestroyLock;
bool mDestroyed;
- std::atomic_bool mHasSensorAccess;
+ bool mHasSensorAccess;
// Store a mapping of sensor handles to required AppOp for a sensor. This map only contains a
// valid mapping for sensors that require a permission in order to reduce the lookup time.
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 29df825..5fdc74f 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -301,24 +301,11 @@
void SensorService::setSensorAccess(uid_t uid, bool hasAccess) {
ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
- const auto& connections = connLock.getActiveConnections();
- const auto& directConnections = connLock.getDirectConnections();
-
- mLock.unlock();
- for (const sp<SensorEventConnection>& conn : connections) {
+ for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) {
if (conn->getUid() == uid) {
conn->setSensorAccess(hasAccess);
}
}
-
- for (const sp<SensorDirectConnection>& conn : directConnections) {
- if (conn->getUid() == uid) {
- conn->setSensorAccess(hasAccess);
- }
- }
-
- // Lock the mutex again for clean shutdown
- mLock.lock();
}
const Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual) {
@@ -651,11 +638,8 @@
void SensorService::disableAllSensorsLocked(ConnectionSafeAutolock* connLock) {
SensorDevice& dev(SensorDevice::getInstance());
- for (const sp<SensorEventConnection>& connection : connLock->getActiveConnections()) {
- connection->updateSensorSubscriptions();
- }
for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) {
- connection->updateSensorSubscriptions();
+ connection->stopAll(true /* backupRecord */);
}
dev.disableAllSensors();
// Clear all pending flush connections for all active sensors. If one of the active
@@ -682,11 +666,8 @@
}
SensorDevice& dev(SensorDevice::getInstance());
dev.enableAllSensors();
- for (const sp<SensorEventConnection>& connection : connLock->getActiveConnections()) {
- connection->updateSensorSubscriptions();
- }
for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) {
- connection->updateSensorSubscriptions();
+ connection->recoverAll();
}
}
@@ -1608,7 +1589,7 @@
}
}
- if (connection->addSensor(handle, samplingPeriodNs, maxBatchReportLatencyNs, reservedFlags)) {
+ if (connection->addSensor(handle)) {
BatteryService::enableSensor(connection->getUid(), handle);
// the sensor was added (which means it wasn't already there)
// so, see if this connection becomes active
@@ -1758,22 +1739,17 @@
const int halVersion = dev.getHalDeviceVersion();
status_t err(NO_ERROR);
Mutex::Autolock _l(mLock);
-
- size_t numSensors = 0;
// Loop through all sensors for this connection and call flush on each of them.
for (int handle : connection->getActiveSensorHandles()) {
sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
if (sensor == nullptr) {
continue;
}
- numSensors++;
-
if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
ALOGE("flush called on a one-shot sensor");
err = INVALID_OPERATION;
continue;
}
-
if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
// For older devices just increment pending flush count which will send a trivial
// flush complete event.
@@ -1791,8 +1767,7 @@
err = (err_flush != NO_ERROR) ? err_flush : err;
}
}
-
- return (numSensors == 0) ? INVALID_OPERATION : err;
+ return err;
}
bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 5f1486b..95f5a3f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -470,17 +470,17 @@
}
void SurfaceFlinger::destroyDisplay(const sp<IBinder>& displayToken) {
- Mutex::Autolock _l(mStateLock);
+ Mutex::Autolock lock(mStateLock);
- ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
+ const ssize_t index = mCurrentState.displays.indexOfKey(displayToken);
if (index < 0) {
- ALOGE("destroyDisplay: Invalid display token %p", displayToken.get());
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
return;
}
const DisplayDeviceState& state = mCurrentState.displays.valueAt(index);
- if (!state.isVirtual()) {
- ALOGE("destroyDisplay called for non-virtual display");
+ if (state.physical) {
+ ALOGE("%s: Invalid operation on physical display", __FUNCTION__);
return;
}
mInterceptor->saveDisplayDeletion(state.sequenceId);
@@ -912,20 +912,29 @@
}
int SurfaceFlinger::getActiveConfig(const sp<IBinder>& displayToken) {
- const auto display = getDisplayDevice(displayToken);
- if (!display) {
- ALOGE("getActiveConfig: Invalid display token %p", displayToken.get());
- return BAD_VALUE;
+ int activeConfig;
+ bool isPrimary;
+
+ {
+ Mutex::Autolock lock(mStateLock);
+
+ if (const auto display = getDisplayDeviceLocked(displayToken)) {
+ activeConfig = display->getActiveConfig().value();
+ isPrimary = display->isPrimary();
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ return NAME_NOT_FOUND;
+ }
}
- if (display->isPrimary()) {
+ if (isPrimary) {
std::lock_guard<std::mutex> lock(mActiveConfigLock);
if (mDesiredActiveConfigChanged) {
return mDesiredActiveConfig.configId.value();
}
}
- return display->getActiveConfig().value();
+ return activeConfig;
}
void SurfaceFlinger::setDesiredActiveConfig(const ActiveConfigInfo& info) {
@@ -976,17 +985,16 @@
return BAD_VALUE;
}
- status_t result = NO_ERROR;
+ status_t result = NAME_NOT_FOUND;
postMessageSync(new LambdaMessage([&]() {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set allowed display configs for invalid display token %p",
displayToken.get());
- result = BAD_VALUE;
} else if (display->isVirtual()) {
ALOGW("Attempt to set allowed display configs for virtual display");
- result = BAD_VALUE;
+ result = INVALID_OPERATION;
} else {
HwcConfigIndexType config(mode);
const auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(config);
@@ -1156,7 +1164,7 @@
// Currently we only support this API for a single internal display.
if (getInternalDisplayToken() != displayToken) {
- return BAD_VALUE;
+ return NAME_NOT_FOUND;
}
memcpy(&primaries, &mInternalDisplayPrimaries, sizeof(ui::DisplayPrimaries));
@@ -1164,7 +1172,9 @@
}
ColorMode SurfaceFlinger::getActiveColorMode(const sp<IBinder>& displayToken) {
- if (const auto display = getDisplayDevice(displayToken)) {
+ Mutex::Autolock lock(mStateLock);
+
+ if (const auto display = getDisplayDeviceLocked(displayToken)) {
return display->getCompositionDisplay()->getState().colorMode;
}
return static_cast<ColorMode>(BAD_VALUE);
@@ -1180,7 +1190,7 @@
decodeColorMode(mode).c_str(), mode, displayToken.get());
return;
}
- const auto display = getDisplayDevice(displayToken);
+ const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set active color mode %s (%d) for invalid display token %p",
decodeColorMode(mode).c_str(), mode, displayToken.get());
@@ -1200,16 +1210,14 @@
status_t SurfaceFlinger::getAutoLowLatencyModeSupport(const sp<IBinder>& displayToken,
bool* outSupport) const {
- Mutex::Autolock _l(mStateLock);
-
if (!displayToken) {
- ALOGE("getAutoLowLatencyModeSupport() failed. Missing display token.");
return BAD_VALUE;
}
+
+ Mutex::Autolock lock(mStateLock);
+
const auto displayId = getPhysicalDisplayIdLocked(displayToken);
if (!displayId) {
- ALOGE("getAutoLowLatencyModeSupport() failed. Display id for display token %p not found.",
- displayToken.get());
return NAME_NOT_FOUND;
}
*outSupport = getHwComposer().hasDisplayCapability(*displayId,
@@ -1218,64 +1226,45 @@
}
void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
- postMessageAsync(new LambdaMessage([=] { setAutoLowLatencyModeInternal(displayToken, on); }));
-}
-
-void SurfaceFlinger::setAutoLowLatencyModeInternal(const sp<IBinder>& displayToken, bool on) {
- if (!displayToken) {
- ALOGE("setAutoLowLatencyMode() failed. Missing display token.");
- return;
- }
- const auto displayId = getPhysicalDisplayIdLocked(displayToken);
- if (!displayId) {
- ALOGE("setAutoLowLatencyMode() failed. Display id for display token %p not found.",
- displayToken.get());
- return;
- }
-
- getHwComposer().setAutoLowLatencyMode(*displayId, on);
+ postMessageAsync(new LambdaMessage([=] {
+ if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+ getHwComposer().setAutoLowLatencyMode(*displayId, on);
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ }
+ }));
}
status_t SurfaceFlinger::getGameContentTypeSupport(const sp<IBinder>& displayToken,
bool* outSupport) const {
- Mutex::Autolock _l(mStateLock);
-
if (!displayToken) {
- ALOGE("getGameContentTypeSupport() failed. Missing display token.");
return BAD_VALUE;
}
+
+ Mutex::Autolock lock(mStateLock);
+
const auto displayId = getPhysicalDisplayIdLocked(displayToken);
if (!displayId) {
- ALOGE("getGameContentTypeSupport() failed. Display id for display token %p not found.",
- displayToken.get());
return NAME_NOT_FOUND;
}
- std::vector<HWC2::ContentType> outSupportedContentTypes;
- getHwComposer().getSupportedContentTypes(*displayId, &outSupportedContentTypes);
- *outSupport = std::find(outSupportedContentTypes.begin(), outSupportedContentTypes.end(),
- HWC2::ContentType::Game) != outSupportedContentTypes.end();
+ std::vector<HWC2::ContentType> types;
+ getHwComposer().getSupportedContentTypes(*displayId, &types);
+
+ *outSupport = std::any_of(types.begin(), types.end(),
+ [](auto type) { return type == HWC2::ContentType::Game; });
return NO_ERROR;
}
void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) {
- postMessageAsync(new LambdaMessage([=] { setGameContentTypeInternal(displayToken, on); }));
-}
-
-void SurfaceFlinger::setGameContentTypeInternal(const sp<IBinder>& displayToken, bool on) {
- if (!displayToken) {
- ALOGE("setGameContentType() failed. Missing display token.");
- return;
- }
- const auto displayId = getPhysicalDisplayIdLocked(displayToken);
- if (!displayId) {
- ALOGE("setGameContentType() failed. Display id for display token %p not found.",
- displayToken.get());
- return;
- }
-
- const HWC2::ContentType type = on ? HWC2::ContentType::Game : HWC2::ContentType::None;
- getHwComposer().setContentType(*displayId, type);
+ postMessageAsync(new LambdaMessage([=] {
+ if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+ const auto type = on ? HWC2::ContentType::Game : HWC2::ContentType::None;
+ getHwComposer().setContentType(*displayId, type);
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ }
+ }));
}
status_t SurfaceFlinger::clearAnimationFrameStats() {
@@ -1292,15 +1281,15 @@
status_t SurfaceFlinger::getHdrCapabilities(const sp<IBinder>& displayToken,
HdrCapabilities* outCapabilities) const {
- Mutex::Autolock _l(mStateLock);
+ Mutex::Autolock lock(mStateLock);
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
- ALOGE("getHdrCapabilities: Invalid display token %p", displayToken.get());
- return BAD_VALUE;
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ return NAME_NOT_FOUND;
}
- // At this point the DisplayDeivce should already be set up,
+ // At this point the DisplayDevice should already be set up,
// meaning the luminance information is already queried from
// hardware composer and stored properly.
const HdrCapabilities& capabilities = display->getHdrCapabilities();
@@ -1343,39 +1332,46 @@
if (!outFormat || !outDataspace || !outComponentMask) {
return BAD_VALUE;
}
- const auto display = getDisplayDevice(displayToken);
- if (!display || !display->getId()) {
- ALOGE("getDisplayedContentSamplingAttributes: Bad display token: %p", display.get());
- return BAD_VALUE;
+
+ Mutex::Autolock lock(mStateLock);
+
+ const auto displayId = getPhysicalDisplayIdLocked(displayToken);
+ if (!displayId) {
+ return NAME_NOT_FOUND;
}
- return getHwComposer().getDisplayedContentSamplingAttributes(*display->getId(), outFormat,
+
+ return getHwComposer().getDisplayedContentSamplingAttributes(*displayId, outFormat,
outDataspace, outComponentMask);
}
status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken,
bool enable, uint8_t componentMask,
- uint64_t maxFrames) const {
- const auto display = getDisplayDevice(displayToken);
- if (!display || !display->getId()) {
- ALOGE("setDisplayContentSamplingEnabled: Bad display token: %p", display.get());
- return BAD_VALUE;
- }
+ uint64_t maxFrames) {
+ status_t result = NAME_NOT_FOUND;
- return getHwComposer().setDisplayContentSamplingEnabled(*display->getId(), enable,
- componentMask, maxFrames);
+ postMessageSync(new LambdaMessage([&] {
+ if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+ result = getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable,
+ componentMask, maxFrames);
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ }
+ }));
+
+ return result;
}
status_t SurfaceFlinger::getDisplayedContentSample(const sp<IBinder>& displayToken,
uint64_t maxFrames, uint64_t timestamp,
DisplayedFrameStats* outStats) const {
- const auto display = getDisplayDevice(displayToken);
- if (!display || !display->getId()) {
- ALOGE("getDisplayContentSample: Bad display token: %p", displayToken.get());
- return BAD_VALUE;
+ Mutex::Autolock lock(mStateLock);
+
+ const auto displayId = getPhysicalDisplayIdLocked(displayToken);
+ if (!displayId) {
+ return NAME_NOT_FOUND;
}
- return getHwComposer().getDisplayedContentSample(*display->getId(), maxFrames, timestamp,
- outStats);
+ return getHwComposer().getDisplayedContentSample(*displayId, maxFrames, timestamp, outStats);
}
status_t SurfaceFlinger::getProtectedContentSupport(bool* outSupported) const {
@@ -1391,19 +1387,15 @@
if (!displayToken || !outIsWideColorDisplay) {
return BAD_VALUE;
}
- Mutex::Autolock _l(mStateLock);
+
+ Mutex::Autolock lock(mStateLock);
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
- return BAD_VALUE;
+ return NAME_NOT_FOUND;
}
- // Use hasWideColorDisplay to override built-in display.
- const auto displayId = display->getId();
- if (displayId && displayId == getInternalDisplayIdLocked()) {
- *outIsWideColorDisplay = hasWideColorDisplay;
- return NO_ERROR;
- }
- *outIsWideColorDisplay = display->hasWideColorGamut();
+ *outIsWideColorDisplay =
+ display->isPrimary() ? hasWideColorDisplay : display->hasWideColorGamut();
return NO_ERROR;
}
@@ -1478,6 +1470,9 @@
if (!displayToken || !outSupport) {
return BAD_VALUE;
}
+
+ Mutex::Autolock lock(mStateLock);
+
const auto displayId = getPhysicalDisplayIdLocked(displayToken);
if (!displayId) {
return NAME_NOT_FOUND;
@@ -1487,16 +1482,22 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken,
- float brightness) const {
+status_t SurfaceFlinger::setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) {
if (!displayToken) {
return BAD_VALUE;
}
- const auto displayId = getPhysicalDisplayIdLocked(displayToken);
- if (!displayId) {
- return NAME_NOT_FOUND;
- }
- return getHwComposer().setDisplayBrightness(*displayId, brightness);
+
+ status_t result = NAME_NOT_FOUND;
+
+ postMessageSync(new LambdaMessage([&] {
+ if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+ result = getHwComposer().setDisplayBrightness(*displayId, brightness);
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ }
+ }));
+
+ return result;
}
status_t SurfaceFlinger::notifyPowerHint(int32_t hintId) {
@@ -2248,6 +2249,9 @@
}
});
+ mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]);
+ mTransactionCompletedThread.sendCallbacks();
+
if (displayDevice && displayDevice->isPrimary() &&
displayDevice->getPowerMode() == HWC_POWER_MODE_NORMAL && presentFenceTime->isValid()) {
mScheduler->addPresentFence(presentFenceTime);
@@ -2328,9 +2332,6 @@
}
}
- mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]);
- mTransactionCompletedThread.sendCallbacks();
-
if (mLumaSampling && mRegionSamplingThread) {
mRegionSamplingThread->notifyNewContent();
}
@@ -4242,7 +4243,7 @@
void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
postMessageSync(new LambdaMessage([&]() NO_THREAD_SAFETY_ANALYSIS {
- const auto display = getDisplayDevice(displayToken);
+ const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
displayToken.get());
@@ -5355,10 +5356,10 @@
sp<DisplayDevice> display;
{
- Mutex::Autolock _l(mStateLock);
+ Mutex::Autolock lock(mStateLock);
display = getDisplayDeviceLocked(displayToken);
- if (!display) return BAD_VALUE;
+ if (!display) return NAME_NOT_FOUND;
// set the requested width/height to the logical display viewport size
// by default
@@ -5434,10 +5435,10 @@
uint32_t height;
ui::Transform::RotationFlags captureOrientation;
{
- Mutex::Autolock _l(mStateLock);
+ Mutex::Autolock lock(mStateLock);
display = getDisplayByIdOrLayerStack(displayOrLayerStack);
if (!display) {
- return BAD_VALUE;
+ return NAME_NOT_FOUND;
}
width = uint32_t(display->getViewport().width());
@@ -5572,7 +5573,7 @@
std::unordered_set<sp<Layer>, ISurfaceComposer::SpHash<Layer>> excludeLayers;
Rect displayViewport;
{
- Mutex::Autolock _l(mStateLock);
+ Mutex::Autolock lock(mStateLock);
parent = fromHandle(layerHandleBinder);
if (parent == nullptr || parent->isRemovedFromCurrentState()) {
@@ -5616,9 +5617,9 @@
}
}
- auto display = getDisplayByLayerStack(parent->getLayerStack());
+ const auto display = getDisplayByLayerStack(parent->getLayerStack());
if (!display) {
- return BAD_VALUE;
+ return NAME_NOT_FOUND;
}
displayViewport = display->getViewport();
@@ -6005,17 +6006,16 @@
return BAD_VALUE;
}
- status_t result = NO_ERROR;
+ status_t result = NAME_NOT_FOUND;
postMessageSync(new LambdaMessage([&]() {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
- result = BAD_VALUE;
ALOGE("Attempt to set desired display configs for invalid display token %p",
displayToken.get());
} else if (display->isVirtual()) {
- result = BAD_VALUE;
ALOGW("Attempt to set desired display configs for virtual display");
+ result = INVALID_OPERATION;
} else {
result = setDesiredDisplayConfigSpecsInternal(display,
scheduler::RefreshRateConfigs::
@@ -6054,12 +6054,11 @@
*outMaxRefreshRate = policy.maxRefreshRate;
return NO_ERROR;
} else if (display->isVirtual()) {
- return BAD_VALUE;
+ return INVALID_OPERATION;
} else {
const auto displayId = display->getId();
- if (!displayId) {
- return BAD_VALUE;
- }
+ LOG_FATAL_IF(!displayId);
+
*outDefaultConfig = getHwComposer().getActiveConfigIndex(*displayId);
auto vsyncPeriod = getHwComposer().getActiveConfig(*displayId)->getVsyncPeriod();
*outMinRefreshRate = 1e9f / vsyncPeriod;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ec103b1..f4741d9 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -475,14 +475,13 @@
status_t getCompositionPreference(ui::Dataspace* outDataspace, ui::PixelFormat* outPixelFormat,
ui::Dataspace* outWideColorGamutDataspace,
ui::PixelFormat* outWideColorGamutPixelFormat) const override;
- status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display,
+ status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& displayToken,
ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask) const override;
- status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
- uint8_t componentMask,
- uint64_t maxFrames) const override;
- status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
+ status_t setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken, bool enable,
+ uint8_t componentMask, uint64_t maxFrames) override;
+ status_t getDisplayedContentSample(const sp<IBinder>& displayToken, uint64_t maxFrames,
uint64_t timestamp,
DisplayedFrameStats* outStats) const override;
status_t getProtectedContentSupport(bool* outSupported) const override;
@@ -498,7 +497,7 @@
float* outMaxRefreshRate) override;
status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
bool* outSupport) const override;
- status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) const override;
+ status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) override;
status_t notifyPowerHint(int32_t hintId) override;
status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
float lightPosY, float lightPosZ, float lightRadius) override;
@@ -579,11 +578,6 @@
const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy)
EXCLUDES(mStateLock);
- // called on the main thread in response to setAutoLowLatencyMode()
- void setAutoLowLatencyModeInternal(const sp<IBinder>& displayToken, bool on);
- // called on the main thread in response to setGameContentType()
- void setGameContentTypeInternal(const sp<IBinder>& displayToken, bool on);
-
// Returns whether the transaction actually modified any state
bool handleMessageTransaction();
@@ -738,16 +732,6 @@
// called when starting, or restarting after system_server death
void initializeDisplays();
- sp<const DisplayDevice> getDisplayDevice(const wp<IBinder>& displayToken) const {
- Mutex::Autolock _l(mStateLock);
- return getDisplayDeviceLocked(displayToken);
- }
-
- sp<DisplayDevice> getDisplayDevice(const wp<IBinder>& displayToken) {
- Mutex::Autolock _l(mStateLock);
- return getDisplayDeviceLocked(displayToken);
- }
-
// NOTE: can only be called from the main thread or with mStateLock held
sp<const DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) const {
return const_cast<SurfaceFlinger*>(this)->getDisplayDeviceLocked(displayToken);
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index ea3d744..cd11409 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -1731,7 +1731,8 @@
ui::DisplayPrimaries primaries;
populateDummyDisplayNativePrimaries(primaries);
- EXPECT_EQ(BAD_VALUE, mFlinger.getDisplayNativePrimaries(notInternalDisplayToken, primaries));
+ EXPECT_EQ(NAME_NOT_FOUND,
+ mFlinger.getDisplayNativePrimaries(notInternalDisplayToken, primaries));
// Check primaries argument wasn't modified in case of failure
checkDummyDisplayNativePrimaries(primaries);