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

Commit 64e6437d authored by Shuzhen Wang's avatar Shuzhen Wang
Browse files

CameraServiceProxy: Handle race between systemserver and cameraserver

Add retry logic for case where camera proxy in system service needs to
wait for camera server to starts up.

Test: Camera CTS and Forrest test
Bug: 130045093
Change-Id: Ib56e487bbd039dad21bf9e86524cf417f3abcd4c
parent 68c570ec
Loading
Loading
Loading
Loading
+21 −15
Original line number Original line Diff line number Diff line
@@ -50,7 +50,7 @@ import java.util.List;
import java.util.Set;
import java.util.Set;


/**
/**
 * CameraServiceProxy is the system_server analog to the camera service running in mediaserver.
 * CameraServiceProxy is the system_server analog to the camera service running in cameraserver.
 *
 *
 * @hide
 * @hide
 */
 */
@@ -74,6 +74,7 @@ public class CameraServiceProxy extends SystemService
    private static final int MSG_SWITCH_USER = 1;
    private static final int MSG_SWITCH_USER = 1;


    private static final int RETRY_DELAY_TIME = 20; //ms
    private static final int RETRY_DELAY_TIME = 20; //ms
    private static final int RETRY_TIMES = 30;


    // Maximum entries to keep in usage history before dumping out
    // Maximum entries to keep in usage history before dumping out
    private static final int MAX_USAGE_HISTORY = 100;
    private static final int MAX_USAGE_HISTORY = 100;
@@ -171,7 +172,7 @@ public class CameraServiceProxy extends SystemService
                        " camera service UID!");
                        " camera service UID!");
                return;
                return;
            }
            }
            notifySwitchWithRetries(30);
            notifySwitchWithRetries(RETRY_TIMES);
        }
        }


        @Override
        @Override
@@ -242,7 +243,8 @@ public class CameraServiceProxy extends SystemService
    public void onStartUser(int userHandle) {
    public void onStartUser(int userHandle) {
        synchronized(mLock) {
        synchronized(mLock) {
            if (mEnabledCameraUsers == null) {
            if (mEnabledCameraUsers == null) {
                // Initialize mediaserver, or update mediaserver if we are recovering from a crash.
                // Initialize cameraserver, or update cameraserver if we are recovering
                // from a crash.
                switchUserLocked(userHandle);
                switchUserLocked(userHandle);
            }
            }
        }
        }
@@ -324,9 +326,9 @@ public class CameraServiceProxy extends SystemService
        Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
        Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
        mLastUser = userHandle;
        mLastUser = userHandle;
        if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
        if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
            // Some user handles have been added or removed, update mediaserver.
            // Some user handles have been added or removed, update cameraserver.
            mEnabledCameraUsers = currentUserHandles;
            mEnabledCameraUsers = currentUserHandles;
            notifyMediaserverLocked(ICameraService.EVENT_USER_SWITCHED, currentUserHandles);
            notifySwitchWithRetriesLocked(RETRY_TIMES);
        }
        }
    }
    }


@@ -343,13 +345,17 @@ public class CameraServiceProxy extends SystemService


    private void notifySwitchWithRetries(int retries) {
    private void notifySwitchWithRetries(int retries) {
        synchronized(mLock) {
        synchronized(mLock) {
            notifySwitchWithRetriesLocked(retries);
        }
    }

    private void notifySwitchWithRetriesLocked(int retries) {
        if (mEnabledCameraUsers == null) {
        if (mEnabledCameraUsers == null) {
            return;
            return;
        }
        }
            if (notifyMediaserverLocked(ICameraService.EVENT_USER_SWITCHED, mEnabledCameraUsers)) {
        if (notifyCameraserverLocked(ICameraService.EVENT_USER_SWITCHED, mEnabledCameraUsers)) {
            retries = 0;
            retries = 0;
        }
        }
        }
        if (retries <= 0) {
        if (retries <= 0) {
            return;
            return;
        }
        }
@@ -358,13 +364,13 @@ public class CameraServiceProxy extends SystemService
                RETRY_DELAY_TIME);
                RETRY_DELAY_TIME);
    }
    }


    private boolean notifyMediaserverLocked(int eventType, Set<Integer> updatedUserHandles) {
    private boolean notifyCameraserverLocked(int eventType, Set<Integer> updatedUserHandles) {
        // Forward the user switch event to the native camera service running in the mediaserver
        // Forward the user switch event to the native camera service running in the cameraserver
        // process.
        // process.
        if (mCameraServiceRaw == null) {
        if (mCameraServiceRaw == null) {
            IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
            IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
            if (cameraServiceBinder == null) {
            if (cameraServiceBinder == null) {
                Slog.w(TAG, "Could not notify mediaserver, camera service not available.");
                Slog.w(TAG, "Could not notify cameraserver, camera service not available.");
                return false; // Camera service not active, cannot evict user clients.
                return false; // Camera service not active, cannot evict user clients.
            }
            }
            try {
            try {
@@ -380,7 +386,7 @@ public class CameraServiceProxy extends SystemService
        try {
        try {
            mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
            mCameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
        } catch (RemoteException e) {
        } catch (RemoteException e) {
            Slog.w(TAG, "Could not notify mediaserver, remote exception: " + e);
            Slog.w(TAG, "Could not notify cameraserver, remote exception: " + e);
            // Not much we can do if camera service is dead.
            // Not much we can do if camera service is dead.
            return false;
            return false;
        }
        }