cameraservice handleEvictionsLocked函数简单分析。
来源:互联网 发布:迷你笔记本电脑知乎 编辑:程序博客网 时间:2024/06/05 14:28
status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clientPid, apiLevel effectiveApiLevel, const sp<IBinder>& remoteCallback, const String8& packageName, /*out*/ sp<BasicClient>* client, std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>* partial) { ATRACE_CALL(); status_t ret = NO_ERROR; std::vector<DescriptorPtr> evictedClients; DescriptorPtr clientDescriptor; { if (effectiveApiLevel == API_1) { // If we are using API1, any existing client for this camera ID with the same remote // should be returned rather than evicted to allow MediaRecorder to work properly. auto current = mActiveClientManager.get(cameraId); if (current != nullptr) { auto clientSp = current->getValue(); if (clientSp.get() != nullptr) { // should never be needed if (!clientSp->canCastToApiClient(effectiveApiLevel)) { ALOGW("CameraService connect called from same client, but with a different" " API level, evicting prior client..."); } else if (clientSp->getRemote() == remoteCallback) { ALOGI("CameraService::connect X (PID %d) (second call from same" " app binder, returning the same client)", clientPid); *client = clientSp; return NO_ERROR; } } } } // Get current active client PIDs std::vector<int> ownerPids(mActiveClientManager.getAllOwners()); ownerPids.push_back(clientPid); // Use the value +PROCESS_STATE_NONEXISTENT, to avoid taking // address of PROCESS_STATE_NONEXISTENT as a reference argument // for the vector constructor. PROCESS_STATE_NONEXISTENT does // not have an out-of-class definition. std::vector<int> priorities(ownerPids.size(), +PROCESS_STATE_NONEXISTENT); // Get priorites of all active PIDs ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0], /*out*/&priorities[0]); // Update all active clients' priorities std::map<int,int> pidToPriorityMap; //!++ ALOGI("Incoming clientPid(%d) packageName(%s) priorities(%d)",clientPid,packageName.string(),priorities[priorities.size() - 1]); if(strcmp("mtk_vt_use", packageName) == 0) { ALOGI("Incoming client is mtk_vt_use, set priorities(old:%d) = 0",priorities[priorities.size() - 1]); priorities[priorities.size() - 1] = 0; } //!-- // modify for preventing 3rd party pre-empty beginfor(size_t n = 0; n< 2; n++ ){String8 id = String8::format("%zu", n);String8 pkg;if(mActiveClientManager.getCameraClient(id)!=0){pkg = String8(mActiveClientManager.getCameraClient(id)->getPackageName().string());}else{ALOGI("Camera[%zu] has no client NOW",n);continue;}if(0 == strcmp("com.mediatek.camera",pkg.string())&& 0 == strcmp("com.google.android.apps.photos",packageName.string())){ALOGI("mediatek camera is running, google photo is excluded");return BAD_VALUE;}}//modify for preventing 3rd party pre-empty end for (size_t i = 0; i < ownerPids.size() - 1; i++) { //!++ //make sure VT has top priority if( mActiveClientManager.getCameraClient(cameraId) != 0 && strcmp("mtk_vt_use", String8(mActiveClientManager.getCameraClient(cameraId)->getPackageName().string())) == 0) { int clientPid_vt = mActiveClientManager.getCameraClient(cameraId)->getClientPid(); if(clientPid_vt == ownerPids[i]) { priorities[i] = 0; ALOGI("i(%zu) pid(%d) => mtk_vt_use, set priorities(old:%d) = 0",i,ownerPids[i],priorities[i]); } } else if(strcmp("mtk_vt_use", packageName) == 0) { priorities[i] = INT_MAX; ALOGI("i(%zu) pid(%d) not mtk_vt_use, set priorities(old:%d) = INT_MAX",i,ownerPids[i],priorities[i]); } ALOGI("i(%zu) pid(%d) priorities(%d),Priority(%d)",i,ownerPids[i],priorities[i],getCameraPriorityFromProcState(priorities[i])); //!-- pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i])); } mActiveClientManager.updatePriorities(pidToPriorityMap); // Get state for the given cameraId auto state = getCameraState(cameraId); if (state == nullptr) { ALOGE("CameraService::connect X (PID %d) rejected (no camera device with ID %s)", clientPid, cameraId.string()); // Should never get here because validateConnectLocked should have errored out return BAD_VALUE; } // Make descriptor for incoming client clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId, sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()), state->getConflicting(), getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid); // Find clients that would be evicted auto evicted = mActiveClientManager.wouldEvict(clientDescriptor); // If the incoming client was 'evicted,' higher priority clients have the camera in the // background, so we cannot do evictions if (std::find(evicted.begin(), evicted.end(), clientDescriptor) != evicted.end()) { ALOGE("CameraService::connect X (PID %d) rejected (existing client(s) with higher" " priority).", clientPid); sp<BasicClient> clientSp = clientDescriptor->getValue(); String8 curTime = getFormattedCurrentTime(); auto incompatibleClients = mActiveClientManager.getIncompatibleClients(clientDescriptor); String8 msg = String8::format("%s : DENIED connect device %s client for package %s " "(PID %d, priority %d) due to eviction policy", curTime.string(), cameraId.string(), packageName.string(), clientPid, getCameraPriorityFromProcState(priorities[priorities.size() - 1])); for (auto& i : incompatibleClients) { msg.appendFormat("\n - Blocked by existing device %s client for package %s" "(PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(), String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(), i->getPriority()); ALOGE(" Conflicts with: Device %s, client package %s (PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(), String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(), i->getPriority()); } // Log the client's attempt Mutex::Autolock l(mLogLock); mEventLog.add(msg); return -EBUSY; } for (auto& i : evicted) { sp<BasicClient> clientSp = i->getValue(); if (clientSp.get() == nullptr) { ALOGE("%s: Invalid state: Null client in active client list.", __FUNCTION__); // TODO: Remove this LOG_ALWAYS_FATAL("%s: Invalid state for CameraService, null client in active list", __FUNCTION__); mActiveClientManager.remove(i); continue; } ALOGE("CameraService::connect evicting conflicting client for camera ID %s", i->getKey().string()); evictedClients.push_back(i); // Log the clients evicted logEvent(String8::format("EVICT device %s client held by package %s (PID" " %" PRId32 ", priority %" PRId32 ")\n - Evicted by device %s client for" " package %s (PID %d, priority %" PRId32 ")", i->getKey().string(), String8{clientSp->getPackageName()}.string(), i->getOwnerId(), i->getPriority(), cameraId.string(), packageName.string(), clientPid, getCameraPriorityFromProcState(priorities[priorities.size() - 1]))); // Notify the client of disconnection clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, CaptureResultExtras()); } } // Do not hold mServiceLock while disconnecting clients, but retain the condition blocking // other clients from connecting in mServiceLockWrapper if held mServiceLock.unlock(); // Clear caller identity temporarily so client disconnect PID checks work correctly int64_t token = IPCThreadState::self()->clearCallingIdentity(); // Destroy evicted clients for (auto& i : evictedClients) { // Disconnect is blocking, and should only have returned when HAL has cleaned up i->getValue()->disconnect(); // Clients will remove themselves from the active client list } IPCThreadState::self()->restoreCallingIdentity(token); for (const auto& i : evictedClients) { ALOGV("%s: Waiting for disconnect to complete for client for device %s (PID %" PRId32 ")", __FUNCTION__, i->getKey().string(), i->getOwnerId()); ret = mActiveClientManager.waitUntilRemoved(i, DEFAULT_DISCONNECT_TIMEOUT_NS); if (ret == TIMED_OUT) { ALOGE("%s: Timed out waiting for client for device %s to disconnect, " "current clients:\n%s", __FUNCTION__, i->getKey().string(), mActiveClientManager.toString().string()); return -EBUSY; } if (ret != NO_ERROR) { ALOGE("%s: Received error waiting for client for device %s to disconnect: %s (%d), " "current clients:\n%s", __FUNCTION__, i->getKey().string(), strerror(-ret), ret, mActiveClientManager.toString().string()); return ret; } } evictedClients.clear(); // Once clients have been disconnected, relock mServiceLock.lock(); // Check again if the device was unplugged or something while we weren't holding mServiceLock if ((ret = checkIfDeviceIsUsable(cameraId)) != NO_ERROR) { return ret; } *partial = clientDescriptor; return NO_ERROR;}
阅读全文
0 0
- cameraservice handleEvictionsLocked函数简单分析。
- Camera API1 从应用到CameraService分析
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- Android4.4 Camera client连接到CameraService的过程分析
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- CameraService初始化
- kernel_thread函数简单分析
- memset函数简单分析
- klist函数的简单分析
- 函数调用过程简单分析
- 简单的分析函数举例
- 简单的分析函数举例
- ffmpeg 函数简单分析 : av_register_all()
- ffmpeg 函数简单分析 : avcodec_register_all()
- ffmpeg 函数简单分析 : av_read_frame()
- FFmpeg函数简单分析:avformat_find_stream_info()
- FFmpeg函数简单分析:avformat_close_input()
- 重温DOS下的小作品:回忆过去,展望将来
- Caffe中学习率策略
- Maven最佳实践:版本管理
- zeppelin源码分析(4)——主要的class分析(下)
- java中几种Map在什么情况下使用,并简单介绍原因及原理
- cameraservice handleEvictionsLocked函数简单分析。
- GMS: Grid-based Motion Statistics for Fast, Ultra-robust Feature Correspondence解读
- 关于android生成的MD5值
- c++ list, vector, map, set 区别与用法比较
- CQRS体系结构模式实践案例:Tiny Library:领域仓储与事件存储
- android studio 使用lambda表达式
- windows系统安装composer,解决安装magento问题
- Android开发之银联工作密钥,主密钥,传输密钥(加解密图文展示)
- 获取运行文件路径 ,TCHAR 转 CString