Camera framework/HAL(一)

目录

一、framework

1、开启camera:

1.1、openCameraDeviceUserAsync:

1.1.1、openCameraDeviceUserAsync

目录

一、framework

1、开启camera:

1.1、openCameraDeviceUserAsync

获取cameraService

1.1.1、openCameraDeviceUserAsync:

1.1.2、getCameraCharacteristics:

1.1.3、CameraDeviceImpl

1.1.4、获取CameraService



一、framework

base/core/java/android/hardware/camera2/CameraManager.java

调用opencamera,根据传入的参数执行不同的接口,检查是否开启camera功能。

openCamera->openCameraForUid()->openCameraDeviceUserAsync()->connectHelper()->makeClient()->CameraDeviceClient()->Camera2ClientBase()->
                                                                            ->initialize()->initializeImpl()->

那么这就是打开camera个过程,其实是获取CameraDeviceImpl到应用。
重要的包含结构
CameraDeviceImpl
ICameraDeviceUserWrapper
ICameraDeviceUser(通过cameraService.connectDevice获取,framework和service交互)
对应CameraDeviceClient(framework和service交互,就是创建client)
Camera2ClientBase
Camera3Device

CameraDeviceClient属于camerasever,所以可以调用CameraProviderManager 里面的deviceInfo3-> mInterface(privder里面的CameraDevice)CameraDevice通过CameraModule(包含加载的hal模块句柄)可以访问hal

1、开启camera:

1.1、openCameraDeviceUserAsync

        根据传入的cameraid获取对应的配置属性,并将其保存,注册camera状态的回调函数,最后打开camera,并返回device。

->getCameraCharacteristics()//

->android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =

        new android.hardware.camera2.impl.CameraDeviceImpl();//保存此次传入的camera的相         机id以及相关属性。

->ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();//获取一个               CameraDeviceCallbacks

->ICameraService cameraService = CameraManagerGlobal.get().getCameraService();//获取             CameraService

->cameraUser = cameraService.connectDevice(callbacks, cameraId,

        mContext.getOpPackageName(), mContext.getAttributionTag(), uid);//根据cameraid来打          开camera

->deviceImpl.setRemoteDevice(cameraUser);//设置远程设备,触发Onopened/OnConfigured

->return device;//返回一个CameraDevice

获取cameraService

1.1.1、openCameraDeviceUserAsync:

    private CameraDevice openCameraDeviceUserAsync(String cameraId,
            CameraDevice.StateCallback callback, Executor executor, final int uid)
            throws CameraAccessException {
        CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
        CameraDevice device = null;

        synchronized (mLock) {

            ICameraDeviceUser cameraUser = null;

            android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
                    new android.hardware.camera2.impl.CameraDeviceImpl(
                        cameraId,
                        callback,
                        executor,
                        characteristics,
                        mContext.getApplicationInfo().targetSdkVersion);

            ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();

            try {
                if (supportsCamera2ApiLocked(cameraId)) {
                    // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
                    ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
                    if (cameraService == null) {
                        throw new ServiceSpecificException(
                            ICameraService.ERROR_DISCONNECTED,
                            "Camera service is currently unavailable");
                    }
                    cameraUser = cameraService.connectDevice(callbacks, cameraId,
                            mContext.getOpPackageName(), mContext.getAttributionTag(), uid);
                } else {
                    // Use legacy camera implementation for HAL1 devices
                    int id;
                    try {
                        id = Integer.parseInt(cameraId);
                    } catch (NumberFormatException e) {
                        throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
                                + cameraId);
                    }

                    Log.i(TAG, "Using legacy camera HAL.");
                    cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id,
                            getDisplaySize());
                }
            } catch (ServiceSpecificException e) {
                if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {
                    throw new AssertionError("Should've gone down the shim path");
                } else if (e.errorCode == ICameraService.ERROR_CAMERA_IN_USE ||
                        e.errorCode == ICameraService.ERROR_MAX_CAMERAS_IN_USE ||
                        e.errorCode == ICameraService.ERROR_DISABLED ||
                        e.errorCode == ICameraService.ERROR_DISCONNECTED ||
                        e.errorCode == ICameraService.ERROR_INVALID_OPERATION) {
                    // Received one of the known connection errors
                    // The remote camera device cannot be connected to, so
                    // set the local camera to the startup error state
                    deviceImpl.setRemoteFailure(e);

                    if (e.errorCode == ICameraService.ERROR_DISABLED ||
                            e.errorCode == ICameraService.ERROR_DISCONNECTED ||
                            e.errorCode == ICameraService.ERROR_CAMERA_IN_USE) {
                        // Per API docs, these failures call onError and throw
                        throwAsPublicException(e);
                    }
                } else {
                    // Unexpected failure - rethrow
                    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");
                deviceImpl.setRemoteFailure(sse);
                throwAsPublicException(sse);
            }

            // TODO: factor out callback to be non-nested, then move setter to constructor
            // For now, calling setRemoteDevice will fire initial
            // onOpened/onUnconfigured callbacks.
            // This function call may post onDisconnected and throw CAMERA_DISCONNECTED if
            // cameraUser dies during setup.
            deviceImpl.setRemoteDevice(cameraUser);
            device = deviceImpl;
        }

        return device;
    }

