Loading libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -74,4 +74,11 @@ interface IPackageManagerNative { * LOCATION_PRODUCT: getApplicationInfo(packageName).isProduct() */ int getLocationFlags(in @utf8InCpp String packageName); /** * Returns the target SDK version for the given package. * Unknown packages will cause the call to fail. The caller must check the * returned Status before using the result of this function. */ int getTargetSdkVersionForPackage(in String packageName); } libs/sensor/Sensor.cpp +20 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,13 @@ #include <binder/IPermissionController.h> #include <binder/IServiceManager.h> /* * The permission to use for activity recognition sensors (like step counter). * See sensor types for more details on what sensors should require this * permission. */ #define SENSOR_PERMISSION_ACTIVITY_RECOGNITION "android.permission.ACTIVITY_RECOGNITION" // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- Loading Loading @@ -116,7 +123,7 @@ Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersi mStringType = SENSOR_STRING_TYPE_HEART_RATE; mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS; AppOpsManager appOps; mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS)); mRequiredAppOp = appOps.permissionToOpCode(String16(mRequiredPermission)); mFlags |= SENSOR_FLAG_ON_CHANGE_MODE; } break; case SENSOR_TYPE_LIGHT: Loading Loading @@ -165,14 +172,22 @@ Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersi mFlags |= SENSOR_FLAG_WAKE_UP; } break; case SENSOR_TYPE_STEP_COUNTER: case SENSOR_TYPE_STEP_COUNTER: { mStringType = SENSOR_STRING_TYPE_STEP_COUNTER; mRequiredPermission = SENSOR_PERMISSION_ACTIVITY_RECOGNITION; AppOpsManager appOps; mRequiredAppOp = appOps.permissionToOpCode(String16(mRequiredPermission)); mFlags |= SENSOR_FLAG_ON_CHANGE_MODE; break; case SENSOR_TYPE_STEP_DETECTOR: } break; case SENSOR_TYPE_STEP_DETECTOR: { mStringType = SENSOR_STRING_TYPE_STEP_DETECTOR; mRequiredPermission = SENSOR_PERMISSION_ACTIVITY_RECOGNITION; AppOpsManager appOps; mRequiredAppOp = appOps.permissionToOpCode(String16(mRequiredPermission)); mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE; break; } break; case SENSOR_TYPE_TEMPERATURE: mStringType = SENSOR_STRING_TYPE_TEMPERATURE; mFlags |= SENSOR_FLAG_ON_CHANGE_MODE; Loading services/sensorservice/SensorEventConnection.cpp +13 −2 Original line number Diff line number Diff line Loading @@ -285,8 +285,9 @@ status_t SensorService::SensorEventConnection::sendEvents( scratch[count++] = buffer[i]; } } else { // Regular sensor event, just copy it to the scratch buffer. if (hasSensorAccess()) { // Regular sensor event, just copy it to the scratch buffer after checking // the AppOp. if (hasSensorAccess() && noteOpIfRequired(buffer[i])) { scratch[count++] = buffer[i]; } } Loading Loading @@ -386,6 +387,16 @@ bool SensorService::SensorEventConnection::hasSensorAccess() { return mHasSensorAccess && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled(); } bool SensorService::SensorEventConnection::noteOpIfRequired(const sensors_event_t& event) { bool success = true; const auto iter = mHandleToAppOp.find(event.sensor); if (iter != mHandleToAppOp.end()) { int32_t appOpMode = mService->sAppOpsManager.noteOp((*iter).second, mUid, mOpPackageName); success = (appOpMode == AppOpsManager::MODE_ALLOWED); } return success; } void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch, int count) { sensors_event_t *eventCache_new; Loading services/sensorservice/SensorEventConnection.h +8 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> #include <unordered_map> #include <utils/Vector.h> #include <utils/SortedVector.h> Loading Loading @@ -134,6 +135,9 @@ private: // privacy not being enabled. bool hasSensorAccess(); // 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; Loading Loading @@ -181,6 +185,10 @@ private: mutable Mutex mDestroyLock; bool mDestroyed; 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. std::unordered_map<int32_t, int32_t> mHandleToAppOp; }; } // namepsace android Loading services/sensorservice/SensorService.cpp +78 −20 Original line number Diff line number Diff line Loading @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #include <android/content/pm/IPackageManagerNative.h> #include <binder/ActivityManager.h> #include <binder/AppOpsManager.h> #include <binder/BinderService.h> #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> Loading Loading @@ -75,6 +75,9 @@ namespace android { const char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock"; uint8_t SensorService::sHmacGlobalKey[128] = {}; bool SensorService::sHmacGlobalKeyIsValid = false; std::map<String16, int> SensorService::sPackageTargetVersion; Mutex SensorService::sPackageTargetVersionLock; AppOpsManager SensorService::sAppOpsManager; #define SENSOR_SERVICE_DIR "/data/system/sensor_service" #define SENSOR_SERVICE_HMAC_KEY_FILE SENSOR_SERVICE_DIR "/hmac_key" Loading Loading @@ -1394,6 +1397,14 @@ void SensorService::cleanupConnection(SensorEventConnection* c) { checkWakeLockStateLocked(); } { Mutex::Autolock packageLock(sPackageTargetVersionLock); auto iter = sPackageTargetVersion.find(c->mOpPackageName); if (iter != sPackageTargetVersion.end()) { sPackageTargetVersion.erase(iter); } } SensorDevice& dev(SensorDevice::getInstance()); dev.notifyConnectionDestroyed(c); } Loading Loading @@ -1539,6 +1550,10 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, if (err == NO_ERROR) { connection->updateLooperRegistration(mLooper); if (sensor->getSensor().getRequiredPermission().size() > 0) { connection->mHandleToAppOp[handle] = sensor->getSensor().getRequiredAppOp(); } mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) = SensorRegistrationInfo(handle, connection->getPackageName(), samplingPeriodNs, maxBatchReportLatencyNs, true); Loading Loading @@ -1663,13 +1678,50 @@ status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection, bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, const String16& opPackageName) { const String8& requiredPermission = sensor.getRequiredPermission(); if (requiredPermission.length() <= 0) { // Check if a permission is required for this sensor if (sensor.getRequiredPermission().length() <= 0) { return true; } const int32_t opCode = sensor.getRequiredAppOp(); const int32_t appOpMode = sAppOpsManager.checkOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName); // Ensure that the AppOp is allowed // // This check is also required to ensure that the user hasn't revoked the necessary permissions // to access the Step Detector and Step Counter when the application targets pre-Q. Without this // check, if the user revokes the pre-Q install-time GMS Core AR permission, the app would // still be able to receive Step Counter and Step Detector events. bool canAccess = false; if (opCode >= 0 && appOpMode == AppOpsManager::MODE_ALLOWED) { if (hasPermissionForSensor(sensor)) { canAccess = true; } else if (sensor.getType() == SENSOR_TYPE_STEP_COUNTER || sensor.getType() == SENSOR_TYPE_STEP_DETECTOR) { int targetSdkVersion = getTargetSdkVersion(opPackageName); // Allow access to the sensor if the application targets pre-Q, which is before the // requirement to hold the AR permission to access Step Counter and Step Detector events // was introduced. if (targetSdkVersion > 0 && targetSdkVersion <= __ANDROID_API_P__) { canAccess = true; } } } if (canAccess) { sAppOpsManager.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName); } else { ALOGE("%s a sensor (%s) without holding its required permission: %s", operation, sensor.getName().string(), sensor.getRequiredPermission().string()); } return canAccess; } bool SensorService::hasPermissionForSensor(const Sensor& sensor) { bool hasPermission = false; const String8& requiredPermission = sensor.getRequiredPermission(); // Runtime permissions can't use the cache as they may change. if (sensor.isRequiredPermissionRuntime()) { Loading @@ -1678,25 +1730,31 @@ bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, } else { hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission)); } if (!hasPermission) { ALOGE("%s a sensor (%s) without holding its required permission: %s", operation, sensor.getName().string(), sensor.getRequiredPermission().string()); return false; return hasPermission; } const int32_t opCode = sensor.getRequiredAppOp(); if (opCode >= 0) { AppOpsManager appOps; if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName) != AppOpsManager::MODE_ALLOWED) { ALOGE("%s a sensor (%s) without enabled required app op: %d", operation, sensor.getName().string(), opCode); return false; int SensorService::getTargetSdkVersion(const String16& opPackageName) { Mutex::Autolock packageLock(sPackageTargetVersionLock); int targetSdkVersion = -1; auto entry = sPackageTargetVersion.find(opPackageName); if (entry != sPackageTargetVersion.end()) { targetSdkVersion = entry->second; } else { sp<IBinder> binder = defaultServiceManager()->getService(String16("package_native")); if (binder != nullptr) { sp<content::pm::IPackageManagerNative> packageManager = interface_cast<content::pm::IPackageManagerNative>(binder); if (packageManager != nullptr) { binder::Status status = packageManager->getTargetSdkVersionForPackage( opPackageName, &targetSdkVersion); if (!status.isOk()) { targetSdkVersion = -1; } } return true; } sPackageTargetVersion[opPackageName] = targetSdkVersion; } return targetSdkVersion; } void SensorService::checkWakeLockState() { Loading Loading
libs/binder/aidl/android/content/pm/IPackageManagerNative.aidl +7 −0 Original line number Diff line number Diff line Loading @@ -74,4 +74,11 @@ interface IPackageManagerNative { * LOCATION_PRODUCT: getApplicationInfo(packageName).isProduct() */ int getLocationFlags(in @utf8InCpp String packageName); /** * Returns the target SDK version for the given package. * Unknown packages will cause the call to fail. The caller must check the * returned Status before using the result of this function. */ int getTargetSdkVersionForPackage(in String packageName); }
libs/sensor/Sensor.cpp +20 −5 Original line number Diff line number Diff line Loading @@ -22,6 +22,13 @@ #include <binder/IPermissionController.h> #include <binder/IServiceManager.h> /* * The permission to use for activity recognition sensors (like step counter). * See sensor types for more details on what sensors should require this * permission. */ #define SENSOR_PERMISSION_ACTIVITY_RECOGNITION "android.permission.ACTIVITY_RECOGNITION" // ---------------------------------------------------------------------------- namespace android { // ---------------------------------------------------------------------------- Loading Loading @@ -116,7 +123,7 @@ Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersi mStringType = SENSOR_STRING_TYPE_HEART_RATE; mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS; AppOpsManager appOps; mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS)); mRequiredAppOp = appOps.permissionToOpCode(String16(mRequiredPermission)); mFlags |= SENSOR_FLAG_ON_CHANGE_MODE; } break; case SENSOR_TYPE_LIGHT: Loading Loading @@ -165,14 +172,22 @@ Sensor::Sensor(struct sensor_t const& hwSensor, const uuid_t& uuid, int halVersi mFlags |= SENSOR_FLAG_WAKE_UP; } break; case SENSOR_TYPE_STEP_COUNTER: case SENSOR_TYPE_STEP_COUNTER: { mStringType = SENSOR_STRING_TYPE_STEP_COUNTER; mRequiredPermission = SENSOR_PERMISSION_ACTIVITY_RECOGNITION; AppOpsManager appOps; mRequiredAppOp = appOps.permissionToOpCode(String16(mRequiredPermission)); mFlags |= SENSOR_FLAG_ON_CHANGE_MODE; break; case SENSOR_TYPE_STEP_DETECTOR: } break; case SENSOR_TYPE_STEP_DETECTOR: { mStringType = SENSOR_STRING_TYPE_STEP_DETECTOR; mRequiredPermission = SENSOR_PERMISSION_ACTIVITY_RECOGNITION; AppOpsManager appOps; mRequiredAppOp = appOps.permissionToOpCode(String16(mRequiredPermission)); mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE; break; } break; case SENSOR_TYPE_TEMPERATURE: mStringType = SENSOR_STRING_TYPE_TEMPERATURE; mFlags |= SENSOR_FLAG_ON_CHANGE_MODE; Loading
services/sensorservice/SensorEventConnection.cpp +13 −2 Original line number Diff line number Diff line Loading @@ -285,8 +285,9 @@ status_t SensorService::SensorEventConnection::sendEvents( scratch[count++] = buffer[i]; } } else { // Regular sensor event, just copy it to the scratch buffer. if (hasSensorAccess()) { // Regular sensor event, just copy it to the scratch buffer after checking // the AppOp. if (hasSensorAccess() && noteOpIfRequired(buffer[i])) { scratch[count++] = buffer[i]; } } Loading Loading @@ -386,6 +387,16 @@ bool SensorService::SensorEventConnection::hasSensorAccess() { return mHasSensorAccess && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled(); } bool SensorService::SensorEventConnection::noteOpIfRequired(const sensors_event_t& event) { bool success = true; const auto iter = mHandleToAppOp.find(event.sensor); if (iter != mHandleToAppOp.end()) { int32_t appOpMode = mService->sAppOpsManager.noteOp((*iter).second, mUid, mOpPackageName); success = (appOpMode == AppOpsManager::MODE_ALLOWED); } return success; } void SensorService::SensorEventConnection::reAllocateCacheLocked(sensors_event_t const* scratch, int count) { sensors_event_t *eventCache_new; Loading
services/sensorservice/SensorEventConnection.h +8 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> #include <unordered_map> #include <utils/Vector.h> #include <utils/SortedVector.h> Loading Loading @@ -134,6 +135,9 @@ private: // privacy not being enabled. bool hasSensorAccess(); // 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; Loading Loading @@ -181,6 +185,10 @@ private: mutable Mutex mDestroyLock; bool mDestroyed; 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. std::unordered_map<int32_t, int32_t> mHandleToAppOp; }; } // namepsace android Loading
services/sensorservice/SensorService.cpp +78 −20 Original line number Diff line number Diff line Loading @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ #include <android/content/pm/IPackageManagerNative.h> #include <binder/ActivityManager.h> #include <binder/AppOpsManager.h> #include <binder/BinderService.h> #include <binder/IServiceManager.h> #include <binder/PermissionCache.h> Loading Loading @@ -75,6 +75,9 @@ namespace android { const char* SensorService::WAKE_LOCK_NAME = "SensorService_wakelock"; uint8_t SensorService::sHmacGlobalKey[128] = {}; bool SensorService::sHmacGlobalKeyIsValid = false; std::map<String16, int> SensorService::sPackageTargetVersion; Mutex SensorService::sPackageTargetVersionLock; AppOpsManager SensorService::sAppOpsManager; #define SENSOR_SERVICE_DIR "/data/system/sensor_service" #define SENSOR_SERVICE_HMAC_KEY_FILE SENSOR_SERVICE_DIR "/hmac_key" Loading Loading @@ -1394,6 +1397,14 @@ void SensorService::cleanupConnection(SensorEventConnection* c) { checkWakeLockStateLocked(); } { Mutex::Autolock packageLock(sPackageTargetVersionLock); auto iter = sPackageTargetVersion.find(c->mOpPackageName); if (iter != sPackageTargetVersion.end()) { sPackageTargetVersion.erase(iter); } } SensorDevice& dev(SensorDevice::getInstance()); dev.notifyConnectionDestroyed(c); } Loading Loading @@ -1539,6 +1550,10 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, if (err == NO_ERROR) { connection->updateLooperRegistration(mLooper); if (sensor->getSensor().getRequiredPermission().size() > 0) { connection->mHandleToAppOp[handle] = sensor->getSensor().getRequiredAppOp(); } mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) = SensorRegistrationInfo(handle, connection->getPackageName(), samplingPeriodNs, maxBatchReportLatencyNs, true); Loading Loading @@ -1663,13 +1678,50 @@ status_t SensorService::flushSensor(const sp<SensorEventConnection>& connection, bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, const String16& opPackageName) { const String8& requiredPermission = sensor.getRequiredPermission(); if (requiredPermission.length() <= 0) { // Check if a permission is required for this sensor if (sensor.getRequiredPermission().length() <= 0) { return true; } const int32_t opCode = sensor.getRequiredAppOp(); const int32_t appOpMode = sAppOpsManager.checkOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName); // Ensure that the AppOp is allowed // // This check is also required to ensure that the user hasn't revoked the necessary permissions // to access the Step Detector and Step Counter when the application targets pre-Q. Without this // check, if the user revokes the pre-Q install-time GMS Core AR permission, the app would // still be able to receive Step Counter and Step Detector events. bool canAccess = false; if (opCode >= 0 && appOpMode == AppOpsManager::MODE_ALLOWED) { if (hasPermissionForSensor(sensor)) { canAccess = true; } else if (sensor.getType() == SENSOR_TYPE_STEP_COUNTER || sensor.getType() == SENSOR_TYPE_STEP_DETECTOR) { int targetSdkVersion = getTargetSdkVersion(opPackageName); // Allow access to the sensor if the application targets pre-Q, which is before the // requirement to hold the AR permission to access Step Counter and Step Detector events // was introduced. if (targetSdkVersion > 0 && targetSdkVersion <= __ANDROID_API_P__) { canAccess = true; } } } if (canAccess) { sAppOpsManager.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName); } else { ALOGE("%s a sensor (%s) without holding its required permission: %s", operation, sensor.getName().string(), sensor.getRequiredPermission().string()); } return canAccess; } bool SensorService::hasPermissionForSensor(const Sensor& sensor) { bool hasPermission = false; const String8& requiredPermission = sensor.getRequiredPermission(); // Runtime permissions can't use the cache as they may change. if (sensor.isRequiredPermissionRuntime()) { Loading @@ -1678,25 +1730,31 @@ bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation, } else { hasPermission = PermissionCache::checkCallingPermission(String16(requiredPermission)); } if (!hasPermission) { ALOGE("%s a sensor (%s) without holding its required permission: %s", operation, sensor.getName().string(), sensor.getRequiredPermission().string()); return false; return hasPermission; } const int32_t opCode = sensor.getRequiredAppOp(); if (opCode >= 0) { AppOpsManager appOps; if (appOps.noteOp(opCode, IPCThreadState::self()->getCallingUid(), opPackageName) != AppOpsManager::MODE_ALLOWED) { ALOGE("%s a sensor (%s) without enabled required app op: %d", operation, sensor.getName().string(), opCode); return false; int SensorService::getTargetSdkVersion(const String16& opPackageName) { Mutex::Autolock packageLock(sPackageTargetVersionLock); int targetSdkVersion = -1; auto entry = sPackageTargetVersion.find(opPackageName); if (entry != sPackageTargetVersion.end()) { targetSdkVersion = entry->second; } else { sp<IBinder> binder = defaultServiceManager()->getService(String16("package_native")); if (binder != nullptr) { sp<content::pm::IPackageManagerNative> packageManager = interface_cast<content::pm::IPackageManagerNative>(binder); if (packageManager != nullptr) { binder::Status status = packageManager->getTargetSdkVersionForPackage( opPackageName, &targetSdkVersion); if (!status.isOk()) { targetSdkVersion = -1; } } return true; } sPackageTargetVersion[opPackageName] = targetSdkVersion; } return targetSdkVersion; } void SensorService::checkWakeLockState() { Loading