Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb572630 authored by Eino-Ville Talvala's avatar Eino-Ville Talvala Committed by Android (Google) Code Review
Browse files

Merge "Camera: Fix handling of dead processes for arbitration" into sc-dev

parents 9c8eb940 7c602c35
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -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() :
+43 −6
Original line number Diff line number Diff line
@@ -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,
@@ -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
@@ -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
@@ -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";
}
+29 −2
Original line number Diff line number Diff line
@@ -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:
    /**
@@ -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; }
@@ -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;
        }
    }