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

Commit 66ef6451 authored by Ruben Brunk's avatar Ruben Brunk
Browse files

Refactor CameraService to handle errors properly.

Bug: 10361136

- Connect calls now return status_t error flags.

Change-Id: Ibce9ab047348cfcade7e70a2ef03f5a833e13af8
parent 6f2883c9
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.hardware.IProCameraUser;
import android.hardware.IProCameraCallbacks;
import android.hardware.camera2.ICameraDeviceUser;
import android.hardware.camera2.ICameraDeviceCallbacks;
import android.hardware.camera2.utils.BinderHolder;
import android.hardware.ICameraServiceListener;
import android.hardware.CameraInfo;

@@ -37,17 +38,23 @@ interface ICameraService

    int getCameraInfo(int cameraId, out CameraInfo info);

    ICamera connect(ICameraClient client, int cameraId,
    int connect(ICameraClient client, int cameraId,
                    String clientPackageName,
                    int clientUid);
                    int clientUid,
                    // Container for an ICamera object
                    out BinderHolder device);

    IProCameraUser connectPro(IProCameraCallbacks callbacks, int cameraId,
    int connectPro(IProCameraCallbacks callbacks, int cameraId,
                              String clientPackageName,
                              int clientUid);
                              int clientUid,
                              // Container for an IProCameraUser object
                              out BinderHolder device);

    ICameraDeviceUser connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,
    int connectDevice(ICameraDeviceCallbacks callbacks, int cameraId,
                              String clientPackageName,
                              int clientUid);
                              int clientUid,
                              // Container for an ICameraDeviceUser object
                              out BinderHolder device);

    int addListener(ICameraServiceListener listener);
    int removeListener(ICameraServiceListener listener);
+8 −1
Original line number Diff line number Diff line
@@ -48,11 +48,18 @@ public class CameraAccessException extends AndroidException {

    /**
     * The camera device is removable and has been disconnected from the Android
     * device, or the camera service has shut down the connection due to a
     * device, or the camera id used with {@link android.hardware.camera2.CameraManager#openCamera}
     * is no longer valid, or the camera service has shut down the connection due to a
     * higher-priority access request for the camera device.
     */
    public static final int CAMERA_DISCONNECTED = 4;

    /**
     * A deprecated HAL version is in use.
     * @hide
     */
    public static final int CAMERA_DEPRECATED_HAL = 1000;

    // Make the eclipse warning about serializable exceptions go away
    private static final long serialVersionUID = 5630338637471475675L; // randomly generated

+9 −18
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.hardware.ICameraServiceListener;
import android.hardware.IProCameraUser;
import android.hardware.camera2.utils.CameraBinderDecorator;
import android.hardware.camera2.utils.CameraRuntimeException;
import android.hardware.camera2.utils.BinderHolder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -171,10 +172,10 @@ public final class CameraManager {
     *
     * @param cameraId The unique identifier of the camera device to open
     *
     * @throws IllegalArgumentException if the cameraId does not match any
     * currently connected camera device.
     * @throws CameraAccessException if the camera is disabled by device policy,
     * or too many camera devices are already open.
     * or too many camera devices are already open, or the cameraId does not match
     * any currently available camera device.
     *
     * @throws SecurityException if the application does not have permission to
     * access the camera
     *
@@ -192,16 +193,11 @@ public final class CameraManager {
                android.hardware.camera2.impl.CameraDevice device =
                        new android.hardware.camera2.impl.CameraDevice(cameraId);

                cameraUser = mCameraService.connectDevice(device.getCallbacks(),
                BinderHolder holder = new BinderHolder();
                mCameraService.connectDevice(device.getCallbacks(),
                        Integer.parseInt(cameraId),
                        mContext.getPackageName(), USE_CALLING_UID);

                // TODO: change ICameraService#connectDevice to return status_t
                if (cameraUser == null) {
                    // TEMPORARY CODE.
                    // catch-all exception since we aren't yet getting the actual error code
                    throw new IllegalStateException("Failed to open camera device");
                }
                        mContext.getPackageName(), USE_CALLING_UID, holder);
                cameraUser = ICameraDeviceUser.Stub.asInterface(holder.getBinder());

                // TODO: factor out listener to be non-nested, then move setter to constructor
                device.setRemoteDevice(cameraUser);
@@ -214,12 +210,7 @@ public final class CameraManager {
            throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
                    + cameraId);
        } catch (CameraRuntimeException e) {
            if (e.getReason() == CameraAccessException.CAMERA_DISCONNECTED) {
                throw new IllegalArgumentException("Invalid camera ID specified -- " +
                        "perhaps the camera was physically disconnected", e);
            } else {
            throw e.asChecked();
            }
        } catch (RemoteException e) {
            // impossible
            return null;
+20 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.camera2.utils;

/** @hide */
parcelable BinderHolder;
+74 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.hardware.camera2.utils;

import android.os.Parcel;
import android.os.Parcelable;
import android.os.IBinder;

/**
 * @hide
 */
public class BinderHolder implements Parcelable {
    private IBinder mBinder = null;

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStrongBinder(mBinder);
    }

    public void readFromParcel(Parcel src) {
        mBinder = src.readStrongBinder();
    }

    public static final Parcelable.Creator<BinderHolder> CREATOR =
             new Parcelable.Creator<BinderHolder>() {
         @Override
         public BinderHolder createFromParcel(Parcel in) {
             return new BinderHolder(in);
         }

         @Override
         public BinderHolder[] newArray(int size) {
             return new BinderHolder[size];
         }
    };

    public IBinder getBinder() {
        return mBinder;
    }

    public void setBinder(IBinder binder) {
        mBinder = binder;
    }

    public BinderHolder() {}

    public BinderHolder(IBinder binder) {
        mBinder = binder;
    }

    private BinderHolder(Parcel in) {
        mBinder = in.readStrongBinder();
    }
}
Loading