Android camera open 流程( 三 )

clientTmp = nullptr;1661std::shared_ptr> partial;1662if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,1663IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,1664/*out*/&partial)) != NO_ERROR) {1665switch (err) {1666case -ENODEV:1667return STATUS_ERROR_FMT(ERROR_DISCONNECTED,1668"No camera device with ID \"%s\" currently available",1669cameraId.string());1670case -EBUSY:1671return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,1672"Higher-priority client using camera, ID \"%s\" currently unavailable",1673cameraId.string());1674case -EUSERS:1675return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,1676"Too many cameras already open, cannot open camera \"%s\"",1677cameraId.string());1678default:1679return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,1680"Unexpected error %s (%d) opening camera \"%s\"",1681strerror(-err), err, cameraId.string());1682}1683}16841685if (clientTmp.get() != nullptr) {1686// Handle special case for API1 MediaRecorder where the existing client is returned1687device = static_cast(clientTmp.get());1688return ret;1689}16901691// give flashlight a chance to close devices if necessary.1692mFlashlight->prepareDeviceOpen(cameraId);16931694int facing = -1;1695int deviceVersion = getDeviceVersion(cameraId, /*out*/&facing);1696if (facing == -1) {1697ALOGE("%s: Unable to get camera device \"%s\"facing", __FUNCTION__, cameraId.string());1698return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,1699"Unable to get camera device \"%s\" facing", cameraId.string());1700}17011702sp tmp = nullptr;1703if(!(ret = makeClient(this, cameraCb, clientPackageName, clientFeatureId,1704cameraId, api1CameraId, facing,1705clientPid, clientUid, getpid(),1706halVersion, deviceVersion, effectiveApiLevel,1707/*out*/&tmp)).isOk()) {1708return ret;1709}1710client = static_cast(tmp.get());17111712LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",1713__FUNCTION__);//这里的client就是CameraDeviceClient1715err = client->initialize(mCameraProviderManager, mMonitorTags);1716if (err != OK) {1717ALOGE("%s: Could not initialize client from HAL.", __FUNCTION__);1718// Errors could be from the HAL module open call or from AppOpsManager1719switch(err) {1720case BAD_VALUE:1721return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,1722"Illegal argument to HAL module for camera \"%s\"", cameraId.string());1723case -EBUSY:1724return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,1725"Camera \"%s\" is already open", cameraId.string());1726case -EUSERS:1727return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,1728"Too many cameras already open, cannot open camera \"%s\"",1729cameraId.string());1730case PERMISSION_DENIED:1731return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,1732"No permission to open camera \"%s\"", cameraId.string());1733case -EACCES:1734return STATUS_ERROR_FMT(ERROR_DISABLED,1735"Camera \"%s\" disabled by policy", cameraId.string());1736case -ENODEV:1737default:1738return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,1739"Failed to initialize camera \"%s\": %s (%d)", cameraId.string(),1740strerror(-err), err);1741}1742}17431744// Update shim paremeters for legacy clients1745if (effectiveApiLevel == API_1) {1746// Assume we have always received a Client subclass for API11747sp shimClient = reinterpret_cast(client.get());1748String8 rawParams = shimClient->getParameters();1749CameraParameters params(rawParams);17501751auto cameraState = getCameraState(cameraId);1752if (cameraState != nullptr) {1753cameraState->setShimParams(params);1754} else {1755ALOGE("%s: Cannot update shim parameters for camera %s, no such device exists.",1756__FUNCTION__, cameraId.string());1757}1758}17591760// Set rotate-and-crop override behavior1761if (mOverrideRotateAndCropMode != ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {1762client->setRotateAndCropOverride(mOverrideRotateAndCropMode);1763}17641765if (shimUpdateOnly) {1766// If only updating legacy shim parameters, immediately disconnect client1767mServiceLock.unlock();1768client->disconnect();1769mServiceLock.lock();1770} else {1771// Otherwise, add client to active clients list1772finishConnectLocked(client, partial);1773}1774} // lock is destroyed, allow further connect calls17751776// Important: release the mutex here so the client can call back into the service from its1777// destructor (can be at the end of the call)1778device = client;1779return ret;}