1.1.2、getCameraCharacteristics:

        获取CameraServer,获取屏幕显示比例,判断是否是逻辑相机,将相机信息保存到CameraMetadataNative(java层的CameraMetadata),然后返回一个characteristics。

    public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)
            throws CameraAccessException {
        CameraCharacteristics characteristics = null;
        if (CameraManagerGlobal.sCameraServiceDisabled) {
            throw new IllegalArgumentException("No cameras available on device");
        }
        synchronized (mLock) {
            /*
             * Get the camera characteristics from the camera service directly if it supports it,
             * otherwise get them from the legacy shim instead.
             */
            ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
            if (cameraService == null) {
                throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                        "Camera service is currently unavailable");
            }
            try {
                Size displaySize = getDisplaySize();

                // First check isHiddenPhysicalCamera to avoid supportsCamera2ApiLocked throwing
                // exception in case cameraId is a hidden physical camera.
                if (!isHiddenPhysicalCamera(cameraId) && !supportsCamera2ApiLocked(cameraId)) {
                    // Legacy backwards compatibility path; build static info from the camera
                    // parameters
                    int id = Integer.parseInt(cameraId);

                    String parameters = cameraService.getLegacyParameters(id);

                    CameraInfo info = cameraService.getCameraInfo(id);

                    characteristics = LegacyMetadataMapper.createCharacteristics(parameters, info,
                            id, displaySize);
                } else {
                    // Normal path: Get the camera characteristics directly from the camera service
                    CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
                    try {
                        info.setCameraId(Integer.parseInt(cameraId));
                    } catch (NumberFormatException e) {
                        // For external camera, reaching here is expected.
                        Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
                    }
                    boolean hasConcurrentStreams =
                            CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId);
                    info.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
                    info.setDisplaySize(displaySize);
                    characteristics = new CameraCharacteristics(info);
                }
            } catch (ServiceSpecificException e) {
                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 characteristics;
    }

1.1.3、CameraDeviceImpl

1)构造函数中传入的StateCallback赋给了CameraDeviceImpl中的mDeviceCallback,以及其他相应的参数赋值到CameraDeviceImpl中。

    public CameraDeviceImpl(String cameraId, StateCallback callback, Executor executor,
                        CameraCharacteristics characteristics, int appTargetSdkVersion) {
        if (cameraId == null || callback == null || executor == null || characteristics == null) {
            throw new IllegalArgumentException("Null argument given");
        }
        mCameraId = cameraId;
        mDeviceCallback = callback;
        mDeviceExecutor = executor;
        mCharacteristics = characteristics;
        mAppTargetSdkVersion = appTargetSdkVersion;

        final int MAX_TAG_LEN = 23;
        String tag = String.format("CameraDevice-JV-%s", mCameraId);
        if (tag.length() > MAX_TAG_LEN) {
            tag = tag.substring(0, MAX_TAG_LEN);
        }
        TAG = tag;

        Integer partialCount =
                mCharacteristics.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT);
        if (partialCount == null) {
            // 1 means partial result is not supported.
            mTotalPartialCount = 1;
        } else {
            mTotalPartialCount = partialCount;
        }
    }

2)返回CameraDeviceCallbacks

CameraDeviceCallbacks继承ICameraDeviceCallbacks.Stub,而ICameraDeviceCallbacks.Stub是可以在Binder IPC中传输的对象,很显然这个才是应用程序与CameraService通信的回调,在这个回调中的执行方法标识当前的camera的执行状态。

ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();

/************************************************************************/

public CameraDeviceCallbacks getCallbacks() {
    return mCallbacks;
}
/************************************************************************/

private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks();
/************************************************************************/

public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
    ......
}

1.1.4、获取CameraService

1)获取CameraManagerGlobal对象,然后调用connectCameraServiceLocked。

ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
/***********************************************************************************/
 // Singleton instance
public static CameraManagerGlobal get() {
    return gCameraManager;
}
/***********************************************************************************/
private static final CameraManagerGlobal gCameraManager = new CameraManagerGlobal();

