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

Commit 60679f6b authored by Igor Murashkin's avatar Igor Murashkin Committed by Android (Google) Code Review
Browse files

Merge "camera: Get detailed error reporting from api1 Camera if open fails"

parents b127713b a1d66271
Loading
Loading
Loading
Loading
+42 −42
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ public class Camera {
    private boolean mOneShot;
    private boolean mWithBuffer;
    private boolean mFaceDetectionRunning = false;
    private Object mAutoFocusCallbackLock = new Object();
    private final Object mAutoFocusCallbackLock = new Object();

    private static final int NO_ERROR = 0;
    private static final int EACCESS = -13;
@@ -202,14 +202,14 @@ public class Camera {

    /**
     * A constant meaning the normal camera connect/open will be used.
     * @hide
     */
    public static final int CAMERA_HAL_API_VERSION_NORMAL_OPEN = -2;
    private static final int CAMERA_HAL_API_VERSION_NORMAL_CONNECT = -2;

    /**
     * Used to indicate HAL version un-specified.
     */
    private static final int CAMERA_HAL_API_VERSION_UNSPECIFIED = -1;

    /**
     * Hardware face detection. It does not use much CPU.
     */
@@ -376,18 +376,25 @@ public class Camera {
     *
     * @param cameraId The hardware camera to access, between 0 and
     * {@link #getNumberOfCameras()}-1.
     * @param halVersion The HAL API version this camera device to be opened as. When
     * it is {@value #CAMERA_HAL_API_VERSION_NORMAL_OPEN}, the methods will be equivalent
     * to {@link #open}, but more detailed error information will be returned to managed code.
     * @param halVersion The HAL API version this camera device to be opened as.
     * @return a new Camera object, connected, locked and ready for use.
     *
     * @throws IllegalArgumentException if the {@code halVersion} is invalid
     *
     * @throws RuntimeException if opening the camera fails (for example, if the
     * camera is in use by another process or device policy manager has disabled
     * the camera).
     *
     * @see android.app.admin.DevicePolicyManager#getCameraDisabled(android.content.ComponentName)
     * @see #CAMERA_HAL_API_VERSION_1_0
     *
     * @hide
     */
    public static Camera openLegacy(int cameraId, int halVersion) {
        if (halVersion < CAMERA_HAL_API_VERSION_1_0) {
            throw new IllegalArgumentException("Invalid HAL version " + halVersion);
        }

        return new Camera(cameraId, halVersion);
    }

@@ -399,7 +406,7 @@ public class Camera {
     * @param halVersion The HAL API version this camera device to be opened as.
     */
    private Camera(int cameraId, int halVersion) {
        int err = cameraInit(cameraId, halVersion);
        int err = cameraInitVersion(cameraId, halVersion);
        if (checkInitErrors(err)) {
            switch(err) {
                case EACCESS:
@@ -428,13 +435,7 @@ public class Camera {
        }
    }

    private int cameraInit(int cameraId, int halVersion) {
        // This function should be only called by Camera(int cameraId, int halVersion).
        if (halVersion < CAMERA_HAL_API_VERSION_1_0 &&
                halVersion != CAMERA_HAL_API_VERSION_NORMAL_OPEN) {
            throw new IllegalArgumentException("Invalid HAL version " + halVersion);
        }

    private int cameraInitVersion(int cameraId, int halVersion) {
        mShutterCallback = null;
        mRawImageCallback = null;
        mJpegCallback = null;
@@ -457,8 +458,31 @@ public class Camera {
        return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);
    }

    private int cameraInitNormal(int cameraId) {
        return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
    }

    /**
     * Connect to the camera service using #connectLegacy
     *
     * <p>
     * This acts the same as normal except that it will return
     * the detailed error code if open fails instead of
     * converting everything into {@code NO_INIT}.</p>
     *
     * <p>Intended to use by the camera2 shim only, do <i>not</i> use this for other code.</p>
     *
     * @return a detailed errno error code, or {@code NO_ERROR} on success
     *
     * @hide
     */
    public int cameraInitUnspecified(int cameraId) {
        return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_UNSPECIFIED);
    }

    /** used by Camera#open, Camera#open(int) */
    Camera(int cameraId) {
        int err = cameraInit(cameraId);
        int err = cameraInitNormal(cameraId);
        if (checkInitErrors(err)) {
            switch(err) {
                case EACCESS:
@@ -472,32 +496,6 @@ public class Camera {
        }
    }

    /**
     * @hide
     */
    public int cameraInit(int cameraId) {
        mShutterCallback = null;
        mRawImageCallback = null;
        mJpegCallback = null;
        mPreviewCallback = null;
        mPostviewCallback = null;
        mUsingPreviewAllocation = false;
        mZoomListener = null;

        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
        }

        String packageName = ActivityThread.currentPackageName();

        return native_setup(new WeakReference<Camera>(this), cameraId,
                CAMERA_HAL_API_VERSION_UNSPECIFIED, packageName);
    }

    /**
     * @hide
@@ -519,6 +517,7 @@ public class Camera {
    Camera() {
    }

    @Override
    protected void finalize() {
        release();
    }
@@ -1056,7 +1055,7 @@ public class Camera {

    private class EventHandler extends Handler
    {
        private Camera mCamera;
        private final Camera mCamera;

        public EventHandler(Camera c, Looper looper) {
            super(looper);
@@ -2337,6 +2336,7 @@ public class Camera {
         * @hide
         * @deprecated
         */
        @Deprecated
        public void dump() {
            Log.e(TAG, "dump: size=" + mMap.size());
            for (String k : mMap.keySet()) {
+10 −5
Original line number Diff line number Diff line
@@ -278,14 +278,19 @@ public final class CameraManager {
                ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
                int id = Integer.parseInt(cameraId);
                try {
                    if (supportsCamera2Api(cameraId)) {
                        // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
                        mCameraService.connectDevice(callbacks, id, mContext.getPackageName(),
                                USE_CALLING_UID, holder);
                        cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());
                } catch (CameraRuntimeException e) {
                    if (e.getReason() == CameraAccessException.CAMERA_DEPRECATED_HAL) {
                    } else {
                        // Use legacy camera implementation for HAL1 devices
                        Log.i(TAG, "Using legacy camera HAL.");
                        cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);
                    }
                } catch (CameraRuntimeException e) {
                    if (e.getReason() == CameraAccessException.CAMERA_DEPRECATED_HAL) {
                        throw new AssertionError("Should've gone down the shim path");
                    } else if (e.getReason() == CameraAccessException.CAMERA_IN_USE ||
                            e.getReason() == CameraAccessException.MAX_CAMERAS_IN_USE ||
                            e.getReason() == CameraAccessException.CAMERA_DISABLED ||
+4 −6
Original line number Diff line number Diff line
@@ -76,13 +76,11 @@ public class CameraDeviceUserShim implements ICameraDeviceUser {
        }
        // TODO: Move open/init into LegacyCameraDevice thread when API is switched to async.
        Camera legacyCamera = Camera.openUninitialized();
        int initErrors = legacyCamera.cameraInit(cameraId);
        int initErrors = legacyCamera.cameraInitUnspecified(cameraId);

        // Check errors old HAL initialization
        if (Camera.checkInitErrors(initErrors)) {
            // TODO: Map over old camera error codes.  This likely involves improving the error
            // reporting in the HAL1 connect path.
            throw new CameraRuntimeException(CameraAccessException.CAMERA_DISCONNECTED);
        }
        CameraBinderDecorator.throwOnError(initErrors);

        LegacyCameraDevice device = new LegacyCameraDevice(cameraId, legacyCamera, callbacks);
        return new CameraDeviceUserShim(cameraId, device);
    }
+7 −2
Original line number Diff line number Diff line
@@ -36,6 +36,11 @@

using namespace android;

enum {
    // Keep up to date with Camera.java
    CAMERA_HAL_API_VERSION_NORMAL_CONNECT = -2,
};

struct fields_t {
    jfieldID    context;
    jfieldID    facing;
@@ -475,8 +480,8 @@ static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
    env->ReleaseStringChars(clientPackageName, rawClientName);

    sp<Camera> camera;
    if (halVersion == ICameraService::CAMERA_HAL_API_VERSION_UNSPECIFIED) {
        // Default path: hal version is unspecified, do normal camera open.
    if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) {
        // Default path: hal version is don't care, do normal camera connect.
        camera = Camera::connect(cameraId, clientName,
                Camera::USE_CALLING_UID);
    } else {