Loading services/camera/libcameraservice/CameraService.cpp +50 −48 Original line number Diff line number Diff line Loading @@ -651,22 +651,6 @@ String8 CameraService::getFormattedCurrentTime() { return String8(formattedTime); } int CameraService::getCameraPriorityFromProcState(int procState) { // Find the priority for the camera usage based on the process state. Higher priority clients // win for evictions. if (procState < 0) { ALOGE("%s: Received invalid process state %d from ActivityManagerService!", __FUNCTION__, procState); return -1; } // Treat sleeping TOP processes the same as regular TOP processes, for // access priority. This is important for lock-screen camera launch scenarios if (procState == PROCESS_STATE_TOP_SLEEPING) { procState = PROCESS_STATE_TOP; } return INT_MAX - procState; } Status CameraService::getCameraVendorTagDescriptor( /*out*/ hardware::camera2::params::VendorTagDescriptor* desc) { Loading Loading @@ -1212,20 +1196,24 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien 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); std::vector<int> priorityScores(ownerPids.size()); std::vector<int> states(ownerPids.size()); // Get priorites of all active PIDs ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0], /*out*/&priorities[0]); // Get priority scores of all active PIDs status_t err = ProcessInfoService::getProcessStatesScoresFromPids( ownerPids.size(), &ownerPids[0], /*out*/&states[0], /*out*/&priorityScores[0]); if (err != OK) { ALOGE("%s: Priority score query failed: %d", __FUNCTION__, err); return err; } // Update all active clients' priorities std::map<int,int> pidToPriorityMap; std::map<int,resource_policy::ClientPriority> pidToPriorityMap; for (size_t i = 0; i < ownerPids.size() - 1; i++) { pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i])); pidToPriorityMap.emplace(ownerPids[i], resource_policy::ClientPriority(priorityScores[i], states[i])); } mActiveClientManager.updatePriorities(pidToPriorityMap); Loading @@ -1242,7 +1230,9 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId, sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()), state->getConflicting(), getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid); priorityScores[priorityScores.size() - 1], clientPid, states[states.size() - 1]); // Find clients that would be evicted auto evicted = mActiveClientManager.wouldEvict(clientDescriptor); Loading @@ -1259,19 +1249,22 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien 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(), "(PID %d, score %d state %d) due to eviction policy", curTime.string(), cameraId.string(), packageName.string(), clientPid, getCameraPriorityFromProcState(priorities[priorities.size() - 1])); priorityScores[priorityScores.size() - 1], states[states.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()); "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(), String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(), i->getPriority().getScore(), i->getPriority().getState()); ALOGE(" Conflicts with: Device %s, client package %s (PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(), PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(), String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(), i->getPriority()); i->getPriority().getScore(), i->getPriority().getState()); } // Log the client's attempt Loading Loading @@ -1299,12 +1292,14 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien // 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 ")", " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for" " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")", i->getKey().string(), String8{clientSp->getPackageName()}.string(), i->getOwnerId(), i->getPriority(), cameraId.string(), i->getOwnerId(), i->getPriority().getScore(), i->getPriority().getState(), cameraId.string(), packageName.string(), clientPid, getCameraPriorityFromProcState(priorities[priorities.size() - 1]))); priorityScores[priorityScores.size() - 1], states[states.size() - 1])); // Notify the client of disconnection clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, Loading Loading @@ -2142,9 +2137,11 @@ void CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) { // Log the clients evicted logEvent(String8::format("EVICT device %s client held by package %s (PID %" PRId32 ", priority %" PRId32 ")\n - Evicted due to user switch.", i->getKey().string(), String8{clientSp->getPackageName()}.string(), i->getOwnerId(), i->getPriority())); PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted due" " to user switch.", i->getKey().string(), String8{clientSp->getPackageName()}.string(), i->getOwnerId(), i->getPriority().getScore(), i->getPriority().getState())); } Loading Loading @@ -2680,7 +2677,8 @@ String8 CameraService::CameraClientManager::toString() const { String8 key = i->getKey(); int32_t cost = i->getCost(); int32_t pid = i->getOwnerId(); int32_t priority = i->getPriority(); int32_t score = i->getPriority().getScore(); int32_t state = i->getPriority().getState(); auto conflicting = i->getConflicting(); auto clientSp = i->getValue(); String8 packageName; Loading @@ -2690,8 +2688,8 @@ String8 CameraService::CameraClientManager::toString() const { uid_t clientUid = clientSp->getClientUid(); clientUserId = multiuser_get_user_id(clientUid); } ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Priority: %" PRId32 ", ", key.string(), cost, pid, priority); ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %" PRId32 ", State: %" PRId32, key.string(), cost, pid, score, state); if (clientSp.get() != nullptr) { ret.appendFormat("User Id: %d, ", clientUserId); Loading @@ -2713,16 +2711,18 @@ String8 CameraService::CameraClientManager::toString() const { CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor( const String8& key, const sp<BasicClient>& value, int32_t cost, const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId) { const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) { return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>( key, value, cost, conflictingKeys, priority, ownerId); key, value, cost, conflictingKeys, score, ownerId, state); } CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor( const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) { return makeClientDescriptor(partial->getKey(), value, partial->getCost(), partial->getConflicting(), partial->getPriority(), partial->getOwnerId()); partial->getConflicting(), partial->getPriority().getScore(), partial->getOwnerId(), partial->getPriority().getState()); } // ---------------------------------------------------------------------------- Loading Loading @@ -2800,7 +2800,9 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { } dprintf(fd, " Device %s is open. Client instance dump:\n", cameraId.string()); dprintf(fd, " Client priority level: %d\n", clientDescriptor->getPriority()); dprintf(fd, " Client priority score: %d state: %d\n", clientDescriptor->getPriority().getScore(), clientDescriptor->getPriority().getState()); dprintf(fd, " Client PID: %d\n", clientDescriptor->getOwnerId()); auto client = clientDescriptor->getValue(); Loading services/camera/libcameraservice/CameraService.h +2 −12 Original line number Diff line number Diff line Loading @@ -75,11 +75,6 @@ public: API_2 = 2 }; // Process state (mirrors frameworks/base/core/java/android/app/ActivityManager.java) static const int PROCESS_STATE_NONEXISTENT = -1; static const int PROCESS_STATE_TOP = 2; static const int PROCESS_STATE_TOP_SLEEPING = 5; // 3 second busy timeout when other clients are connecting static const nsecs_t DEFAULT_CONNECT_TIMEOUT_NS = 3000000000; Loading Loading @@ -402,8 +397,8 @@ public: * Make a ClientDescriptor object wrapping the given BasicClient strong pointer. */ static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value, int32_t cost, const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId); int32_t cost, const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state); /** * Make a ClientDescriptor object wrapping the given BasicClient strong pointer with Loading Loading @@ -775,11 +770,6 @@ private: */ static String8 getFormattedCurrentTime(); /** * Get the camera eviction priority from the current process state given by ActivityManager. */ static int getCameraPriorityFromProcState(int procState); static binder::Status makeClient(const sp<CameraService>& cameraService, const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId, int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode, Loading services/camera/libcameraservice/utils/ClientManager.h +60 −22 Original line number Diff line number Diff line Loading @@ -31,6 +31,43 @@ namespace android { namespace resource_policy { class ClientPriority { public: ClientPriority(int32_t score, int32_t state) : mScore(score), mState(state) {} int32_t getScore() const { return mScore; } int32_t getState() const { return mState; } bool operator==(const ClientPriority& rhs) const { return (this->mScore == rhs.mScore) && (this->mState == rhs.mState); } bool operator< (const ClientPriority& rhs) const { if (this->mScore == rhs.mScore) { return this->mState < rhs.mState; } else { return this->mScore < rhs.mScore; } } bool operator> (const ClientPriority& rhs) const { return rhs < *this; } bool operator<=(const ClientPriority& rhs) const { return !(*this > rhs); } bool operator>=(const ClientPriority& rhs) const { return !(*this < rhs); } private: int32_t mScore; int32_t mState; }; // -------------------------------------------------------------------------------- /** Loading @@ -45,9 +82,9 @@ template<class KEY, class VALUE> class ClientDescriptor final { public: ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost, const std::set<KEY>& conflictingKeys, int32_t priority, int32_t ownerId); const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state); ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost, std::set<KEY>&& conflictingKeys, int32_t priority, int32_t ownerId); int32_t score, int32_t ownerId, int32_t state); ~ClientDescriptor(); Loading @@ -69,7 +106,7 @@ public: /** * Return the priority for this descriptor. */ int32_t getPriority() const; const ClientPriority &getPriority() const; /** * Return the owner ID for this descriptor. Loading @@ -89,7 +126,7 @@ public: /** * Set the proirity for this descriptor. */ void setPriority(int32_t priority); void setPriority(const ClientPriority& priority); // This class is ordered by key template<class K, class V> Loading @@ -100,7 +137,7 @@ private: VALUE mValue; int32_t mCost; std::set<KEY> mConflicting; int32_t mPriority; ClientPriority mPriority; int32_t mOwnerId; }; // class ClientDescriptor Loading @@ -111,16 +148,17 @@ bool operator < (const ClientDescriptor<K, V>& a, const ClientDescriptor<K, V>& template<class KEY, class VALUE> ClientDescriptor<KEY, VALUE>::ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost, const std::set<KEY>& conflictingKeys, int32_t priority, int32_t ownerId) : mKey{key}, mValue{value}, mCost{cost}, mConflicting{conflictingKeys}, mPriority{priority}, const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) : mKey{key}, mValue{value}, mCost{cost}, mConflicting{conflictingKeys}, mPriority(score, state), mOwnerId{ownerId} {} template<class KEY, class VALUE> ClientDescriptor<KEY, VALUE>::ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost, std::set<KEY>&& conflictingKeys, int32_t priority, int32_t ownerId) : std::set<KEY>&& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) : mKey{std::forward<KEY>(key)}, mValue{std::forward<VALUE>(value)}, mCost{cost}, mConflicting{std::forward<std::set<KEY>>(conflictingKeys)}, mPriority{priority}, mOwnerId{ownerId} {} mConflicting{std::forward<std::set<KEY>>(conflictingKeys)}, mPriority(score, state), mOwnerId{ownerId} {} template<class KEY, class VALUE> ClientDescriptor<KEY, VALUE>::~ClientDescriptor() {} Loading @@ -141,7 +179,7 @@ int32_t ClientDescriptor<KEY, VALUE>::getCost() const { } template<class KEY, class VALUE> int32_t ClientDescriptor<KEY, VALUE>::getPriority() const { const ClientPriority& ClientDescriptor<KEY, VALUE>::getPriority() const { return mPriority; } Loading @@ -165,7 +203,7 @@ std::set<KEY> ClientDescriptor<KEY, VALUE>::getConflicting() const { } template<class KEY, class VALUE> void ClientDescriptor<KEY, VALUE>::setPriority(int32_t priority) { void ClientDescriptor<KEY, VALUE>::setPriority(const ClientPriority& priority) { mPriority = priority; } Loading Loading @@ -231,7 +269,7 @@ public: * Given a map containing owner (pid) -> priority mappings, update the priority of each * ClientDescriptor with an owner in this mapping. */ void updatePriorities(const std::map<int32_t,int32_t>& ownerPriorityList); void updatePriorities(const std::map<int32_t,ClientPriority>& ownerPriorityList); /** * Remove all ClientDescriptors. Loading Loading @@ -383,17 +421,17 @@ ClientManager<KEY, VALUE, LISTENER>::wouldEvictLocked( const KEY& key = client->getKey(); int32_t cost = client->getCost(); int32_t priority = client->getPriority(); ClientPriority priority = client->getPriority(); int32_t owner = client->getOwnerId(); int64_t totalCost = getCurrentCostLocked() + cost; // Determine the MRU of the owners tied for having the highest priority int32_t highestPriorityOwner = owner; int32_t highestPriority = priority; ClientPriority highestPriority = priority; for (const auto& i : mClients) { int32_t curPriority = i->getPriority(); if (curPriority >= highestPriority) { ClientPriority curPriority = i->getPriority(); if (curPriority <= highestPriority) { highestPriority = curPriority; highestPriorityOwner = i->getOwnerId(); } Loading @@ -408,7 +446,7 @@ ClientManager<KEY, VALUE, LISTENER>::wouldEvictLocked( for (const auto& i : mClients) { const KEY& curKey = i->getKey(); int32_t curCost = i->getCost(); int32_t curPriority = i->getPriority(); ClientPriority curPriority = i->getPriority(); int32_t curOwner = i->getOwnerId(); bool conflicting = (curKey == key || i->isConflicting(key) || Loading @@ -417,13 +455,13 @@ ClientManager<KEY, VALUE, LISTENER>::wouldEvictLocked( if (!returnIncompatibleClients) { // Find evicted clients if (conflicting && curPriority > priority) { if (conflicting && curPriority < priority) { // Pre-existing conflicting client with higher priority exists evictList.clear(); evictList.push_back(client); return evictList; } else if (conflicting || ((totalCost > mMaxCost && curCost > 0) && (curPriority <= priority) && (curPriority >= priority) && !(highestPriorityOwner == owner && owner == curOwner))) { // Add a pre-existing client to the eviction list if: // - We are adding a client with higher priority that conflicts with this one. Loading @@ -437,7 +475,7 @@ ClientManager<KEY, VALUE, LISTENER>::wouldEvictLocked( } else { // Find clients preventing the incoming client from being added if (curPriority > priority && (conflicting || (totalCost > mMaxCost && curCost > 0))) { if (curPriority < priority && (conflicting || (totalCost > mMaxCost && curCost > 0))) { // Pre-existing conflicting client with higher priority exists evictList.push_back(i); } Loading Loading @@ -524,7 +562,7 @@ std::vector<int32_t> ClientManager<KEY, VALUE, LISTENER>::getAllOwners() const { template<class KEY, class VALUE, class LISTENER> void ClientManager<KEY, VALUE, LISTENER>::updatePriorities( const std::map<int32_t,int32_t>& ownerPriorityList) { const std::map<int32_t,ClientPriority>& ownerPriorityList) { Mutex::Autolock lock(mLock); for (auto& i : mClients) { auto j = ownerPriorityList.find(i->getOwnerId()); Loading Loading
services/camera/libcameraservice/CameraService.cpp +50 −48 Original line number Diff line number Diff line Loading @@ -651,22 +651,6 @@ String8 CameraService::getFormattedCurrentTime() { return String8(formattedTime); } int CameraService::getCameraPriorityFromProcState(int procState) { // Find the priority for the camera usage based on the process state. Higher priority clients // win for evictions. if (procState < 0) { ALOGE("%s: Received invalid process state %d from ActivityManagerService!", __FUNCTION__, procState); return -1; } // Treat sleeping TOP processes the same as regular TOP processes, for // access priority. This is important for lock-screen camera launch scenarios if (procState == PROCESS_STATE_TOP_SLEEPING) { procState = PROCESS_STATE_TOP; } return INT_MAX - procState; } Status CameraService::getCameraVendorTagDescriptor( /*out*/ hardware::camera2::params::VendorTagDescriptor* desc) { Loading Loading @@ -1212,20 +1196,24 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien 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); std::vector<int> priorityScores(ownerPids.size()); std::vector<int> states(ownerPids.size()); // Get priorites of all active PIDs ProcessInfoService::getProcessStatesFromPids(ownerPids.size(), &ownerPids[0], /*out*/&priorities[0]); // Get priority scores of all active PIDs status_t err = ProcessInfoService::getProcessStatesScoresFromPids( ownerPids.size(), &ownerPids[0], /*out*/&states[0], /*out*/&priorityScores[0]); if (err != OK) { ALOGE("%s: Priority score query failed: %d", __FUNCTION__, err); return err; } // Update all active clients' priorities std::map<int,int> pidToPriorityMap; std::map<int,resource_policy::ClientPriority> pidToPriorityMap; for (size_t i = 0; i < ownerPids.size() - 1; i++) { pidToPriorityMap.emplace(ownerPids[i], getCameraPriorityFromProcState(priorities[i])); pidToPriorityMap.emplace(ownerPids[i], resource_policy::ClientPriority(priorityScores[i], states[i])); } mActiveClientManager.updatePriorities(pidToPriorityMap); Loading @@ -1242,7 +1230,9 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien clientDescriptor = CameraClientManager::makeClientDescriptor(cameraId, sp<BasicClient>{nullptr}, static_cast<int32_t>(state->getCost()), state->getConflicting(), getCameraPriorityFromProcState(priorities[priorities.size() - 1]), clientPid); priorityScores[priorityScores.size() - 1], clientPid, states[states.size() - 1]); // Find clients that would be evicted auto evicted = mActiveClientManager.wouldEvict(clientDescriptor); Loading @@ -1259,19 +1249,22 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien 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(), "(PID %d, score %d state %d) due to eviction policy", curTime.string(), cameraId.string(), packageName.string(), clientPid, getCameraPriorityFromProcState(priorities[priorities.size() - 1])); priorityScores[priorityScores.size() - 1], states[states.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()); "(PID %" PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(), String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(), i->getPriority().getScore(), i->getPriority().getState()); ALOGE(" Conflicts with: Device %s, client package %s (PID %" PRId32 ", priority %" PRId32 ")", i->getKey().string(), PRId32 ", score %" PRId32 ", state %" PRId32 ")", i->getKey().string(), String8{i->getValue()->getPackageName()}.string(), i->getOwnerId(), i->getPriority()); i->getPriority().getScore(), i->getPriority().getState()); } // Log the client's attempt Loading Loading @@ -1299,12 +1292,14 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien // 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 ")", " %" PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted by device %s client for" " package %s (PID %d, score %" PRId32 ", state %" PRId32 ")", i->getKey().string(), String8{clientSp->getPackageName()}.string(), i->getOwnerId(), i->getPriority(), cameraId.string(), i->getOwnerId(), i->getPriority().getScore(), i->getPriority().getState(), cameraId.string(), packageName.string(), clientPid, getCameraPriorityFromProcState(priorities[priorities.size() - 1]))); priorityScores[priorityScores.size() - 1], states[states.size() - 1])); // Notify the client of disconnection clientSp->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, Loading Loading @@ -2142,9 +2137,11 @@ void CameraService::doUserSwitch(const std::vector<int32_t>& newUserIds) { // Log the clients evicted logEvent(String8::format("EVICT device %s client held by package %s (PID %" PRId32 ", priority %" PRId32 ")\n - Evicted due to user switch.", i->getKey().string(), String8{clientSp->getPackageName()}.string(), i->getOwnerId(), i->getPriority())); PRId32 ", score %" PRId32 ", state %" PRId32 ")\n - Evicted due" " to user switch.", i->getKey().string(), String8{clientSp->getPackageName()}.string(), i->getOwnerId(), i->getPriority().getScore(), i->getPriority().getState())); } Loading Loading @@ -2680,7 +2677,8 @@ String8 CameraService::CameraClientManager::toString() const { String8 key = i->getKey(); int32_t cost = i->getCost(); int32_t pid = i->getOwnerId(); int32_t priority = i->getPriority(); int32_t score = i->getPriority().getScore(); int32_t state = i->getPriority().getState(); auto conflicting = i->getConflicting(); auto clientSp = i->getValue(); String8 packageName; Loading @@ -2690,8 +2688,8 @@ String8 CameraService::CameraClientManager::toString() const { uid_t clientUid = clientSp->getClientUid(); clientUserId = multiuser_get_user_id(clientUid); } ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Priority: %" PRId32 ", ", key.string(), cost, pid, priority); ret.appendFormat("\n(Camera ID: %s, Cost: %" PRId32 ", PID: %" PRId32 ", Score: %" PRId32 ", State: %" PRId32, key.string(), cost, pid, score, state); if (clientSp.get() != nullptr) { ret.appendFormat("User Id: %d, ", clientUserId); Loading @@ -2713,16 +2711,18 @@ String8 CameraService::CameraClientManager::toString() const { CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor( const String8& key, const sp<BasicClient>& value, int32_t cost, const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId) { const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) { return std::make_shared<resource_policy::ClientDescriptor<String8, sp<BasicClient>>>( key, value, cost, conflictingKeys, priority, ownerId); key, value, cost, conflictingKeys, score, ownerId, state); } CameraService::DescriptorPtr CameraService::CameraClientManager::makeClientDescriptor( const sp<BasicClient>& value, const CameraService::DescriptorPtr& partial) { return makeClientDescriptor(partial->getKey(), value, partial->getCost(), partial->getConflicting(), partial->getPriority(), partial->getOwnerId()); partial->getConflicting(), partial->getPriority().getScore(), partial->getOwnerId(), partial->getPriority().getState()); } // ---------------------------------------------------------------------------- Loading Loading @@ -2800,7 +2800,9 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { } dprintf(fd, " Device %s is open. Client instance dump:\n", cameraId.string()); dprintf(fd, " Client priority level: %d\n", clientDescriptor->getPriority()); dprintf(fd, " Client priority score: %d state: %d\n", clientDescriptor->getPriority().getScore(), clientDescriptor->getPriority().getState()); dprintf(fd, " Client PID: %d\n", clientDescriptor->getOwnerId()); auto client = clientDescriptor->getValue(); Loading
services/camera/libcameraservice/CameraService.h +2 −12 Original line number Diff line number Diff line Loading @@ -75,11 +75,6 @@ public: API_2 = 2 }; // Process state (mirrors frameworks/base/core/java/android/app/ActivityManager.java) static const int PROCESS_STATE_NONEXISTENT = -1; static const int PROCESS_STATE_TOP = 2; static const int PROCESS_STATE_TOP_SLEEPING = 5; // 3 second busy timeout when other clients are connecting static const nsecs_t DEFAULT_CONNECT_TIMEOUT_NS = 3000000000; Loading Loading @@ -402,8 +397,8 @@ public: * Make a ClientDescriptor object wrapping the given BasicClient strong pointer. */ static DescriptorPtr makeClientDescriptor(const String8& key, const sp<BasicClient>& value, int32_t cost, const std::set<String8>& conflictingKeys, int32_t priority, int32_t ownerId); int32_t cost, const std::set<String8>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state); /** * Make a ClientDescriptor object wrapping the given BasicClient strong pointer with Loading Loading @@ -775,11 +770,6 @@ private: */ static String8 getFormattedCurrentTime(); /** * Get the camera eviction priority from the current process state given by ActivityManager. */ static int getCameraPriorityFromProcState(int procState); static binder::Status makeClient(const sp<CameraService>& cameraService, const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId, int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode, Loading
services/camera/libcameraservice/utils/ClientManager.h +60 −22 Original line number Diff line number Diff line Loading @@ -31,6 +31,43 @@ namespace android { namespace resource_policy { class ClientPriority { public: ClientPriority(int32_t score, int32_t state) : mScore(score), mState(state) {} int32_t getScore() const { return mScore; } int32_t getState() const { return mState; } bool operator==(const ClientPriority& rhs) const { return (this->mScore == rhs.mScore) && (this->mState == rhs.mState); } bool operator< (const ClientPriority& rhs) const { if (this->mScore == rhs.mScore) { return this->mState < rhs.mState; } else { return this->mScore < rhs.mScore; } } bool operator> (const ClientPriority& rhs) const { return rhs < *this; } bool operator<=(const ClientPriority& rhs) const { return !(*this > rhs); } bool operator>=(const ClientPriority& rhs) const { return !(*this < rhs); } private: int32_t mScore; int32_t mState; }; // -------------------------------------------------------------------------------- /** Loading @@ -45,9 +82,9 @@ template<class KEY, class VALUE> class ClientDescriptor final { public: ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost, const std::set<KEY>& conflictingKeys, int32_t priority, int32_t ownerId); const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state); ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost, std::set<KEY>&& conflictingKeys, int32_t priority, int32_t ownerId); int32_t score, int32_t ownerId, int32_t state); ~ClientDescriptor(); Loading @@ -69,7 +106,7 @@ public: /** * Return the priority for this descriptor. */ int32_t getPriority() const; const ClientPriority &getPriority() const; /** * Return the owner ID for this descriptor. Loading @@ -89,7 +126,7 @@ public: /** * Set the proirity for this descriptor. */ void setPriority(int32_t priority); void setPriority(const ClientPriority& priority); // This class is ordered by key template<class K, class V> Loading @@ -100,7 +137,7 @@ private: VALUE mValue; int32_t mCost; std::set<KEY> mConflicting; int32_t mPriority; ClientPriority mPriority; int32_t mOwnerId; }; // class ClientDescriptor Loading @@ -111,16 +148,17 @@ bool operator < (const ClientDescriptor<K, V>& a, const ClientDescriptor<K, V>& template<class KEY, class VALUE> ClientDescriptor<KEY, VALUE>::ClientDescriptor(const KEY& key, const VALUE& value, int32_t cost, const std::set<KEY>& conflictingKeys, int32_t priority, int32_t ownerId) : mKey{key}, mValue{value}, mCost{cost}, mConflicting{conflictingKeys}, mPriority{priority}, const std::set<KEY>& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) : mKey{key}, mValue{value}, mCost{cost}, mConflicting{conflictingKeys}, mPriority(score, state), mOwnerId{ownerId} {} template<class KEY, class VALUE> ClientDescriptor<KEY, VALUE>::ClientDescriptor(KEY&& key, VALUE&& value, int32_t cost, std::set<KEY>&& conflictingKeys, int32_t priority, int32_t ownerId) : std::set<KEY>&& conflictingKeys, int32_t score, int32_t ownerId, int32_t state) : mKey{std::forward<KEY>(key)}, mValue{std::forward<VALUE>(value)}, mCost{cost}, mConflicting{std::forward<std::set<KEY>>(conflictingKeys)}, mPriority{priority}, mOwnerId{ownerId} {} mConflicting{std::forward<std::set<KEY>>(conflictingKeys)}, mPriority(score, state), mOwnerId{ownerId} {} template<class KEY, class VALUE> ClientDescriptor<KEY, VALUE>::~ClientDescriptor() {} Loading @@ -141,7 +179,7 @@ int32_t ClientDescriptor<KEY, VALUE>::getCost() const { } template<class KEY, class VALUE> int32_t ClientDescriptor<KEY, VALUE>::getPriority() const { const ClientPriority& ClientDescriptor<KEY, VALUE>::getPriority() const { return mPriority; } Loading @@ -165,7 +203,7 @@ std::set<KEY> ClientDescriptor<KEY, VALUE>::getConflicting() const { } template<class KEY, class VALUE> void ClientDescriptor<KEY, VALUE>::setPriority(int32_t priority) { void ClientDescriptor<KEY, VALUE>::setPriority(const ClientPriority& priority) { mPriority = priority; } Loading Loading @@ -231,7 +269,7 @@ public: * Given a map containing owner (pid) -> priority mappings, update the priority of each * ClientDescriptor with an owner in this mapping. */ void updatePriorities(const std::map<int32_t,int32_t>& ownerPriorityList); void updatePriorities(const std::map<int32_t,ClientPriority>& ownerPriorityList); /** * Remove all ClientDescriptors. Loading Loading @@ -383,17 +421,17 @@ ClientManager<KEY, VALUE, LISTENER>::wouldEvictLocked( const KEY& key = client->getKey(); int32_t cost = client->getCost(); int32_t priority = client->getPriority(); ClientPriority priority = client->getPriority(); int32_t owner = client->getOwnerId(); int64_t totalCost = getCurrentCostLocked() + cost; // Determine the MRU of the owners tied for having the highest priority int32_t highestPriorityOwner = owner; int32_t highestPriority = priority; ClientPriority highestPriority = priority; for (const auto& i : mClients) { int32_t curPriority = i->getPriority(); if (curPriority >= highestPriority) { ClientPriority curPriority = i->getPriority(); if (curPriority <= highestPriority) { highestPriority = curPriority; highestPriorityOwner = i->getOwnerId(); } Loading @@ -408,7 +446,7 @@ ClientManager<KEY, VALUE, LISTENER>::wouldEvictLocked( for (const auto& i : mClients) { const KEY& curKey = i->getKey(); int32_t curCost = i->getCost(); int32_t curPriority = i->getPriority(); ClientPriority curPriority = i->getPriority(); int32_t curOwner = i->getOwnerId(); bool conflicting = (curKey == key || i->isConflicting(key) || Loading @@ -417,13 +455,13 @@ ClientManager<KEY, VALUE, LISTENER>::wouldEvictLocked( if (!returnIncompatibleClients) { // Find evicted clients if (conflicting && curPriority > priority) { if (conflicting && curPriority < priority) { // Pre-existing conflicting client with higher priority exists evictList.clear(); evictList.push_back(client); return evictList; } else if (conflicting || ((totalCost > mMaxCost && curCost > 0) && (curPriority <= priority) && (curPriority >= priority) && !(highestPriorityOwner == owner && owner == curOwner))) { // Add a pre-existing client to the eviction list if: // - We are adding a client with higher priority that conflicts with this one. Loading @@ -437,7 +475,7 @@ ClientManager<KEY, VALUE, LISTENER>::wouldEvictLocked( } else { // Find clients preventing the incoming client from being added if (curPriority > priority && (conflicting || (totalCost > mMaxCost && curCost > 0))) { if (curPriority < priority && (conflicting || (totalCost > mMaxCost && curCost > 0))) { // Pre-existing conflicting client with higher priority exists evictList.push_back(i); } Loading Loading @@ -524,7 +562,7 @@ std::vector<int32_t> ClientManager<KEY, VALUE, LISTENER>::getAllOwners() const { template<class KEY, class VALUE, class LISTENER> void ClientManager<KEY, VALUE, LISTENER>::updatePriorities( const std::map<int32_t,int32_t>& ownerPriorityList) { const std::map<int32_t,ClientPriority>& ownerPriorityList) { Mutex::Autolock lock(mLock); for (auto& i : mClients) { auto j = ownerPriorityList.find(i->getOwnerId()); Loading