camera 之 openCamera

openCamera() 方法参数解析

1、 打开 camera我们可以直接调用系统service,获得CameraManager,然后调用openCamera();
CameraManager cameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
cameraManager.openCamera(mCameraId, mStateCallback, mCameraHandler);

openCamera() 需要传递三个参数,第一个参数是当前你要具体使用的cameraId。

            for (String cameraId : cameraManager.getCameraIdList()) {
                //描述相机设备的属性类
                cameraId = cameraId;
                CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
                //获取是前置还是后置摄像头
                Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
                //使用后置摄像头
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {
                    StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                    if (map != null) {
                        Size[] sizeMap = map.getOutputSizes(SurfaceTexture.class);
                        LogUtil.d("preview->" + previewSize.toString());
                        mCameraId = cameraId;
                    }
            }

openCamera() 第二个参数是open 摄像头的状态,回调三个方法分别是打开成功、摄像头没有连接、打开失败。需要继承自CameraDevice.StateCallback 接口类。

private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(CameraDevice camera) {
        }

        @Override
        public void onDisconnected(CameraDevice camera) {
        }

        @Override
        public void onError(CameraDevice camera, int error) {
        }
    };

openCamera() 第三个参数就是主线程的handler。

mCameraHandler = new Handler(handlerThread.getLooper());

openCamera() 代码流程

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

    @RequiresPermission(android.Manifest.permission.CAMERA)
    public void openCamera(@NonNull String cameraId,
            @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
            throws CameraAccessException {

		// 1、checkAndWrapHandler()就是判断handler是不是null,USE_CALLING_UID 系统默认为-1
        openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
                USE_CALLING_UID);
    }
    
    public void openCameraForUid(@NonNull String cameraId,
            @NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
            int clientUid)
            throws CameraAccessException {

        if (cameraId == null) {
            throw new IllegalArgumentException("cameraId was null");
        } else if (callback == null) {
            throw new IllegalArgumentException("callback was null");
        }
        if (CameraManagerGlobal.sCameraServiceDisabled) {
            throw new IllegalArgumentException("No cameras available on device");
        }
		
		// 2.0
        openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);
    }


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;

			// 2.1 这里new deviceImpl里面没做什么事,就是把一些属性值进行了赋值
            android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
                    new android.hardware.camera2.impl.CameraDeviceImpl(
                        cameraId,
                        callback,
                        executor,
                        characteristics,
                        mContext.getApplicationInfo().targetSdkVersion);

			// 2.2 接着deviceImpl.getCallbacks() 返回的就是 mCallbacks = new CameraDeviceCallbacks();
			// public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub{}
            ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();

            try {
                if (supportsCamera2ApiLocked(cameraId)) {
                	// 2.3 这里的ICameraService 的实现类是 CameraService
                	// class CameraService : public BinderService<CameraService>,
    				//						public virtual ::android::hardware::BnCameraService,
    				//						public virtual IBinder::DeathRecipient,
    				//						public virtual CameraProviderManager::StatusListener
    				// BinderService 的实现在
    		        //out\soong\.intermediates\frameworks\av\camera\libcamera_client\android_arm64_armv8-a_core_shared_cfi\gen\aidl\android\hardware\BnCameraService.h
					// class BnCameraService : public ::android::BnInterface<ICameraService>
                    ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
                    ...... 省略部分代码......

					/* 通过 ICameraService::connectDevice() 连接设备,
                     * 返回的 cameraUser 实际上是远端CameraDeviceClient的本地代理。通过
                     * cameraUser 访问到具体实现类CameraDeviceClient的方法。
                     * class BnCameraDeviceUser : public ::android::BnInterface<ICameraDeviceUser>
                     * 
                     * struct CameraDeviceClientBase : public hardware::camera2::BnCameraDeviceUser 
                     * 
					 * class CameraDeviceClient : public Camera2ClientBase<CameraDeviceClientBase>,
                     */
                  cameraUser = cameraService.connectDevice(callbacks, cameraId,
                            mContext.getOpPackageName(), uid);
                } else {
            	...... 省略部分代码......
                }
            } catch (ServiceSpecificException e) {
            	...... 省略部分代码......
            }

            // 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.
            // 2.4 上面cameraService.connectDevice
            deviceImpl.setRemoteDevice(cameraUser);
            device = deviceImpl;
        }

        return device;
    }

