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

Commit 63f36110 authored by Eino-Ville Talvala's avatar Eino-Ville Talvala
Browse files

Camera service: Support for device state change notifications

Add AIDL method for device-wide physical state updates (such as
folding/unfolding), and wire it up to the new camera provider HAL call.

Also clean up camera provider startup sequence - devices were being enumerated before
the new lazy HAL interface pointers were set up, resulting in many repeated calls
to getService even for a non-lazy HAL.

Also add unit test for CameraProviderManager to verify its section of
the callpath, as well as tests to check that the provider HAL and
hardware service manager aren't queried more than expected during
initialization.

Test: atest cameraservice_test

Change-Id: I5ec60fd9d93b7a2fe4d1a5854fad720a972fe8ea
parent 7de66a0e
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -162,6 +162,28 @@ interface ICameraService
     * Callers require the android.permission.CAMERA_SEND_SYSTEM_EVENTS permission.
     */
    const int EVENT_NONE = 0;
    const int EVENT_USER_SWITCHED = 1;
    const int EVENT_USER_SWITCHED = 1; // The argument is the set of new foreground user IDs.
    oneway void notifySystemEvent(int eventId, in int[] args);

    /**
     * Notify the camera service of a device physical status change. May only be called from
     * a privileged process.
     *
     * newState is a bitfield consisting of DEVICE_STATE_* values combined together. Valid state
     * combinations are device-specific. At device startup, the camera service will assume the device
     * state is NORMAL until otherwise notified.
     *
     * Callers require the android.permission.CAMERA_SEND_SYSTEM_EVENTS permission.
     */
    oneway void notifyDeviceStateChange(long newState);

    // Bitfield constants for notifyDeviceStateChange
    // All bits >= 32 are for custom vendor states
    // Written as ints since AIDL does not support long constants.
    const int DEVICE_STATE_NORMAL = 0;
    const int DEVICE_STATE_BACK_COVERED = 1;
    const int DEVICE_STATE_FRONT_COVERED = 2;
    const int DEVICE_STATE_FOLDED = 4;
    const int DEVICE_STATE_LAST_FRAMEWORK_BIT = 0x80000000; // 1 << 31;

}
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ cc_binary {
        "libhidltransport",
        "android.hardware.camera.common@1.0",
        "android.hardware.camera.provider@2.4",
        "android.hardware.camera.provider@2.5",
        "android.hardware.camera.device@1.0",
        "android.hardware.camera.device@3.2",
        "android.hardware.camera.device@3.4",
+1 −0
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ cc_library_shared {
        "android.frameworks.cameraservice.device@2.0",
        "android.hardware.camera.common@1.0",
        "android.hardware.camera.provider@2.4",
        "android.hardware.camera.provider@2.5",
        "android.hardware.camera.device@1.0",
        "android.hardware.camera.device@3.2",
        "android.hardware.camera.device@3.3",
+43 −0
Original line number Diff line number Diff line
@@ -1632,6 +1632,49 @@ Status CameraService::notifySystemEvent(int32_t eventId,
    return Status::ok();
}

Status CameraService::notifyDeviceStateChange(int64_t newState) {
    const int pid = CameraThreadState::getCallingPid();
    const int selfPid = getpid();

    // Permission checks
    if (pid != selfPid) {
        // Ensure we're being called by system_server, or similar process with
        // permissions to notify the camera service about system events
        if (!checkCallingPermission(
                String16("android.permission.CAMERA_SEND_SYSTEM_EVENTS"))) {
            const int uid = CameraThreadState::getCallingUid();
            ALOGE("Permission Denial: cannot send updates to camera service about device"
                    " state changes from pid=%d, uid=%d", pid, uid);
            return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
                    "No permission to send updates to camera service about device state"
                    " changes from pid=%d, uid=%d", pid, uid);
        }
    }

    ATRACE_CALL();

    using hardware::camera::provider::V2_5::DeviceState;
    hardware::hidl_bitfield<DeviceState> newDeviceState{};
    if (newState & ICameraService::DEVICE_STATE_BACK_COVERED) {
        newDeviceState |= DeviceState::BACK_COVERED;
    }
    if (newState & ICameraService::DEVICE_STATE_FRONT_COVERED) {
        newDeviceState |= DeviceState::FRONT_COVERED;
    }
    if (newState & ICameraService::DEVICE_STATE_FOLDED) {
        newDeviceState |= DeviceState::FOLDED;
    }
    // Only map vendor bits directly
    uint64_t vendorBits = static_cast<uint64_t>(newState) & 0xFFFFFFFF00000000l;
    newDeviceState |= vendorBits;

    ALOGV("%s: New device state 0x%" PRIx64, __FUNCTION__, newDeviceState);
    Mutex::Autolock l(mServiceLock);
    mCameraProviderManager->notifyDeviceStateChange(newDeviceState);

    return Status::ok();
}

Status CameraService::addListener(const sp<ICameraServiceListener>& listener,
        /*out*/
        std::vector<hardware::CameraStatus> *cameraStatuses) {
+2 −0
Original line number Diff line number Diff line
@@ -154,6 +154,8 @@ public:
    virtual binder::Status    notifySystemEvent(int32_t eventId,
            const std::vector<int32_t>& args);

    virtual binder::Status    notifyDeviceStateChange(int64_t newState);

    // OK = supports api of that version, -EOPNOTSUPP = does not support
    virtual binder::Status    supportsCameraApi(
            const String16& cameraId, int32_t apiVersion,
Loading