1871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey/*
2871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey * Copyright (C) 2017 The Android Open Source Project
3871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey *
4871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License");
5871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey * you may not use this file except in compliance with the License.
6871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey * You may obtain a copy of the License at
7871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey *
8871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey *      http://www.apache.org/licenses/LICENSE-2.0
9871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey *
10871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey * Unless required by applicable law or agreed to in writing, software
11871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS,
12871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey * See the License for the specific language governing permissions and
14871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey * limitations under the License.
15871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey */
16871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
17871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include <stdlib.h>
18871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include <string.h>
19871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include <sys/statvfs.h>
20871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include <sys/xattr.h>
21871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
22871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include <android-base/logging.h>
23871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include <android-base/stringprintf.h>
24871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include <cutils/properties.h>
25871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include <gtest/gtest.h>
26871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
27871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include "InstalldNativeService.h"
28871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include "globals.h"
29871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey#include "utils.h"
30871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
31871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyusing android::base::StringPrintf;
32871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
33871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeynamespace android {
34871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeynamespace installd {
35871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
36871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyconstexpr const char* kTestUuid = "TEST";
37871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
38871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyconstexpr int64_t kKbInBytes = 1024;
39871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyconstexpr int64_t kMbInBytes = 1024 * kKbInBytes;
40871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyconstexpr int64_t kGbInBytes = 1024 * kMbInBytes;
41871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyconstexpr int64_t kTbInBytes = 1024 * kGbInBytes;
42871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
43871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystatic constexpr int FLAG_FREE_CACHE_V2 = 1 << 13;
44871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystatic constexpr int FLAG_FREE_CACHE_V2_DEFY_QUOTA = 1 << 14;
45871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
46871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyint get_property(const char *key, char *value, const char *default_value) {
47871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    return property_get(key, value, default_value);
48871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
49871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
50871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeybool calculate_oat_file_path(char path[PKG_PATH_MAX] ATTRIBUTE_UNUSED,
51871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        const char *oat_dir ATTRIBUTE_UNUSED,
52871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        const char *apk_path ATTRIBUTE_UNUSED,
53871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        const char *instruction_set ATTRIBUTE_UNUSED) {
54871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    return false;
55871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
56871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
57871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeybool calculate_odex_file_path(char path[PKG_PATH_MAX] ATTRIBUTE_UNUSED,
58871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        const char *apk_path ATTRIBUTE_UNUSED,
59871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        const char *instruction_set ATTRIBUTE_UNUSED) {
60871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    return false;
61871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
62871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
63871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeybool create_cache_path(char path[PKG_PATH_MAX] ATTRIBUTE_UNUSED,
64871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        const char *src ATTRIBUTE_UNUSED,
65871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        const char *instruction_set ATTRIBUTE_UNUSED) {
66871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    return false;
67871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
68871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
69871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystatic void mkdir(const char* path) {
70871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    const char* fullPath = StringPrintf("/data/local/tmp/user/0/%s", path).c_str();
71871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    ::mkdir(fullPath, 0755);
72871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
73871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
74871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystatic void touch(const char* path, int len, int time) {
75871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    const char* fullPath = StringPrintf("/data/local/tmp/user/0/%s", path).c_str();
76871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    int fd = ::open(fullPath, O_RDWR | O_CREAT, 0644);
77871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    ::fallocate(fd, 0, 0, len);
78871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    ::close(fd);
79871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    struct utimbuf times;
80871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    times.actime = times.modtime = std::time(0) + time;
81871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    ::utime(fullPath, &times);
82871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
83871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
84871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystatic int exists(const char* path) {
85871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    const char* fullPath = StringPrintf("/data/local/tmp/user/0/%s", path).c_str();
86871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    return ::access(fullPath, F_OK);
87871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
88871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
89871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystatic int64_t size(const char* path) {
90871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    const char* fullPath = StringPrintf("/data/local/tmp/user/0/%s", path).c_str();
91871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    struct stat buf;
92871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    if (!stat(fullPath, &buf)) {
93871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        return buf.st_size;
94871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    } else {
95871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        return -1;
96871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    }
97871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
98871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
99871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystatic int64_t free() {
100871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    struct statvfs buf;
101871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    if (!statvfs("/data/local/tmp", &buf)) {
102a836c472f017f09cf16fa68176df461a4958d22aJeff Sharkey        return buf.f_bavail * buf.f_frsize;
103871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    } else {
104ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey        PLOG(ERROR) << "Failed to statvfs";
105871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        return -1;
106871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    }
107871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
108871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
109871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeystatic void setxattr(const char* path, const char* key) {
110871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    const char* fullPath = StringPrintf("/data/local/tmp/user/0/%s", path).c_str();
111871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    ::setxattr(fullPath, key, "", 0, 0);
112871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
113871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
114871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyclass CacheTest : public testing::Test {
115871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkeyprotected:
116871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    InstalldNativeService* service;
117871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    std::unique_ptr<std::string> testUuid;
118871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
119871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    virtual void SetUp() {
120871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        setenv("ANDROID_LOG_TAGS", "*:v", 1);
121871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        android::base::InitLogging(nullptr);
122871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
123871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        service = new InstalldNativeService();
124871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        testUuid = std::make_unique<std::string>();
125871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        *testUuid = std::string(kTestUuid);
126871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        system("mkdir -p /data/local/tmp/user/0");
127871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    }
128871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
129871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    virtual void TearDown() {
130871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        delete service;
131871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey        system("rm -rf /data/local/tmp/user");
132871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    }
133871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey};
134871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
135871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff SharkeyTEST_F(CacheTest, FreeCache_All) {
136ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    LOG(INFO) << "FreeCache_All";
137ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey
138871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example");
139871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/normal", 1 * kMbInBytes, 60);
140871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache");
141871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache/foo");
142871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/foo/one", 1 * kMbInBytes, 60);
143871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/foo/two", 2 * kMbInBytes, 120);
144871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
145871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/normal"));
146871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/cache/foo/one"));
147871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/cache/foo/two"));
148871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
14928443c23fb22fd9cc07117842c4c2155e3fde5fcJeff Sharkey    service->freeCache(testUuid, kTbInBytes, 0,
150871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey            FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA);
151871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
152871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/normal"));
153871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(-1, exists("com.example/cache/foo/one"));
154871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(-1, exists("com.example/cache/foo/two"));
155871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
156871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
157871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff SharkeyTEST_F(CacheTest, FreeCache_Age) {
158ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    LOG(INFO) << "FreeCache_Age";
159ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey
160871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example");
161871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache");
162871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache/foo");
163871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/foo/one", kMbInBytes, 60);
164871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/foo/two", kMbInBytes, 120);
165871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
16628443c23fb22fd9cc07117842c4c2155e3fde5fcJeff Sharkey    service->freeCache(testUuid, free() + kKbInBytes, 0,
167871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey            FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA);
168871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
169871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(-1, exists("com.example/cache/foo/one"));
170871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/cache/foo/two"));
171871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
17228443c23fb22fd9cc07117842c4c2155e3fde5fcJeff Sharkey    service->freeCache(testUuid, free() + kKbInBytes, 0,
173871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey            FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA);
174871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
175871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(-1, exists("com.example/cache/foo/one"));
176871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(-1, exists("com.example/cache/foo/two"));
177871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
178871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
179871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff SharkeyTEST_F(CacheTest, FreeCache_Tombstone) {
180ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    LOG(INFO) << "FreeCache_Tombstone";
181ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey
182871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example");
183871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache");
184871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache/foo");
185871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/foo/foo1", 1 * kMbInBytes, 60);
186871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/foo/foo2", 1 * kMbInBytes, 60);
187871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache/bar");
188871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/bar/bar1", 2 * kMbInBytes, 120);
189871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/bar/bar2", 2 * kMbInBytes, 120);
190871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
191871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    setxattr("com.example/cache/bar", "user.cache_tombstone");
192871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
193871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/cache/foo/foo1"));
194871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/cache/foo/foo2"));
195871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/cache/bar/bar1"));
196871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/cache/bar/bar2"));
197871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(2 * kMbInBytes, size("com.example/cache/bar/bar1"));
198871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(2 * kMbInBytes, size("com.example/cache/bar/bar2"));
199871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
20028443c23fb22fd9cc07117842c4c2155e3fde5fcJeff Sharkey    service->freeCache(testUuid, kTbInBytes, 0,
201871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey            FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA);
202871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
203871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(-1, exists("com.example/cache/foo/foo1"));
204871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(-1, exists("com.example/cache/foo/foo2"));
205871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/cache/bar/bar1"));
206871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, exists("com.example/cache/bar/bar2"));
207871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/bar/bar1"));
208871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/bar/bar2"));
209871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
210871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
211ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff SharkeyTEST_F(CacheTest, FreeCache_Group) {
212ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    LOG(INFO) << "FreeCache_Group";
213ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey
214871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example");
215871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache");
216871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache/foo");
217871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/foo/foo1", 1 * kMbInBytes, 60);
218871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/foo/foo2", 1 * kMbInBytes, 120);
219871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
220ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    setxattr("com.example/cache/foo", "user.cache_group");
221871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
22228443c23fb22fd9cc07117842c4c2155e3fde5fcJeff Sharkey    service->freeCache(testUuid, free() + kKbInBytes, 0,
223871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey            FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA);
224871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
225871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(-1, exists("com.example/cache/foo/foo1"));
226871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(-1, exists("com.example/cache/foo/foo2"));
227871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
228871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
229ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff SharkeyTEST_F(CacheTest, FreeCache_GroupTombstone) {
230ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    LOG(INFO) << "FreeCache_GroupTombstone";
231871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
232871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example");
233871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache");
234871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
235871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    // this dir must look really old for some reason?
236ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    mkdir("com.example/cache/group");
237ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/group/file1", kMbInBytes, 120);
238ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/group/file2", kMbInBytes, 120);
239ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    mkdir("com.example/cache/group/dir");
240ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/group/dir/file1", kMbInBytes, 120);
241ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/group/dir/file2", kMbInBytes, 120);
242ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    mkdir("com.example/cache/group/tomb");
243ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/group/tomb/file1", kMbInBytes, 120);
244ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/group/tomb/file2", kMbInBytes, 120);
245ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    mkdir("com.example/cache/group/tomb/dir");
246ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/group/tomb/dir/file1", kMbInBytes, 120);
247ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/group/tomb/dir/file2", kMbInBytes, 120);
248871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
249871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache/tomb");
250871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/tomb/file1", kMbInBytes, 240);
251871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/tomb/file2", kMbInBytes, 240);
252871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    mkdir("com.example/cache/tomb/dir");
253871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/tomb/dir/file1", kMbInBytes, 240);
254871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    touch("com.example/cache/tomb/dir/file2", kMbInBytes, 240);
255ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    mkdir("com.example/cache/tomb/group");
256ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/tomb/group/file1", kMbInBytes, 60);
257ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/tomb/group/file2", kMbInBytes, 60);
258ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    mkdir("com.example/cache/tomb/group/dir");
259ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/tomb/group/dir/file1", kMbInBytes, 60);
260ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    touch("com.example/cache/tomb/group/dir/file2", kMbInBytes, 60);
261ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey
262ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    setxattr("com.example/cache/group", "user.cache_group");
263ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    setxattr("com.example/cache/group/tomb", "user.cache_tombstone");
264871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    setxattr("com.example/cache/tomb", "user.cache_tombstone");
265ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    setxattr("com.example/cache/tomb/group", "user.cache_group");
266871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
26728443c23fb22fd9cc07117842c4c2155e3fde5fcJeff Sharkey    service->freeCache(testUuid, free() + kKbInBytes, 0,
268871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey            FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA);
269871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
270ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/group/file1"));
271ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/group/file2"));
272ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/group/dir/file1"));
273ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/group/dir/file2"));
274ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/file1"));
275ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/file2"));
276ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/dir/file1"));
277ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/group/tomb/dir/file2"));
278871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
279871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1"));
280871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2"));
281871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1"));
282871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2"));
283ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/file1"));
284ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/file2"));
285ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1"));
286ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2"));
287871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
28828443c23fb22fd9cc07117842c4c2155e3fde5fcJeff Sharkey    service->freeCache(testUuid, free() + kKbInBytes, 0,
289871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey            FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA);
290871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
291ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(-1, size("com.example/cache/group/file1"));
292ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(-1, size("com.example/cache/group/file2"));
293ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(-1, size("com.example/cache/group/dir/file1"));
294ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(-1, size("com.example/cache/group/dir/file2"));
295ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/group/tomb/file1"));
296ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/group/tomb/file2"));
297ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file1"));
298ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file2"));
299871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
300871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file1"));
301871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/file2"));
302871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file1"));
303871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(kMbInBytes, size("com.example/cache/tomb/dir/file2"));
304ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/file1"));
305ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/file2"));
306ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1"));
307ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2"));
308871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
30928443c23fb22fd9cc07117842c4c2155e3fde5fcJeff Sharkey    service->freeCache(testUuid, kTbInBytes, 0,
310871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey            FLAG_FREE_CACHE_V2 | FLAG_FREE_CACHE_V2_DEFY_QUOTA);
311871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
312ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(-1, size("com.example/cache/group/file1"));
313ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(-1, size("com.example/cache/group/file2"));
314ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(-1, size("com.example/cache/group/dir/file1"));
315ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(-1, size("com.example/cache/group/dir/file2"));
316ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/group/tomb/file1"));
317ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/group/tomb/file2"));
318ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file1"));
319ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/group/tomb/dir/file2"));
320871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
321871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/file1"));
322871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/file2"));
323871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/dir/file1"));
324871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/dir/file2"));
325ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/file1"));
326ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/file2"));
327ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file1"));
328ed909ae8db2f44ce7fe7003c6fee457f13669702Jeff Sharkey    EXPECT_EQ(0, size("com.example/cache/tomb/group/dir/file2"));
329871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}
330871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey
331871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}  // namespace installd
332871a8f236ef2a055b9955b47a342b2c44c020ef7Jeff Sharkey}  // namespace android
333