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

Commit d9996aa2 authored by Evan Severson's avatar Evan Severson Committed by Android (Google) Code Review
Browse files

Merge "CameraService check sensor privacy if the appop is ignored" into sc-dev

parents ef24fda0 09ab4008
Loading
Loading
Loading
Loading
+61 −77
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@
#include <inttypes.h>
#include <inttypes.h>
#include <pthread.h>
#include <pthread.h>


#include <android/content/pm/IPackageManagerNative.h>
#include <android/hardware/ICamera.h>
#include <android/hardware/ICamera.h>
#include <android/hardware/ICameraClient.h>
#include <android/hardware/ICameraClient.h>


@@ -242,10 +243,6 @@ CameraService::~CameraService() {
    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
    VendorTagDescriptor::clearGlobalVendorTagDescriptor();
    mUidPolicy->unregisterSelf();
    mUidPolicy->unregisterSelf();
    mSensorPrivacyPolicy->unregisterSelf();
    mSensorPrivacyPolicy->unregisterSelf();

    for (auto const& [_, policy] : mCameraSensorPrivacyPolicies) {
        policy->unregisterSelf();
    }
}
}


void CameraService::onNewProviderRegistered() {
void CameraService::onNewProviderRegistered() {
@@ -1711,8 +1708,9 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8&


        // Set camera muting behavior
        // Set camera muting behavior
        if (client->supportsCameraMute()) {
        if (client->supportsCameraMute()) {
            client->setCameraMute(mOverrideCameraMuteMode ||
            bool isCameraPrivacyEnabled =
                    isUserSensorPrivacyEnabledForUid(clientUid));
                    mSensorPrivacyPolicy->isCameraPrivacyEnabled(multiuser_get_user_id(clientUid));
            client->setCameraMute(mOverrideCameraMuteMode || isCameraPrivacyEnabled);
        }
        }


        if (shimUpdateOnly) {
        if (shimUpdateOnly) {
@@ -2945,12 +2943,19 @@ status_t CameraService::BasicClient::startCameraOps() {
        // If the calling Uid is trusted (a native service), the AppOpsManager could
        // If the calling Uid is trusted (a native service), the AppOpsManager could
        // return MODE_IGNORED. Do not treat such case as error.
        // return MODE_IGNORED. Do not treat such case as error.
        if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
        if (!mUidIsTrusted && res == AppOpsManager::MODE_IGNORED) {
            bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid,
                    mClientPackageName);
            bool isCameraPrivacyEnabled =
                    sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled(
                            multiuser_get_user_id(mClientUid));
            if (!isUidActive || !isCameraPrivacyEnabled) {
                ALOGI("Camera %s: Access for \"%s\" has been restricted",
                ALOGI("Camera %s: Access for \"%s\" has been restricted",
                        mCameraIdStr.string(), String8(mClientPackageName).string());
                        mCameraIdStr.string(), String8(mClientPackageName).string());
                // Return the same error as for device policy manager rejection
                // Return the same error as for device policy manager rejection
                return -EACCES;
                return -EACCES;
            }
            }
        }
        }
    }


    mOpsActive = true;
    mOpsActive = true;


@@ -3026,15 +3031,22 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16&) {
        block();
        block();
    } else if (res == AppOpsManager::MODE_IGNORED) {
    } else if (res == AppOpsManager::MODE_IGNORED) {
        bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName);
        bool isUidActive = sCameraService->mUidPolicy->isUidActive(mClientUid, mClientPackageName);
        bool isCameraPrivacyEnabled =
                sCameraService->mSensorPrivacyPolicy->isCameraPrivacyEnabled(
                        multiuser_get_user_id(mClientUid));
        ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d",
        ALOGI("Camera %s: Access for \"%s\" has been restricted, isUidTrusted %d, isUidActive %d",
                mCameraIdStr.string(), String8(mClientPackageName).string(),
                mCameraIdStr.string(), String8(mClientPackageName).string(),
                mUidIsTrusted, isUidActive);
                mUidIsTrusted, isUidActive);
        // If the calling Uid is trusted (a native service), or the client Uid is active (WAR for
        // If the calling Uid is trusted (a native service), or the client Uid is active (WAR for
        // b/175320666), the AppOpsManager could return MODE_IGNORED. Do not treat such cases as
        // b/175320666), the AppOpsManager could return MODE_IGNORED. Do not treat such cases as
        // error.
        // error.
        if (!mUidIsTrusted && !isUidActive) {
        if (!mUidIsTrusted && isUidActive && isCameraPrivacyEnabled) {
            setCameraMute(true);
        } else if (!mUidIsTrusted && !isUidActive) {
            block();
            block();
        }
        }
    } else if (res == AppOpsManager::MODE_ALLOWED) {
        setCameraMute(sCameraService->mOverrideCameraMuteMode);
    }
    }
}
}


