Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 457e639a authored by Brian Duddie's avatar Brian Duddie
Browse files

Skip checking the app op for step sensors for legacy apps

To maintain backwards compatibility, ensure that apps with target SDK
set to P or lower get access to step count and detect sensors,
regardless of their permission status. After a change was made to the
app ops code in rvc-dev, this check resulted in compatibility breakage
for some apps built with target SDK before Q.

Fixes: 157638722
Test: confirm that a popular step counting app from the Play Store is
      able to receive step count events after the change (where it
      couldn't before)
Change-Id: Idab0ec458221524997f68311f4c6b216c969cb61
parent 109ad715
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ SensorService::SensorEventConnection::SensorEventConnection(
      mCacheSize(0), mMaxCacheSize(0), mTimeOfLastEventDrop(0), mEventsDropped(0),
      mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false) {
    mChannel = new BitTube(mService->mSocketBufferSize);
    mTargetSdk = SensorService::getTargetSdkVersion(opPackageName);
#if DEBUG_CONNECTIONS
    mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
    mTotalAcksNeeded = mTotalAcksReceived = 0;
@@ -439,9 +440,18 @@ bool SensorService::SensorEventConnection::noteOpIfRequired(const sensors_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);
        // Special handling for step count/detect backwards compatibility: if the app's target SDK
        // is pre-Q, still permit delivering events to the app even if permission isn't granted
        // (since this permission was only introduced in Q)
        if ((event.type == SENSOR_TYPE_STEP_COUNTER || event.type == SENSOR_TYPE_STEP_DETECTOR) &&
                mTargetSdk > 0 && mTargetSdk <= __ANDROID_API_P__) {
            success = true;
        } else {
            int32_t appOpMode = mService->sAppOpsManager.noteOp(iter->second, mUid,
                                                                mOpPackageName);
            success = (appOpMode == AppOpsManager::MODE_ALLOWED);
        }
    }
    return success;
}

+1 −0
Original line number Diff line number Diff line
@@ -175,6 +175,7 @@ private:
    int mEventsDropped;
    String8 mPackageName;
    const String16 mOpPackageName;
    int mTargetSdk;
#if DEBUG_CONNECTIONS
    int mEventsReceived, mEventsSent, mEventsSentFromCache;
    int mTotalAcksNeeded, mTotalAcksReceived;
+11 −19
Original line number Diff line number Diff line
@@ -1802,35 +1802,27 @@ bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,
    const int32_t appOpMode = sAppOpsManager.checkOp(opCode,
            IPCThreadState::self()->getCallingUid(), opPackageName);
    bool appOpAllowed = appOpMode == AppOpsManager::MODE_ALLOWED;
    int targetSdkVersion = getTargetSdkVersion(opPackageName);

    bool canAccess = false;
    if (hasPermissionForSensor(sensor)) {
    if (targetSdkVersion > 0 && targetSdkVersion <= __ANDROID_API_P__ &&
            (sensor.getType() == SENSOR_TYPE_STEP_COUNTER ||
             sensor.getType() == SENSOR_TYPE_STEP_DETECTOR)) {
        // Allow access to step sensors 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.
        canAccess = true;
    } else if (hasPermissionForSensor(sensor)) {
        // Ensure that the AppOp is allowed, or that there is no necessary app op for the sensor
        if (opCode < 0 || appOpAllowed) {
            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, and the user hasn't revoked the app op.
        //
        // Verifying the app op is 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.
        if (appOpAllowed &&
                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",
        ALOGE("%s %s a sensor (%s) without holding %s", String8(opPackageName).string(),
              operation, sensor.getName().string(), sensor.getRequiredPermission().string());
    }