Loading services/camera/libcameraservice/CameraService.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -128,10 +128,9 @@ static const String16 static const String16 sCameraOpenCloseListenerPermission( "android.permission.CAMERA_OPEN_CLOSE_LISTENER"); // Matches with PERCEPTIBLE_APP_ADJ in ProcessList.java static constexpr int32_t kVendorClientScore = 200; // Matches with PROCESS_STATE_PERSISTENT_UI in ActivityManager.java static constexpr int32_t kVendorClientState = 1; static constexpr int32_t kVendorClientScore = resource_policy::PERCEPTIBLE_APP_ADJ; static constexpr int32_t kVendorClientState = ActivityManager::PROCESS_STATE_PERSISTENT_UI; const String8 CameraService::kOfflineDevice("offline-"); CameraService::CameraService() : Loading services/camera/libcameraservice/tests/ClientManagerTest.cpp +43 −6 Original line number Diff line number Diff line Loading @@ -17,10 +17,13 @@ #define LOG_NDEBUG 0 #define LOG_TAG "ClientManagerTest" #include <binder/ActivityManager.h> #include "../utils/ClientManager.h" #include <gtest/gtest.h> using namespace android::resource_policy; using namespace android; struct TestClient { TestClient(int id, int32_t cost, const std::set<int>& conflictingKeys, int32_t ownerId, Loading Loading @@ -59,13 +62,15 @@ TEST(ClientManagerTest, SingleOwnerMultipleCamera) { TestClientManager cm; TestClient cam0Client(/*ID*/0, /*cost*/100, /*conflicts*/{1}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam0Desc = makeDescFromTestClient(cam0Client); auto evicted = cm.addAndEvict(cam0Desc); ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty"; TestClient cam1Client(/*ID*/1, /*cost*/100, /*conflicts*/{0}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam1Desc = makeDescFromTestClient(cam1Client); // 1. Check with conflicting devices, new client would be evicted Loading @@ -76,13 +81,15 @@ TEST(ClientManagerTest, SingleOwnerMultipleCamera) { cm.removeAll(); TestClient cam2Client(/*ID*/2, /*cost*/100, /*conflicts*/{}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam2Desc = makeDescFromTestClient(cam2Client); evicted = cm.addAndEvict(cam2Desc); ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty"; TestClient cam3Client(/*ID*/3, /*cost*/100, /*conflicts*/{}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam3Desc = makeDescFromTestClient(cam3Client); // 2. Check without conflicting devices, the pre-existing client won't be evicted Loading @@ -97,12 +104,42 @@ TEST(ClientManagerTest, SingleOwnerMultipleCamera) { ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty"; TestClient cam0ClientNew(/*ID*/0, /*cost*/100, /*conflicts*/{1}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam0DescNew = makeDescFromTestClient(cam0ClientNew); wouldBeEvicted = cm.wouldEvict(cam0DescNew); // 3. Check opening the same camera twice will evict the older client ASSERT_EQ(wouldBeEvicted.size(), 1u) << "Evicted list length must be 1"; ASSERT_EQ(wouldBeEvicted[0], cam0Desc) << "cam0 (old) must be evicted"; } // 4. Check that an invalid client (dead process) will be evicted cm.removeAll(); TestClient camDeadClient(/*ID*/ 0, /*cost*/100, /*conflicts*/{}, /*ownerId*/ 1000, INVALID_ADJ, ActivityManager::PROCESS_STATE_NONEXISTENT, /*isVendorClient*/ false); auto camDeadDesc = makeDescFromTestClient(camDeadClient); evicted = cm.addAndEvict(camDeadDesc); wouldBeEvicted = cm.wouldEvict(cam0Desc); ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty"; ASSERT_EQ(wouldBeEvicted.size(), 1u) << "Evicted list length must be 1"; ASSERT_EQ(wouldBeEvicted[0], camDeadDesc) << "dead cam must be evicted"; // 5. Check that a more important client will win TestClient cam0ForegroundClient(/*ID*/0, /*cost*/100, /*conflicts*/{1}, /*ownerId*/ 1000, FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam0FgDesc = makeDescFromTestClient(cam0ForegroundClient); cm.removeAll(); evicted = cm.addAndEvict(cam0Desc); wouldBeEvicted = cm.wouldEvict(cam0FgDesc); ASSERT_EQ(evicted.size(), 0u); ASSERT_EQ(wouldBeEvicted.size(), 1u); ASSERT_EQ(wouldBeEvicted[0],cam0Desc) << "less important cam0 must be evicted"; } services/camera/libcameraservice/utils/ClientManager.h +29 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,31 @@ namespace android { namespace resource_policy { // Values from frameworks/base/services/core/java/com/android/server/am/ProcessList.java const int32_t INVALID_ADJ = -10000; const int32_t UNKNOWN_ADJ = 1001; const int32_t CACHED_APP_MAX_ADJ = 999; const int32_t CACHED_APP_MIN_ADJ = 900; const int32_t CACHED_APP_LMK_FIRST_ADJ = 950; const int32_t CACHED_APP_IMPORTANCE_LEVELS = 5; const int32_t SERVICE_B_ADJ = 800; const int32_t PREVIOUS_APP_ADJ = 700; const int32_t HOME_APP_ADJ = 600; const int32_t SERVICE_ADJ = 500; const int32_t HEAVY_WEIGHT_APP_ADJ = 400; const int32_t BACKUP_APP_ADJ = 300; const int32_t PERCEPTIBLE_LOW_APP_ADJ = 250; const int32_t PERCEPTIBLE_MEDIUM_APP_ADJ = 225; const int32_t PERCEPTIBLE_APP_ADJ = 200; const int32_t VISIBLE_APP_ADJ = 100; const int32_t VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1; const int32_t PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50; const int32_t FOREGROUND_APP_ADJ = 0; const int32_t PERSISTENT_SERVICE_ADJ = -700; const int32_t PERSISTENT_PROC_ADJ = -800; const int32_t SYSTEM_ADJ = -900; const int32_t NATIVE_ADJ = -1000; class ClientPriority { public: /** Loading @@ -40,7 +65,9 @@ public: * hwbinder thread. */ ClientPriority(int32_t score, int32_t state, bool isVendorClient) : mScore(score), mState(state), mIsVendorClient(isVendorClient) { } mScore((score == INVALID_ADJ) ? UNKNOWN_ADJ : score), mState(state), mIsVendorClient(isVendorClient) { } int32_t getScore() const { return mScore; } int32_t getState() const { return mState; } Loading @@ -50,7 +77,7 @@ public: // construction. Otherwise, it can get reset each time cameraserver // queries ActivityManagerService for oom_adj scores / states . if (!mIsVendorClient) { mScore = score; mScore = (score == INVALID_ADJ) ? UNKNOWN_ADJ : score; } } Loading Loading
services/camera/libcameraservice/CameraService.cpp +3 −4 Original line number Diff line number Diff line Loading @@ -128,10 +128,9 @@ static const String16 static const String16 sCameraOpenCloseListenerPermission( "android.permission.CAMERA_OPEN_CLOSE_LISTENER"); // Matches with PERCEPTIBLE_APP_ADJ in ProcessList.java static constexpr int32_t kVendorClientScore = 200; // Matches with PROCESS_STATE_PERSISTENT_UI in ActivityManager.java static constexpr int32_t kVendorClientState = 1; static constexpr int32_t kVendorClientScore = resource_policy::PERCEPTIBLE_APP_ADJ; static constexpr int32_t kVendorClientState = ActivityManager::PROCESS_STATE_PERSISTENT_UI; const String8 CameraService::kOfflineDevice("offline-"); CameraService::CameraService() : Loading
services/camera/libcameraservice/tests/ClientManagerTest.cpp +43 −6 Original line number Diff line number Diff line Loading @@ -17,10 +17,13 @@ #define LOG_NDEBUG 0 #define LOG_TAG "ClientManagerTest" #include <binder/ActivityManager.h> #include "../utils/ClientManager.h" #include <gtest/gtest.h> using namespace android::resource_policy; using namespace android; struct TestClient { TestClient(int id, int32_t cost, const std::set<int>& conflictingKeys, int32_t ownerId, Loading Loading @@ -59,13 +62,15 @@ TEST(ClientManagerTest, SingleOwnerMultipleCamera) { TestClientManager cm; TestClient cam0Client(/*ID*/0, /*cost*/100, /*conflicts*/{1}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam0Desc = makeDescFromTestClient(cam0Client); auto evicted = cm.addAndEvict(cam0Desc); ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty"; TestClient cam1Client(/*ID*/1, /*cost*/100, /*conflicts*/{0}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam1Desc = makeDescFromTestClient(cam1Client); // 1. Check with conflicting devices, new client would be evicted Loading @@ -76,13 +81,15 @@ TEST(ClientManagerTest, SingleOwnerMultipleCamera) { cm.removeAll(); TestClient cam2Client(/*ID*/2, /*cost*/100, /*conflicts*/{}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam2Desc = makeDescFromTestClient(cam2Client); evicted = cm.addAndEvict(cam2Desc); ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty"; TestClient cam3Client(/*ID*/3, /*cost*/100, /*conflicts*/{}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam3Desc = makeDescFromTestClient(cam3Client); // 2. Check without conflicting devices, the pre-existing client won't be evicted Loading @@ -97,12 +104,42 @@ TEST(ClientManagerTest, SingleOwnerMultipleCamera) { ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty"; TestClient cam0ClientNew(/*ID*/0, /*cost*/100, /*conflicts*/{1}, /*ownerId*/ 1000, /*score*/50, /*state*/ 1, /*isVendorClient*/ false); /*ownerId*/ 1000, PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam0DescNew = makeDescFromTestClient(cam0ClientNew); wouldBeEvicted = cm.wouldEvict(cam0DescNew); // 3. Check opening the same camera twice will evict the older client ASSERT_EQ(wouldBeEvicted.size(), 1u) << "Evicted list length must be 1"; ASSERT_EQ(wouldBeEvicted[0], cam0Desc) << "cam0 (old) must be evicted"; } // 4. Check that an invalid client (dead process) will be evicted cm.removeAll(); TestClient camDeadClient(/*ID*/ 0, /*cost*/100, /*conflicts*/{}, /*ownerId*/ 1000, INVALID_ADJ, ActivityManager::PROCESS_STATE_NONEXISTENT, /*isVendorClient*/ false); auto camDeadDesc = makeDescFromTestClient(camDeadClient); evicted = cm.addAndEvict(camDeadDesc); wouldBeEvicted = cm.wouldEvict(cam0Desc); ASSERT_EQ(evicted.size(), 0u) << "Evicted list must be empty"; ASSERT_EQ(wouldBeEvicted.size(), 1u) << "Evicted list length must be 1"; ASSERT_EQ(wouldBeEvicted[0], camDeadDesc) << "dead cam must be evicted"; // 5. Check that a more important client will win TestClient cam0ForegroundClient(/*ID*/0, /*cost*/100, /*conflicts*/{1}, /*ownerId*/ 1000, FOREGROUND_APP_ADJ, ActivityManager::PROCESS_STATE_PERSISTENT_UI, /*isVendorClient*/ false); auto cam0FgDesc = makeDescFromTestClient(cam0ForegroundClient); cm.removeAll(); evicted = cm.addAndEvict(cam0Desc); wouldBeEvicted = cm.wouldEvict(cam0FgDesc); ASSERT_EQ(evicted.size(), 0u); ASSERT_EQ(wouldBeEvicted.size(), 1u); ASSERT_EQ(wouldBeEvicted[0],cam0Desc) << "less important cam0 must be evicted"; }
services/camera/libcameraservice/utils/ClientManager.h +29 −2 Original line number Diff line number Diff line Loading @@ -31,6 +31,31 @@ namespace android { namespace resource_policy { // Values from frameworks/base/services/core/java/com/android/server/am/ProcessList.java const int32_t INVALID_ADJ = -10000; const int32_t UNKNOWN_ADJ = 1001; const int32_t CACHED_APP_MAX_ADJ = 999; const int32_t CACHED_APP_MIN_ADJ = 900; const int32_t CACHED_APP_LMK_FIRST_ADJ = 950; const int32_t CACHED_APP_IMPORTANCE_LEVELS = 5; const int32_t SERVICE_B_ADJ = 800; const int32_t PREVIOUS_APP_ADJ = 700; const int32_t HOME_APP_ADJ = 600; const int32_t SERVICE_ADJ = 500; const int32_t HEAVY_WEIGHT_APP_ADJ = 400; const int32_t BACKUP_APP_ADJ = 300; const int32_t PERCEPTIBLE_LOW_APP_ADJ = 250; const int32_t PERCEPTIBLE_MEDIUM_APP_ADJ = 225; const int32_t PERCEPTIBLE_APP_ADJ = 200; const int32_t VISIBLE_APP_ADJ = 100; const int32_t VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1; const int32_t PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50; const int32_t FOREGROUND_APP_ADJ = 0; const int32_t PERSISTENT_SERVICE_ADJ = -700; const int32_t PERSISTENT_PROC_ADJ = -800; const int32_t SYSTEM_ADJ = -900; const int32_t NATIVE_ADJ = -1000; class ClientPriority { public: /** Loading @@ -40,7 +65,9 @@ public: * hwbinder thread. */ ClientPriority(int32_t score, int32_t state, bool isVendorClient) : mScore(score), mState(state), mIsVendorClient(isVendorClient) { } mScore((score == INVALID_ADJ) ? UNKNOWN_ADJ : score), mState(state), mIsVendorClient(isVendorClient) { } int32_t getScore() const { return mScore; } int32_t getState() const { return mState; } Loading @@ -50,7 +77,7 @@ public: // construction. Otherwise, it can get reset each time cameraserver // queries ActivityManagerService for oom_adj scores / states . if (!mIsVendorClient) { mScore = score; mScore = (score == INVALID_ADJ) ? UNKNOWN_ADJ : score; } } Loading