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

Commit 9027446c authored by Avichal Rakesh's avatar Avichal Rakesh Committed by Android (Google) Code Review
Browse files

Merge "camera: make exception handling more explicit in camera2 classes" into main

parents 697cba00 ad646cf4
Loading
Loading
Loading
Loading
+16 −70
Original line number Diff line number Diff line
@@ -45,10 +45,10 @@ import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.StreamConfiguration;
import android.hardware.camera2.utils.CameraIdAndSessionConfiguration;
import android.hardware.camera2.utils.ConcurrentCameraIdCombination;
import android.hardware.camera2.utils.ExceptionUtils;
import android.hardware.devicestate.DeviceStateManager;
import android.hardware.display.DisplayManager;
import android.os.Binder;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.HandlerThread;
@@ -643,7 +643,7 @@ public final class CameraManager {
            ServiceSpecificException sse = new ServiceSpecificException(
                    ICameraService.ERROR_DISCONNECTED,
                    "Camera service is currently unavailable");
            throwAsPublicException(sse);
            throw ExceptionUtils.throwAsPublicException(sse);
        }

        return multiResolutionStreamConfigurations;
@@ -736,7 +736,7 @@ public final class CameraManager {

                characteristics = new CameraCharacteristics(info);
            } catch (ServiceSpecificException e) {
                throwAsPublicException(e);
                throw ExceptionUtils.throwAsPublicException(e);
            } catch (RemoteException e) {
                // Camera service died - act as if the camera was disconnected
                throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
@@ -858,11 +858,11 @@ public final class CameraManager {
                            e.errorCode == ICameraService.ERROR_DISCONNECTED ||
                            e.errorCode == ICameraService.ERROR_CAMERA_IN_USE) {
                        // Per API docs, these failures call onError and throw
                        throwAsPublicException(e);
                        throw ExceptionUtils.throwAsPublicException(e);
                    }
                } else {
                    // Unexpected failure - rethrow
                    throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                }
            } catch (RemoteException e) {
                // Camera service died - act as if it's a CAMERA_DISCONNECTED case
@@ -870,7 +870,7 @@ public final class CameraManager {
                    ICameraService.ERROR_DISCONNECTED,
                    "Camera service is currently unavailable");
                deviceImpl.setRemoteFailure(sse);
                throwAsPublicException(sse);
                throw ExceptionUtils.throwAsPublicException(sse);
            }

            // TODO: factor out callback to be non-nested, then move setter to constructor
