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

Commit 1d667a23 authored by Neharika Jali's avatar Neharika Jali
Browse files

Periodically free cache below high storage threshold

Bug: 203650385
Test: atest installd_cache_test
Ignore-AOSP-First: This CL is to be submitted in a topic aimed
for T release
Change-Id: Ia01ab02a77b6365585fafc974d2c68349b5e9e62
parent 0e54231f
Loading
Loading
Loading
Loading
+26 −17
Original line number Diff line number Diff line
@@ -1353,6 +1353,7 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string>
    const char* uuid_ = uuid ? uuid->c_str() : nullptr;
    auto data_path = create_data_path(uuid_);
    auto noop = (flags & FLAG_FREE_CACHE_NOOP);
    auto defy_target = (flags & FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES);

    int64_t free = data_disk_free(data_path);
    if (free < 0) {
@@ -1361,12 +1362,14 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string>

    int64_t cleared = 0;
    int64_t needed = targetFreeBytes - free;
    if (!defy_target) {
        LOG(DEBUG) << "Device " << data_path << " has " << free << " free; requested "
                << targetFreeBytes << "; needed " << needed;

        if (free >= targetFreeBytes) {
            return ok();
        }
    }

    if (flags & FLAG_FREE_CACHE_V2) {
        // This new cache strategy fairly removes files from UIDs by deleting
@@ -1479,6 +1482,7 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string>
                cleared += item->size;
            }

            if (!defy_target) {
                // Verify that we're actually done before bailing, since sneaky
                // apps might be using hardlinks
                if (needed <= 0) {
@@ -1491,12 +1495,14 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string>
                    }
                }
            }
        }
        ATRACE_END();

    } else {
        return error("Legacy cache logic no longer supported");
    }

    if (!defy_target) {
        free = data_disk_free(data_path);
        if (free >= targetFreeBytes) {
            return ok();
@@ -1504,6 +1510,9 @@ binder::Status InstalldNativeService::freeCache(const std::optional<std::string>
            return error(StringPrintf("Failed to free up %" PRId64 " on %s; final free space %" PRId64,
                    targetFreeBytes, data_path.c_str(), free));
        }
    } else {
        return ok();
    }
}

binder::Status InstalldNativeService::rmdex(const std::string& codePath,
+2 −0
Original line number Diff line number Diff line
@@ -138,6 +138,8 @@ interface IInstalld {
    const int FLAG_FREE_CACHE_V2 = 0x100;
    const int FLAG_FREE_CACHE_V2_DEFY_QUOTA = 0x200;
    const int FLAG_FREE_CACHE_NOOP = 0x400;
    // Set below flag to clear cache irrespective of target free bytes required
    const int FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES = 0x800;

    const int FLAG_USE_QUOTA = 0x1000;
    const int FLAG_FORCE = 0x2000;
+30 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ constexpr int64_t kTbInBytes = 1024 * kGbInBytes;

#define FLAG_FREE_CACHE_V2 InstalldNativeService::FLAG_FREE_CACHE_V2
#define FLAG_FREE_CACHE_V2_DEFY_QUOTA InstalldNativeService::FLAG_FREE_CACHE_V2_DEFY_QUOTA
#define FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES InstalldNativeService::FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES

int get_property(const char *key, char *value, const char *default_value) {
    return property_get(key, value, default_value);
@@ -180,6 +181,35 @@ TEST_F(CacheTest, FreeCache_NonAggressive) {
    EXPECT_EQ(0, exists("com.example/cache/foo/two"));
}

TEST_F(CacheTest, FreeCache_DefyTargetFreeBytes) {
    LOG(INFO) << "FreeCache_DefyTargetFreeBytes";

    mkdir("com.example");
    touch("com.example/normal", 1 * kMbInBytes, 60);
    mkdir("com.example/cache");
    mkdir("com.example/cache/foo");
    touch("com.example/cache/foo/one", 65 * kMbInBytes, 60);
    touch("com.example/cache/foo/two", 2 * kMbInBytes, 120);

    EXPECT_EQ(0, exists("com.example/normal"));
    EXPECT_EQ(0, exists("com.example/cache/foo/one"));
    EXPECT_EQ(0, exists("com.example/cache/foo/two"));

    service->freeCache(testUuid, kMbInBytes, FLAG_FREE_CACHE_V2
            | FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES);

    EXPECT_EQ(0, exists("com.example/normal"));
    EXPECT_EQ(-1, exists("com.example/cache/foo/one"));
    EXPECT_EQ(0, exists("com.example/cache/foo/two"));

    service->freeCache(testUuid, kMbInBytes, FLAG_FREE_CACHE_V2
            | FLAG_FREE_CACHE_DEFY_TARGET_FREE_BYTES);

    EXPECT_EQ(0, exists("com.example/normal"));
    EXPECT_EQ(-1, exists("com.example/cache/foo/one"));
    EXPECT_EQ(0, exists("com.example/cache/foo/two"));
}

TEST_F(CacheTest, FreeCache_Age) {
    LOG(INFO) << "FreeCache_Age";