@@ -3307,6 +3319,7 @@ void CameraService::SensorPrivacyPolicy::registerSelf() {
    if (mRegistered) {
    if (mRegistered) {
        return;
        return;
    }
    }
    hasCameraPrivacyFeature(); // Called so the result is cached
    mSpm.addSensorPrivacyListener(this);
    mSpm.addSensorPrivacyListener(this);
    mSensorPrivacyEnabled = mSpm.isSensorPrivacyEnabled();
    mSensorPrivacyEnabled = mSpm.isSensorPrivacyEnabled();
    status_t res = mSpm.linkToDeath(this);
    status_t res = mSpm.linkToDeath(this);
@@ -3316,39 +3329,6 @@ void CameraService::SensorPrivacyPolicy::registerSelf() {
    }
    }
}
}


status_t CameraService::SensorPrivacyPolicy::registerSelfForIndividual(int userId) {
    Mutex::Autolock _l(mSensorPrivacyLock);
    if (mRegistered) {
        return OK;
    }

    status_t res = mSpm.addIndividualSensorPrivacyListener(userId,
            SensorPrivacyManager::INDIVIDUAL_SENSOR_CAMERA, this);
    if (res != OK) {
        ALOGE("Unable to register camera privacy listener: %s (%d)", strerror(-res), res);
        return res;
    }

    res = mSpm.isIndividualSensorPrivacyEnabled(userId,
        SensorPrivacyManager::INDIVIDUAL_SENSOR_CAMERA, mSensorPrivacyEnabled);
    if (res != OK) {
        ALOGE("Unable to check camera privacy: %s (%d)", strerror(-res), res);
        return res;
    }

    res = mSpm.linkToDeath(this);
    if (res != OK) {
        ALOGE("Register link to death failed for sensor privacy: %s (%d)", strerror(-res), res);
        return res;
    }

    mRegistered = true;
    mIsIndividual = true;
    mUserId = userId;
    ALOGV("SensorPrivacyPolicy: Registered with SensorPrivacyManager");
    return OK;
}

void CameraService::SensorPrivacyPolicy::unregisterSelf() {
void CameraService::SensorPrivacyPolicy::unregisterSelf() {
    Mutex::Autolock _l(mSensorPrivacyLock);
    Mutex::Autolock _l(mSensorPrivacyLock);
    mSpm.removeSensorPrivacyListener(this);
    mSpm.removeSensorPrivacyListener(this);
@@ -3362,22 +3342,26 @@ bool CameraService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
    return mSensorPrivacyEnabled;
    return mSensorPrivacyEnabled;
}
}


bool CameraService::SensorPrivacyPolicy::isCameraPrivacyEnabled(userid_t userId) {
    if (!hasCameraPrivacyFeature()) {
        return false;
    }
    return mSpm.isIndividualSensorPrivacyEnabled(userId,
        SensorPrivacyManager::INDIVIDUAL_SENSOR_CAMERA);
}

binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
binder::Status CameraService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
    {
    {
        Mutex::Autolock _l(mSensorPrivacyLock);
        Mutex::Autolock _l(mSensorPrivacyLock);
        mSensorPrivacyEnabled = enabled;
        mSensorPrivacyEnabled = enabled;
    }
    }
    // if sensor privacy is enabled then block all clients from accessing the camera
    // if sensor privacy is enabled then block all clients from accessing the camera
    if (enabled) {
        sp<CameraService> service = mService.promote();
        sp<CameraService> service = mService.promote();
        if (service != nullptr) {
        if (service != nullptr) {
        if (mIsIndividual) {
            service->setMuteForAllClients(mUserId, enabled);
        } else {
            if (enabled) {
            service->blockAllClients();
            service->blockAllClients();
        }
        }
    }
    }
    }
    return binder::Status::ok();
    return binder::Status::ok();
}
}


@@ -3387,6 +3371,31 @@ void CameraService::SensorPrivacyPolicy::binderDied(const wp<IBinder>& /*who*/)
    mRegistered = false;
    mRegistered = false;
}
}


bool CameraService::SensorPrivacyPolicy::hasCameraPrivacyFeature() {
    if (!mNeedToCheckCameraPrivacyFeature) {
        return mHasCameraPrivacyFeature;
    }
    bool hasCameraPrivacyFeature = false;
    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->hasSystemFeature(
                    String16("android.hardware.camera.toggle"), 0, &hasCameraPrivacyFeature);

            if (status.isOk()) {
                mNeedToCheckCameraPrivacyFeature = false;
                mHasCameraPrivacyFeature = hasCameraPrivacyFeature;
            } else {
                ALOGE("Unable to check if camera privacy feature is supported");
            }
        }
    }

    return hasCameraPrivacyFeature;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