frameworks\av\services\camera\libcameraservice\CameraService.cpp



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

    ATRACE_CALL();
    Status ret = Status::ok();
    String8 id = String8(cameraId);
    sp<CameraDeviceClient> client = nullptr;
    // 2.3.1看这里, client 的赋值在connectHelper(......., /*out*/client) 中。
    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,
            /*api1CameraId*/-1,
            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,
            clientUid, USE_CALLING_PID, API_2,
            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
            /*out*/client);

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

    *device = client;
    return ret;
}

// CALLBACK是CameraDeviceCallbacks, CLIENT是CameraDeviceClient
//2.3.2 看这里, client 的赋值是在connectHelper(......., /*out*/client) 中。
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
        int api1CameraId, int halVersion, const String16& clientPackageName, int clientUid,
        int clientPid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
        /*out*/sp<CLIENT>& device) {
......省略部分代码......
        if (clientTmp.get() != nullptr) {
            // Handle special case for API1 MediaRecorder where the existing client is returned
            // 处理API1 MediaRecorder返回现有客户端的特殊情况
            device = static_cast<CLIENT*>(clientTmp.get());
            return ret;
        }
......省略部分代码......
  sp<BasicClient> tmp = nullptr;
  		// 2.3.3 makeClient中会new CameraDeviceClient
        if(!(ret = makeClient(this, cameraCb, clientPackageName,
                cameraId, api1CameraId, facing,
                clientPid, clientUid, getpid(), legacyMode,
                halVersion, deviceVersion, effectiveApiLevel,
                /*out*/&tmp)).isOk()) {
            return ret;
        }
        client = static_cast<CLIENT*>(tmp.get());

        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
                __FUNCTION__);

		// 2.3.4
        err = client->initialize(mCameraProviderManager, mMonitorTags);
......省略部分代码......
    device = client;
    return ret;

}


Status CameraService::makeClient(const sp<CameraService>& cameraService,
        const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
        int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,
        bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
        /*out*/sp<BasicClient>* client) {

	// 我们知道这里apiLevel = API_2 = 2; 路由走的是api2所以*client = new CameraDeviceClient()
    if (halVersion < 0 || halVersion == deviceVersion) {
        // Default path: HAL version is unspecified by caller, create CameraClient
        // based on device version reported by the HAL.
        switch(deviceVersion) {
          case CAMERA_DEVICE_API_VERSION_1_0:
            if (effectiveApiLevel == API_1) {  // Camera1 API route
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new CameraClient(cameraService, tmp, packageName,
                        api1CameraId, facing, clientPid, clientUid,
                        getpid(), legacyMode);
            } else { // Camera2 API route
                ALOGW("Camera using old HAL version: %d", deviceVersion);
                return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
                        "Camera device \"%s\" HAL version %d does not support camera2 API",
                        cameraId.string(), deviceVersion);
            }
            break;
          case CAMERA_DEVICE_API_VERSION_3_0:
          case CAMERA_DEVICE_API_VERSION_3_1:
          case CAMERA_DEVICE_API_VERSION_3_2:
          case CAMERA_DEVICE_API_VERSION_3_3:
          case CAMERA_DEVICE_API_VERSION_3_4:
            if (effectiveApiLevel == API_1) { // Camera1 API route
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new Camera2Client(cameraService, tmp, packageName,
                        cameraId, api1CameraId,
                        facing, clientPid, clientUid,
                        servicePid, legacyMode);
            } else { // Camera2 API route
                sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
                        static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
                *client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
                        facing, clientPid, clientUid, servicePid);
            }
            break;
          default:
            // Should not be reachable
            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                    "Camera device \"%s\" has unknown HAL version %d",
                    cameraId.string(), deviceVersion);
        }
    } else {
		.......省略部分代码.......
    }
    return Status::ok();
}

CameraDeviceClient::initialize(mCameraProviderManager, mMonitorTags)
framework\base\core\java\android\hardware\camera2\impl\CameraDeviceImpl.java


status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    return initializeImpl(manager, monitorTags);
}

template<typename TProviderPtr>
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
    ATRACE_CALL();
    status_t res;

	// 2.3.4.1
    res = Camera2ClientBase::initialize(providerPtr, monitorTags);
    if (res != OK) {
        return res;
    }

    String8 threadName;
    mFrameProcessor = new FrameProcessorBase(mDevice);
    threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
    mFrameProcessor->run(threadName.string());

    mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
                                      FRAME_PROCESSOR_LISTENER_MAX_ID,
                                      /*listener*/this,
                                      /*sendPartials*/true);

    auto deviceInfo = mDevice->info();
    camera_metadata_entry_t physicalKeysEntry = deviceInfo.find(
            ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS);
    if (physicalKeysEntry.count > 0) {
        mSupportedPhysicalRequestKeys.insert(mSupportedPhysicalRequestKeys.begin(),
                physicalKeysEntry.data.i32,
                physicalKeysEntry.data.i32 + physicalKeysEntry.count);
    }

    return OK;
}

