summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Komsiyski <vladokom@google.com> 2023-12-08 09:02:20 +0100
committer Vladimir Komsiyski <vladokom@google.com> 2023-12-27 10:43:30 +0100
commit71db5f82e6734073549525c9b8428ba03fdd7ac6 (patch)
tree54fa90904767f734ebe0dd31038ebdb5892b2fbd
parenta5643cb05f6d4b5012d443dbdd3077b3fae2bf0c (diff)
Respect deviceId in SensorManager cache.
Do not use the cached SensorManager if the device association of the underlying package has changed. Since the SensorManager is cached per package, if the deviceId changes, then the native SensorManager will always return the wrong sensors. This is seen in the failing CTS. The most straight-forward solution is to refresh the cache when the device for that UID has changed. It would be better to have an API that takes a deviceId but that's a longer term fix - b/306575095 This change is effectively flagged by the read-only flag android.companion.virtual.flags.enable_native_vdm. When it is disabled, the deviceId will always be 0 (i.e. default device). Test: atest VirtualSensorNativeTest Bug: 306575095 Fix: 317495754 Change-Id: If02beb9f3eceec19c104ae03fcb0a8fefb46f85f
-rw-r--r--libs/sensor/SensorManager.cpp70
1 files changed, 36 insertions, 34 deletions
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index f8ee3fc607..b82a79f501 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -88,49 +88,51 @@ SensorManager& SensorManager::getInstanceForPackage(const String16& packageName)
SensorManager* sensorManager;
auto iterator = sPackageInstances.find(packageName);
+ const uid_t uid = IPCThreadState::self()->getCallingUid();
+ const int deviceId = getDeviceIdForUid(uid);
+
+ // Return the cached instance if the device association of the package has not changed.
if (iterator != sPackageInstances.end()) {
sensorManager = iterator->second;
- } else {
- String16 opPackageName = packageName;
- const uid_t uid = IPCThreadState::self()->getCallingUid();
-
- // It is possible that the calling code has no access to the package name.
- // In this case we will get the packages for the calling UID and pick the
- // first one for attributing the app op. This will work correctly for
- // runtime permissions as for legacy apps we will toggle the app op for
- // all packages in the UID. The caveat is that the operation may be attributed
- // to the wrong package and stats based on app ops may be slightly off.
- if (opPackageName.size() <= 0) {
- sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
- if (binder != nullptr) {
- Vector<String16> packages;
- interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages);
- if (!packages.isEmpty()) {
- opPackageName = packages[0];
- } else {
- ALOGE("No packages for calling UID");
- }
+ if (sensorManager->mDeviceId == deviceId) {
+ return *sensorManager;
+ }
+ }
+
+ // It is possible that the calling code has no access to the package name.
+ // In this case we will get the packages for the calling UID and pick the
+ // first one for attributing the app op. This will work correctly for
+ // runtime permissions as for legacy apps we will toggle the app op for
+ // all packages in the UID. The caveat is that the operation may be attributed
+ // to the wrong package and stats based on app ops may be slightly off.
+ String16 opPackageName = packageName;
+ if (opPackageName.size() <= 0) {
+ sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+ if (binder != nullptr) {
+ Vector<String16> packages;
+ interface_cast<IPermissionController>(binder)->getPackagesForUid(uid, packages);
+ if (!packages.isEmpty()) {
+ opPackageName = packages[0];
} else {
- ALOGE("Cannot get permission service");
+ ALOGE("No packages for calling UID");
}
+ } else {
+ ALOGE("Cannot get permission service");
}
+ }
- // Check if the calling UID is observed on a virtual device. If so, provide that device's
- // sensors by default instead of the default device's sensors.
- const int deviceId = getDeviceIdForUid(uid);
- sensorManager = new SensorManager(opPackageName, deviceId);
+ sensorManager = new SensorManager(opPackageName, deviceId);
- // If we had no package name, we looked it up from the UID and the sensor
- // manager instance we created should also be mapped to the empty package
- // name, to avoid looking up the packages for a UID and get the same result.
- if (packageName.size() <= 0) {
- sPackageInstances.insert(std::make_pair(String16(), sensorManager));
- }
-
- // Stash the per package sensor manager.
- sPackageInstances.insert(std::make_pair(opPackageName, sensorManager));
+ // If we had no package name, we looked it up from the UID and the sensor
+ // manager instance we created should also be mapped to the empty package
+ // name, to avoid looking up the packages for a UID and get the same result.
+ if (packageName.size() <= 0) {
+ sPackageInstances.insert(std::make_pair(String16(), sensorManager));
}
+ // Stash the per package sensor manager.
+ sPackageInstances.insert(std::make_pair(opPackageName, sensorManager));
+
return *sensorManager;
}