//                  CameraState
//                  CameraState
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -4006,19 +4015,6 @@ void CameraService::blockAllClients() {
    }
    }
}
}


void CameraService::setMuteForAllClients(userid_t userId, bool enabled) {
    const auto clients = mActiveClientManager.getAll();
    for (auto& current : clients) {
        if (current != nullptr) {
            const auto basicClient = current->getValue();
            if (basicClient.get() != nullptr
                    && multiuser_get_user_id(basicClient->getClientUid()) == userId) {
                basicClient->setCameraMute(enabled);
            }
        }
    }
}

// NOTE: This is a remote API - make sure all args are validated
// NOTE: This is a remote API - make sure all args are validated
status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
status_t CameraService::shellCommand(int in, int out, int err, const Vector<String16>& args) {
    if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {
    if (!checkCallingPermission(sManageCameraPermission, nullptr, nullptr)) {
@@ -4225,16 +4221,4 @@ int32_t CameraService::updateAudioRestrictionLocked() {
    return mode;
    return mode;
}
}


bool CameraService::isUserSensorPrivacyEnabledForUid(uid_t uid) {
    userid_t userId = multiuser_get_user_id(uid);
    if (mCameraSensorPrivacyPolicies.find(userId) == mCameraSensorPrivacyPolicies.end()) {
        sp<SensorPrivacyPolicy> userPolicy = new SensorPrivacyPolicy(this);
        if (userPolicy->registerSelfForIndividual(userId) != OK) {
            return false;
        }
        mCameraSensorPrivacyPolicies[userId] = userPolicy;
    }
    return mCameraSensorPrivacyPolicies[userId]->isSensorPrivacyEnabled();
}

}; // namespace android
}; // namespace android
+6 −13
Original line number Original line Diff line number Diff line
@@ -650,13 +650,13 @@ private:
        public:
        public:
            explicit SensorPrivacyPolicy(wp<CameraService> service)
            explicit SensorPrivacyPolicy(wp<CameraService> service)
                    : mService(service), mSensorPrivacyEnabled(false), mRegistered(false),
                    : mService(service), mSensorPrivacyEnabled(false), mRegistered(false),
                      mIsIndividual(false), mUserId(0) {}
                    mHasCameraPrivacyFeature(false), mNeedToCheckCameraPrivacyFeature(true) {}


            void registerSelf();
            void registerSelf();
            status_t registerSelfForIndividual(int userId);
            void unregisterSelf();
            void unregisterSelf();


            bool isSensorPrivacyEnabled();
            bool isSensorPrivacyEnabled();
            bool isCameraPrivacyEnabled(userid_t userId);


            binder::Status onSensorPrivacyChanged(bool enabled);
            binder::Status onSensorPrivacyChanged(bool enabled);


@@ -669,8 +669,10 @@ private:
            Mutex mSensorPrivacyLock;
            Mutex mSensorPrivacyLock;
            bool mSensorPrivacyEnabled;
            bool mSensorPrivacyEnabled;
            bool mRegistered;
            bool mRegistered;
            bool mIsIndividual;
            bool mHasCameraPrivacyFeature;
            userid_t mUserId;
            bool mNeedToCheckCameraPrivacyFeature;

            bool hasCameraPrivacyFeature();
    };
    };


    sp<UidPolicy> mUidPolicy;
    sp<UidPolicy> mUidPolicy;
@@ -1046,9 +1048,6 @@ private:
    // Blocks all active clients.
    // Blocks all active clients.
    void blockAllClients();
    void blockAllClients();


    // Mutes all active clients for a user.
    void setMuteForAllClients(userid_t userId, bool enabled);

    // Overrides the UID state as if it is idle
    // Overrides the UID state as if it is idle
    status_t handleSetUidState(const Vector<String16>& args, int err);
    status_t handleSetUidState(const Vector<String16>& args, int err);


@@ -1121,12 +1120,6 @@ private:


    // Current camera mute mode
    // Current camera mute mode
    bool mOverrideCameraMuteMode = false;
    bool mOverrideCameraMuteMode = false;

    // Map from user to sensor privacy policy
    std::map<userid_t, sp<SensorPrivacyPolicy>> mCameraSensorPrivacyPolicies;

    // Checks if the sensor privacy is enabled for the uid
    bool isUserSensorPrivacyEnabledForUid(uid_t uid);
};
};


} // namespace android
} // namespace android