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

Commit 230171da authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "step_event_permission" into qt-dev

* changes:
  Call noteOp for sensor events
  Require AR permission to access step events
  Add support for retrieving targetSdkVersion
parents 0bfc4a0c c225aa11
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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);
}
+20 −5
Original line number Diff line number Diff line
@@ -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 {
// ----------------------------------------------------------------------------
@@ -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:
@@ -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;
+13 −2
Original line number Diff line number Diff line
@@ -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];
                    }
                }
@@ -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;
+8 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <stdint.h>
#include <sys/types.h>
#include <unordered_map>

#include <utils/Vector.h>
#include <utils/SortedVector.h>
@@ -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;
@@ -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
+78 −20
Original line number Diff line number Diff line
@@ -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>
@@ -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"
@@ -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);
}
@@ -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);
@@ -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()) {
@@ -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