@@ -1704,56 +1704,6 @@ public final class CameraManager {
        }
    }

    /**
     * Convert ServiceSpecificExceptions and Binder RemoteExceptions from camera binder interfaces
     * into the correct public exceptions.
     *
     * @hide
     */
    public static void throwAsPublicException(Throwable t) throws CameraAccessException {
        if (t instanceof ServiceSpecificException) {
            ServiceSpecificException e = (ServiceSpecificException) t;
            int reason = CameraAccessException.CAMERA_ERROR;
            switch(e.errorCode) {
                case ICameraService.ERROR_DISCONNECTED:
                    reason = CameraAccessException.CAMERA_DISCONNECTED;
                    break;
                case ICameraService.ERROR_DISABLED:
                    reason = CameraAccessException.CAMERA_DISABLED;
                    break;
                case ICameraService.ERROR_CAMERA_IN_USE:
                    reason = CameraAccessException.CAMERA_IN_USE;
                    break;
                case ICameraService.ERROR_MAX_CAMERAS_IN_USE:
                    reason = CameraAccessException.MAX_CAMERAS_IN_USE;
                    break;
                case ICameraService.ERROR_DEPRECATED_HAL:
                    reason = CameraAccessException.CAMERA_DEPRECATED_HAL;
                    break;
                case ICameraService.ERROR_ILLEGAL_ARGUMENT:
                case ICameraService.ERROR_ALREADY_EXISTS:
                    throw new IllegalArgumentException(e.getMessage(), e);
                case ICameraService.ERROR_PERMISSION_DENIED:
                    throw new SecurityException(e.getMessage(), e);
                case ICameraService.ERROR_TIMED_OUT:
                case ICameraService.ERROR_INVALID_OPERATION:
                default:
                    reason = CameraAccessException.CAMERA_ERROR;
            }
            throw new CameraAccessException(reason, e.getMessage(), e);
        } else if (t instanceof DeadObjectException) {
            throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                    "Camera service has died unexpectedly",
                    t);
        } else if (t instanceof RemoteException) {
            throw new UnsupportedOperationException("An unknown RemoteException was thrown" +
                    " which should never happen.", t);
        } else if (t instanceof RuntimeException) {
            RuntimeException e = (RuntimeException) t;
            throw e;
        }
    }

    /**
     * Queries the camera service if a cameraId is a hidden physical camera that belongs to a
     * logical camera device.
@@ -1829,13 +1779,13 @@ public final class CameraManager {
                        internalCamId, externalCamId, cameraInjectionCallback);
                injectionSessionImpl.setRemoteInjectionSession(injectionSession);
            } catch (ServiceSpecificException e) {
                throwAsPublicException(e);
                throw ExceptionUtils.throwAsPublicException(e);
            } catch (RemoteException e) {
                // Camera service died - act as if it's a CAMERA_DISCONNECTED case
                ServiceSpecificException sse = new ServiceSpecificException(
                        ICameraService.ERROR_DISCONNECTED,
                        "Camera service is currently unavailable");
                throwAsPublicException(sse);
                throw ExceptionUtils.throwAsPublicException(sse);
            }
        }
    }
@@ -2124,7 +2074,7 @@ public final class CameraManager {
                    cameraService.remapCameraIds(cameraIdRemapping);
                    mActiveCameraIdRemapping = cameraIdRemapping;
                } catch (ServiceSpecificException e) {
                    throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
                    throw new CameraAccessException(
                            CameraAccessException.CAMERA_DISCONNECTED,
@@ -2148,7 +2098,7 @@ public final class CameraManager {
                try {
                    cameraService.injectSessionParams(cameraId, sessionParams.getNativeMetadata());
                } catch (ServiceSpecificException e) {
                    throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
                    throw new CameraAccessException(
                            CameraAccessException.CAMERA_DISCONNECTED,
@@ -2391,15 +2341,13 @@ public final class CameraManager {
                    return mCameraService.isConcurrentSessionConfigurationSupported(
                            cameraIdsAndConfigs, targetSdkVersion);
                } catch (ServiceSpecificException e) {
                   throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
                  // Camera service died - act as if the camera was disconnected
                  throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                          "Camera service is currently unavailable", e);
                }
            }

            return false;
        }

        public boolean isSessionConfigurationWithParametersSupported(
@@ -2411,15 +2359,13 @@ public final class CameraManager {
                    return mCameraService.isSessionConfigurationWithParametersSupported(
                            cameraId, sessionConfiguration);
                } catch (ServiceSpecificException e) {
                    throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
                    // Camera service died - act as if the camera was disconnected
                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                          "Camera service is currently unavailable", e);
                }
            }

            return false;
        }

      /**
@@ -2462,7 +2408,7 @@ public final class CameraManager {
                try {
                    cameraService.setTorchMode(cameraId, enabled, mTorchClientBinder);
                } catch(ServiceSpecificException e) {
                    throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                            "Camera service is currently unavailable");
@@ -2488,7 +2434,7 @@ public final class CameraManager {
                    cameraService.turnOnTorchWithStrengthLevel(cameraId, torchStrength,
                            mTorchClientBinder);
                } catch(ServiceSpecificException e) {
                    throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                            "Camera service is currently unavailable.");
@@ -2512,7 +2458,7 @@ public final class CameraManager {
                try {
                    torchStrength = cameraService.getTorchStrengthLevel(cameraId);
                } catch(ServiceSpecificException e) {
                    throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                            "Camera service is currently unavailable.");
@@ -2551,7 +2497,7 @@ public final class CameraManager {
                        throw new UnsupportedOperationException(e.getMessage());
                    }

                    throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                            "Camera service is currently unavailable.");
+91 −73
Original line number Diff line number Diff line
@@ -18,14 +18,13 @@ package android.hardware.camera2.impl;

import android.hardware.ICameraService;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.ICameraOfflineSession;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.utils.ExceptionUtils;
import android.hardware.camera2.utils.SubmitInfo;
import android.os.IBinder;
import android.os.RemoteException;
@@ -69,9 +68,10 @@ public class ICameraDeviceUserWrapper {
            throws CameraAccessException  {
        try {
            return mRemoteDevice.submitRequest(request, streaming);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

@@ -79,27 +79,30 @@ public class ICameraDeviceUserWrapper {
            throws CameraAccessException {
        try {
            return mRemoteDevice.submitRequestList(requestList, streaming);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public long cancelRequest(int requestId) throws CameraAccessException {
        try {
            return mRemoteDevice.cancelRequest(requestId);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public void beginConfigure() throws CameraAccessException {
        try {
            mRemoteDevice.beginConfigure();
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

@@ -108,18 +111,20 @@ public class ICameraDeviceUserWrapper {
        try {
            return mRemoteDevice.endConfigure(operatingMode, (sessionParams == null) ?
                    new CameraMetadataNative() : sessionParams, startTimeMs);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public void deleteStream(int streamId) throws CameraAccessException {
        try {
            mRemoteDevice.deleteStream(streamId);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

@@ -127,9 +132,10 @@ public class ICameraDeviceUserWrapper {
            throws CameraAccessException {
        try {
            return mRemoteDevice.createStream(outputConfiguration);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

@@ -137,45 +143,50 @@ public class ICameraDeviceUserWrapper {
            throws CameraAccessException {
        try {
            return mRemoteDevice.createInputStream(width, height, format, isMultiResolution);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public Surface getInputSurface() throws CameraAccessException {
        try {
            return mRemoteDevice.getInputSurface();
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public CameraMetadataNative createDefaultRequest(int templateId) throws CameraAccessException {
        try {
            return mRemoteDevice.createDefaultRequest(templateId);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public CameraMetadataNative getCameraInfo() throws CameraAccessException {
        try {
            return mRemoteDevice.getCameraInfo();
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public void waitUntilIdle() throws CameraAccessException {
        try {
            mRemoteDevice.waitUntilIdle();
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

@@ -191,10 +202,9 @@ public class ICameraDeviceUserWrapper {
                throw new IllegalArgumentException("Invalid session configuration");
            }

            throw e;
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

@@ -213,46 +223,49 @@ public class ICameraDeviceUserWrapper {
                throw new IllegalArgumentException("Invalid session configuration");
            }

            throw e;
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public long flush() throws CameraAccessException {
        try {
            return mRemoteDevice.flush();
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public void prepare(int streamId) throws CameraAccessException {
        try {
            mRemoteDevice.prepare(streamId);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public void tearDown(int streamId) throws CameraAccessException {
        try {
            mRemoteDevice.tearDown(streamId);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public void prepare2(int maxCount, int streamId) throws CameraAccessException {
        try {
            mRemoteDevice.prepare2(maxCount, streamId);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

@@ -260,9 +273,10 @@ public class ICameraDeviceUserWrapper {
            throws CameraAccessException {
        try {
            mRemoteDevice.updateOutputConfiguration(streamId, config);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

@@ -270,9 +284,10 @@ public class ICameraDeviceUserWrapper {
            int[] offlineOutputIds) throws CameraAccessException {
        try {
            return mRemoteDevice.switchToOffline(cbs, offlineOutputIds);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

@@ -280,27 +295,30 @@ public class ICameraDeviceUserWrapper {
            throws CameraAccessException {
        try {
            mRemoteDevice.finalizeOutputConfigurations(streamId, deferredConfig);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public void setCameraAudioRestriction(int mode) throws CameraAccessException {
        try {
            mRemoteDevice.setCameraAudioRestriction(mode);
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

    public int getGlobalAudioRestriction() throws CameraAccessException {
        try {
            return mRemoteDevice.getGlobalAudioRestriction();
        } catch (Throwable t) {
            CameraManager.throwAsPublicException(t);
            throw new UnsupportedOperationException("Unexpected exception", t);
        } catch (ServiceSpecificException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        } catch (RemoteException e) {
            throw ExceptionUtils.throwAsPublicException(e);
        }
    }

+110 −0

File added.

Preview size limit exceeded, changes collapsed.