Camera2ClientBase::initialize

template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,
        const String8& monitorTags) {
    return initializeImpl(manager, monitorTags);
}

template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
        const String8& monitorTags) {
    // Verify ops permissions
    res = TClientBase::startCameraOps();
    if (res != OK) {
        return res;
    }
	..... 省略部分代码.......
	// mDevice 是 Camera3Device,赋值在Camera2ClientBase的构造函数,前面知道
	// CameraDeviceClient继承自public Camera2ClientBase<CameraDeviceClientBase>,所以
	// 在new CameraDeviceClient时候也就调用了Camera2ClientBase
    res = mDevice->initialize(providerPtr, monitorTags);
    if (res != OK) {
        ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
        return res;
    }

    wp<CameraDeviceBase::NotificationListener> weakThis(this);
    res = mDevice->setNotifyCallback(weakThis);

    return OK;
}

Camera3Device::initialize()
frameworks\av\services\camera\libcameraservice\device3\Camera3Device.cpp

status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
	..... 省略部分代码.......
	 status_t res = manager->openSession(mId.string(), this,
            /*out*/ &session);
   ..... 省略部分代码.......
}

CameraProviderManager::openSession()
frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.cpp

status_t CameraProviderManager::openSession(const std::string &id,
        const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
        /*out*/
        sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
    
	 /* 从 CameraProviderManager 的 mProviders 查找对应 id 的 mDevices,
     * 而后调用相对应的 deviceInfo3->mInterface->open(),其中,mInterface
     * 是在CameraProvider adddevice 时,通过DeviceInfo3的构造函数传递进来的,
     * mInterface 最终为
     * android::hardware::camera::device::V3_4::implementation::CameraDevice
     */
    ret = deviceInfo3->mInterface->open(callback, [&status, &session]
            (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
                status = s;
                if (status == Status::OK) {
                    *session = cameraSession;
                }
            });
    ..... 省略部分代码.......
   }

CameraDevice::open()
hardware\interfaces\camera\device\1.0\default\CameraDevice.cpp

Return<Status> CameraDevice::open(const sp<ICameraDeviceCallback>& callback) {
    ALOGI("Opening camera %s", mCameraId.c_str());
    Mutex::Autolock _l(mLock);

    camera_info info;
    status_t res = mModule->getCameraInfo(mCameraIdInt, &info);
    if (res != OK) {
        ALOGE("Could not get camera info: %s: %d", mCameraId.c_str(), res);
        return getHidlStatus(res);
    }

    int rc = OK;
    if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
        info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
        // Open higher version camera device as HAL1.0 device.
        rc = mModule->openLegacy(mCameraId.c_str(),
                                 CAMERA_DEVICE_API_VERSION_1_0,
                                 (hw_device_t **)&mDevice);
    } else {
    	//这个mModule就是CameraModule类,hal层实现的就是CameraModule,各个厂家可以做成so来加载,不对外公开。
        rc = mModule->open(mCameraId.c_str(), (hw_device_t **)&mDevice);
    }
	..... 省略部分代码.......
    return getHidlStatus(rc);
}

上面就是大体openCamera的整个过程。如果上面的整个过程没有error,下面接着会回调到应用。

接着上面的deviceImpl.setRemoteDevice(cameraUser),得到 CameraDeviceClient,然后给到 CameraDeviceImpl。

    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");
                }
            }

			// 2.4.1这里会执行这个线程 mCallOnOpened
            mDeviceExecutor.execute(mCallOnOpened);
            mDeviceExecutor.execute(mCallOnUnconfigured);
        }
    }

    private final Runnable mCallOnOpened = new Runnable() {
        @Override
        public void run() {
            StateCallbackKK sessionCallback = null;
            synchronized(mInterfaceLock) {
                if (mRemoteDevice == null) return; // Camera already closed

                sessionCallback = mSessionStateCallback;
            }
            if (sessionCallback != null) {
                sessionCallback.onOpened(CameraDeviceImpl.this);
            }
            //2.4.1.1这里的mDeviceCallback就是前面new CameraDeviceImpl时传进来的应用实现的CameraDevice.StateCallback,调用StateCallback方法onOpened(). 
            mDeviceCallback.onOpened(CameraDeviceImpl.this);
        }
    };

时序图

在这里插入图片描述

关系图

在这里插入图片描述

参考:https://blog.csdn.net/weixin_41944449/article/details/99684653

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值