public ICameraService getCameraService() {
    synchronized(mLock) {
        connectCameraServiceLocked();
        if (mCameraService == null && !sCameraServiceDisabled) {
            Log.e(TAG, "Camera service is unavailable");
        }
        return mCameraService;
    }
}
/***********************************************************************************/

2)connectCameraServiceLocked

        private void connectCameraServiceLocked() {
            // Only reconnect if necessary
            if (mCameraService != null || sCameraServiceDisabled) return;

            Log.i(TAG, "Connecting to camera service");

            IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
            if (cameraServiceBinder == null) {
                // Camera service is now down, leave mCameraService as null
                return;
            }
            try {
                cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
            } catch (RemoteException e) {
                // Camera service is now down, leave mCameraService as null
                return;
            }

            ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);

            try {
                CameraMetadataNative.setupGlobalVendorTagDescriptor();
            } catch (ServiceSpecificException e) {
                handleRecoverableSetupErrors(e);
            }

            try {
                CameraStatus[] cameraStatuses = cameraService.addListener(this);
                for (CameraStatus c : cameraStatuses) {
                    onStatusChangedLocked(c.status, c.cameraId);

                    if (c.unavailablePhysicalCameras != null) {
                        for (String unavailPhysicalCamera : c.unavailablePhysicalCameras) {
                            onPhysicalCameraStatusChangedLocked(
                                    ICameraServiceListener.STATUS_NOT_PRESENT,
                                    c.cameraId, unavailPhysicalCamera);
                        }
                    }
                }
                mCameraService = cameraService;
            } catch(ServiceSpecificException e) {
                // Unexpected failure
                throw new IllegalStateException("Failed to register a camera service listener", e);
            } catch (RemoteException e) {
                // Camera service is now down, leave mCameraService as null
            }

            try {
                ConcurrentCameraIdCombination[] cameraIdCombinations =
                        cameraService.getConcurrentCameraIds();
                for (ConcurrentCameraIdCombination comb : cameraIdCombinations) {
                    mConcurrentCameraIdCombinations.add(comb.getConcurrentCameraIdCombination());
                }
            } catch (ServiceSpecificException e) {
                // Unexpected failure
                throw new IllegalStateException("Failed to get concurrent camera id combinations",
                        e);
            } catch (RemoteException e) {
                // Camera service died in all probability
            }
        }

3)connectDevice

connectDevice->connectHelper->makeClient->

Status CameraService::connectDevice(
        const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
        const String16& cameraId,
        const String16& clientPackageName,
        const std::unique_ptr<String16>& clientFeatureId,
        int clientUid,
        /*out*/
        sp<hardware::camera2::ICameraDeviceUser>* device) {

    ATRACE_CALL();
    Status ret = Status::ok();
    String8 id = String8(cameraId);
    sp<CameraDeviceClient> client = nullptr;
    String16 clientPackageNameAdj = clientPackageName;

    if (getCurrentServingCall() == BinderCallType::HWBINDER) {
        std::string vendorClient =
                StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
        clientPackageNameAdj = String16(vendorClient.c_str());
    }
    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
            /*api1CameraId*/-1,
            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageNameAdj, clientFeatureId,
            clientUid, USE_CALLING_PID, API_2, /*shimUpdateOnly*/ false, /*out*/client);

    if(!ret.isOk()) {
        logRejected(id, CameraThreadState::getCallingPid(), String8(clientPackageNameAdj),
                ret.toString8());
        return ret;
    }

    *device = client;
    return ret;
}

1.1.5、setRemoteDevice

mDeviceExecutor.execute(mCallOnOpened);

mDeviceExecutor.execute(mCallOnUnconfigured);

其中可从CameraDeviceImpl构造函数得知mDeviceCallback,mDeviceExecutor即是传入的参数。

    public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {
        synchronized(mInterfaceLock) {
            // TODO: Move from decorator to direct binder-mediated exceptions
            // If setRemoteFailure already called, do nothing
            if (mInError) return;

            mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);

            IBinder remoteDeviceBinder = remoteDevice.asBinder();
            // For legacy camera device, remoteDevice is in the same process, and
            // asBinder returns NULL.
            if (remoteDeviceBinder != null) {
                try {
                    remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);
                } catch (RemoteException e) {
                    CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected);

                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                            "The camera device has encountered a serious error");
                }
            }

            mDeviceExecutor.execute(mCallOnOpened);
            mDeviceExecutor.execute(mCallOnUnconfigured);
        }
    

通过我们追代码的流程分析,很清楚的可以理解下图:

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值