1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdlib.h>
18#include <string.h>
19
20#include <gtest/gtest.h>
21
22#include <commands.h>
23#include <globals.h>
24#include <utils.h>
25
26#undef LOG_TAG
27#define LOG_TAG "utils_test"
28
29#define TEST_DATA_DIR "/data/"
30#define TEST_APP_DIR "/data/app/"
31#define TEST_APP_PRIVATE_DIR "/data/app-private/"
32#define TEST_ASEC_DIR "/mnt/asec/"
33#define TEST_EXPAND_DIR "/mnt/expand/"
34
35#define TEST_SYSTEM_DIR1 "/system/app/"
36#define TEST_SYSTEM_DIR2 "/vendor/app/"
37
38#define REALLY_LONG_APP_NAME "com.example." \
39        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
40        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa." \
41        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
42
43#define REALLY_LONG_LEAF_NAME "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
44        "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
45        "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_" \
46        "shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_shared_prefs_"
47
48namespace android {
49namespace installd {
50
51class UtilsTest : public testing::Test {
52protected:
53    virtual void SetUp() {
54        android_app_dir.path = (char*) TEST_APP_DIR;
55        android_app_dir.len = strlen(TEST_APP_DIR);
56
57        android_app_private_dir.path = (char*) TEST_APP_PRIVATE_DIR;
58        android_app_private_dir.len = strlen(TEST_APP_PRIVATE_DIR);
59
60        android_data_dir.path = (char*) TEST_DATA_DIR;
61        android_data_dir.len = strlen(TEST_DATA_DIR);
62
63        android_asec_dir.path = (char*) TEST_ASEC_DIR;
64        android_asec_dir.len = strlen(TEST_ASEC_DIR);
65
66        android_mnt_expand_dir.path = (char*) TEST_EXPAND_DIR;
67        android_mnt_expand_dir.len = strlen(TEST_EXPAND_DIR);
68
69        android_system_dirs.count = 2;
70
71        android_system_dirs.dirs = (dir_rec_t*) calloc(android_system_dirs.count, sizeof(dir_rec_t));
72        android_system_dirs.dirs[0].path = (char*) TEST_SYSTEM_DIR1;
73        android_system_dirs.dirs[0].len = strlen(TEST_SYSTEM_DIR1);
74
75        android_system_dirs.dirs[1].path = (char*) TEST_SYSTEM_DIR2;
76        android_system_dirs.dirs[1].len = strlen(TEST_SYSTEM_DIR2);
77    }
78
79    virtual void TearDown() {
80        free(android_system_dirs.dirs);
81    }
82};
83
84TEST_F(UtilsTest, IsValidApkPath_BadPrefix) {
85    // Bad prefixes directories
86    const char *badprefix1 = "/etc/passwd";
87    EXPECT_EQ(-1, validate_apk_path(badprefix1))
88            << badprefix1 << " should be allowed as a valid path";
89
90    const char *badprefix2 = "../.." TEST_APP_DIR "../../../blah";
91    EXPECT_EQ(-1, validate_apk_path(badprefix2))
92            << badprefix2 << " should be allowed as a valid path";
93
94    const char *badprefix3 = "init.rc";
95    EXPECT_EQ(-1, validate_apk_path(badprefix3))
96            << badprefix3 << " should be allowed as a valid path";
97
98    const char *badprefix4 = "/init.rc";
99    EXPECT_EQ(-1, validate_apk_path(badprefix4))
100            << badprefix4 << " should be allowed as a valid path";
101}
102
103TEST_F(UtilsTest, IsValidApkPath_Internal) {
104    // Internal directories
105    const char *internal1 = TEST_APP_DIR "example.apk";
106    EXPECT_EQ(0, validate_apk_path(internal1))
107            << internal1 << " should be allowed as a valid path";
108
109    // b/16888084
110    const char *path2 = TEST_APP_DIR "example.com/example.apk";
111    EXPECT_EQ(0, validate_apk_path(path2))
112            << path2 << " should be allowed as a valid path";
113
114    const char *badint1 = TEST_APP_DIR "../example.apk";
115    EXPECT_EQ(-1, validate_apk_path(badint1))
116            << badint1 << " should be rejected as a invalid path";
117
118    const char *badint2 = TEST_APP_DIR "/../example.apk";
119    EXPECT_EQ(-1, validate_apk_path(badint2))
120            << badint2 << " should be rejected as a invalid path";
121
122    // Only one subdir should be allowed.
123    const char *bad_path3 = TEST_APP_DIR "example.com/subdir/pkg.apk";
124    EXPECT_EQ(-1, validate_apk_path(bad_path3))
125            << bad_path3 << " should be rejected as a invalid path";
126
127    const char *bad_path4 = TEST_APP_DIR "example.com/subdir/../pkg.apk";
128    EXPECT_EQ(-1, validate_apk_path(bad_path4))
129            << bad_path4 << " should be rejected as a invalid path";
130
131    const char *bad_path5 = TEST_APP_DIR "example.com1/../example.com2/pkg.apk";
132    EXPECT_EQ(-1, validate_apk_path(bad_path5))
133            << bad_path5 << " should be rejected as a invalid path";
134}
135
136TEST_F(UtilsTest, IsValidApkPath_Private) {
137    // Internal directories
138    const char *private1 = TEST_APP_PRIVATE_DIR "example.apk";
139    EXPECT_EQ(0, validate_apk_path(private1))
140            << private1 << " should be allowed as a valid path";
141
142    // b/16888084
143    const char *path2 = TEST_APP_DIR "example.com/example.apk";
144    EXPECT_EQ(0, validate_apk_path(path2))
145            << path2 << " should be allowed as a valid path";
146
147    const char *badpriv1 = TEST_APP_PRIVATE_DIR "../example.apk";
148    EXPECT_EQ(-1, validate_apk_path(badpriv1))
149            << badpriv1 << " should be rejected as a invalid path";
150
151    const char *badpriv2 = TEST_APP_PRIVATE_DIR "/../example.apk";
152    EXPECT_EQ(-1, validate_apk_path(badpriv2))
153            << badpriv2 << " should be rejected as a invalid path";
154
155    // Only one subdir should be allowed.
156    const char *bad_path3 = TEST_APP_PRIVATE_DIR "example.com/subdir/pkg.apk";
157    EXPECT_EQ(-1, validate_apk_path(bad_path3))
158            << bad_path3 << " should be rejected as a invalid path";
159
160    const char *bad_path4 = TEST_APP_PRIVATE_DIR "example.com/subdir/../pkg.apk";
161    EXPECT_EQ(-1, validate_apk_path(bad_path4))
162            << bad_path4 << " should be rejected as a invalid path";
163
164    const char *bad_path5 = TEST_APP_PRIVATE_DIR "example.com1/../example.com2/pkg.apk";
165    EXPECT_EQ(-1, validate_apk_path(bad_path5))
166            << bad_path5 << " should be rejected as a invalid path";
167}
168
169
170TEST_F(UtilsTest, IsValidApkPath_AsecGood1) {
171    const char *asec1 = TEST_ASEC_DIR "example.apk";
172    EXPECT_EQ(0, validate_apk_path(asec1))
173            << asec1 << " should be allowed as a valid path";
174}
175
176TEST_F(UtilsTest, IsValidApkPath_AsecGood2) {
177    const char *asec2 = TEST_ASEC_DIR "com.example.asec/pkg.apk";
178    EXPECT_EQ(0, validate_apk_path(asec2))
179            << asec2 << " should be allowed as a valid path";
180}
181
182TEST_F(UtilsTest, IsValidApkPath_EscapeFail) {
183    const char *badasec1 = TEST_ASEC_DIR "../example.apk";
184    EXPECT_EQ(-1, validate_apk_path(badasec1))
185            << badasec1 << " should be rejected as a invalid path";
186}
187
188TEST_F(UtilsTest, IsValidApkPath_DoubleSlashFail) {
189    const char *badasec2 = TEST_ASEC_DIR "com.example.asec//pkg.apk";
190    EXPECT_EQ(-1, validate_apk_path(badasec2))
191            << badasec2 << " should be rejected as a invalid path";
192}
193
194TEST_F(UtilsTest, IsValidApkPath_SubdirEscapeFail) {
195    const char *badasec3 = TEST_ASEC_DIR "com.example.asec/../../../pkg.apk";
196    EXPECT_EQ(-1, validate_apk_path(badasec3))
197            << badasec3  << " should be rejected as a invalid path";
198}
199
200TEST_F(UtilsTest, IsValidApkPath_SlashEscapeFail) {
201    const char *badasec4 = TEST_ASEC_DIR "/../example.apk";
202    EXPECT_EQ(-1, validate_apk_path(badasec4))
203            << badasec4 << " should be rejected as a invalid path";
204}
205
206TEST_F(UtilsTest, IsValidApkPath_CrazyDirFail) {
207    const char *badasec5 = TEST_ASEC_DIR ".//../..";
208    EXPECT_EQ(-1, validate_apk_path(badasec5))
209            << badasec5 << " should be rejected as a invalid path";
210}
211
212TEST_F(UtilsTest, IsValidApkPath_SubdirEscapeSingleFail) {
213    const char *badasec6 = TEST_ASEC_DIR "com.example.asec/../pkg.apk";
214    EXPECT_EQ(-1, validate_apk_path(badasec6))
215            << badasec6 << " should be rejected as a invalid path";
216}
217
218TEST_F(UtilsTest, IsValidApkPath_TwoSubdirFail) {
219    const char *badasec7 = TEST_ASEC_DIR "com.example.asec/subdir1/pkg.apk";
220    EXPECT_EQ(-1, validate_apk_path(badasec7))
221            << badasec7 << " should be rejected as a invalid path";
222}
223
224TEST_F(UtilsTest, CheckSystemApp_Dir1) {
225    const char *sysapp1 = TEST_SYSTEM_DIR1 "Voice.apk";
226    EXPECT_EQ(0, validate_system_app_path(sysapp1))
227            << sysapp1 << " should be allowed as a system path";
228}
229
230TEST_F(UtilsTest, CheckSystemApp_Dir2) {
231    const char *sysapp2 = TEST_SYSTEM_DIR2 "com.example.myapp.apk";
232    EXPECT_EQ(0, validate_system_app_path(sysapp2))
233            << sysapp2 << " should be allowed as a system path";
234}
235
236TEST_F(UtilsTest, CheckSystemApp_EscapeFail) {
237    const char *badapp1 = TEST_SYSTEM_DIR1 "../com.example.apk";
238    EXPECT_EQ(-1, validate_system_app_path(badapp1))
239            << badapp1 << " should be rejected not a system path";
240}
241
242TEST_F(UtilsTest, CheckSystemApp_DoubleEscapeFail) {
243    const char *badapp2 = TEST_SYSTEM_DIR2 "/../../com.example.apk";
244    EXPECT_EQ(-1, validate_system_app_path(badapp2))
245            << badapp2 << " should be rejected not a system path";
246}
247
248TEST_F(UtilsTest, CheckSystemApp_BadPathEscapeFail) {
249    const char *badapp3 = TEST_APP_DIR "/../../com.example.apk";
250    EXPECT_EQ(-1, validate_system_app_path(badapp3))
251            << badapp3 << " should be rejected not a system path";
252}
253
254TEST_F(UtilsTest, CheckSystemApp_Subdir) {
255    const char *sysapp = TEST_SYSTEM_DIR1 "com.example/com.example.apk";
256    EXPECT_EQ(0, validate_system_app_path(sysapp))
257            << sysapp << " should be allowed as a system path";
258
259    const char *badapp = TEST_SYSTEM_DIR1 "com.example/subdir/com.example.apk";
260    EXPECT_EQ(-1, validate_system_app_path(badapp))
261            << badapp << " should be rejected not a system path";
262
263    const char *badapp1 = TEST_SYSTEM_DIR1 "com.example/subdir/../com.example.apk";
264    EXPECT_EQ(-1, validate_system_app_path(badapp1))
265            << badapp1 << " should be rejected not a system path";
266
267    const char *badapp2 = TEST_SYSTEM_DIR1 "com.example1/../com.example2/com.example.apk";
268    EXPECT_EQ(-1, validate_system_app_path(badapp2))
269            << badapp2 << " should be rejected not a system path";
270}
271
272TEST_F(UtilsTest, GetPathFromString_NullPathFail) {
273    dir_rec_t test1;
274    EXPECT_EQ(-1, get_path_from_string(&test1, (const char *) NULL))
275            << "Should not allow NULL as a path.";
276}
277
278TEST_F(UtilsTest, GetPathFromString_EmptyPathFail) {
279    dir_rec_t test1;
280    EXPECT_EQ(-1, get_path_from_string(&test1, ""))
281            << "Should not allow empty paths.";
282}
283
284TEST_F(UtilsTest, GetPathFromString_RelativePathFail) {
285    dir_rec_t test1;
286    EXPECT_EQ(-1, get_path_from_string(&test1, "mnt/asec"))
287            << "Should not allow relative paths.";
288}
289
290TEST_F(UtilsTest, GetPathFromString_NonCanonical) {
291    dir_rec_t test1;
292
293    EXPECT_EQ(0, get_path_from_string(&test1, "/mnt/asec"))
294            << "Should be able to canonicalize directory /mnt/asec";
295    EXPECT_STREQ("/mnt/asec/", test1.path)
296            << "/mnt/asec should be canonicalized to /mnt/asec/";
297    EXPECT_EQ(10, (ssize_t) test1.len)
298            << "path len should be equal to the length of /mnt/asec/ (10)";
299    free(test1.path);
300}
301
302TEST_F(UtilsTest, GetPathFromString_CanonicalPath) {
303    dir_rec_t test3;
304    EXPECT_EQ(0, get_path_from_string(&test3, "/data/app/"))
305            << "Should be able to canonicalize directory /data/app/";
306    EXPECT_STREQ("/data/app/", test3.path)
307            << "/data/app/ should be canonicalized to /data/app/";
308    EXPECT_EQ(10, (ssize_t) test3.len)
309            << "path len should be equal to the length of /data/app/ (10)";
310    free(test3.path);
311}
312
313TEST_F(UtilsTest, CreatePkgPath_LongPkgNameSuccess) {
314    char path[PKG_PATH_MAX];
315
316    // Create long packagename of "aaaaa..."
317    size_t pkgnameSize = PKG_NAME_MAX;
318    char pkgname[pkgnameSize + 1];
319    memset(pkgname, 'a', pkgnameSize);
320    pkgname[pkgnameSize] = '\0';
321
322    EXPECT_EQ(0, create_pkg_path(path, pkgname, "", 0))
323            << "Should successfully be able to create package name.";
324
325    std::string prefix = std::string(TEST_DATA_DIR) + PRIMARY_USER_PREFIX;
326    size_t offset = prefix.length();
327
328    EXPECT_STREQ(pkgname, path + offset)
329             << "Package path should be a really long string of a's";
330}
331
332TEST_F(UtilsTest, CreatePkgPath_LongPkgNameFail) {
333    char path[PKG_PATH_MAX];
334
335    // Create long packagename of "aaaaa..."
336    size_t pkgnameSize = PKG_NAME_MAX + 1;
337    char pkgname[pkgnameSize + 1];
338    memset(pkgname, 'a', pkgnameSize);
339    pkgname[pkgnameSize] = '\0';
340
341    EXPECT_EQ(-1, create_pkg_path(path, pkgname, "", 0))
342            << "Should return error because package name is too long.";
343}
344
345TEST_F(UtilsTest, CreatePkgPath_LongPostfixFail) {
346    char path[PKG_PATH_MAX];
347
348    // Create long packagename of "aaaaa..."
349    size_t postfixSize = PKG_PATH_MAX;
350    char postfix[postfixSize + 1];
351    memset(postfix, 'a', postfixSize);
352    postfix[postfixSize] = '\0';
353
354    EXPECT_EQ(-1, create_pkg_path(path, "com.example.package", postfix, 0))
355            << "Should return error because postfix is too long.";
356}
357
358TEST_F(UtilsTest, CreatePkgPath_PrimaryUser) {
359    char path[PKG_PATH_MAX];
360
361    EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 0))
362            << "Should return error because postfix is too long.";
363
364    std::string p = std::string(TEST_DATA_DIR)
365                    + PRIMARY_USER_PREFIX
366                    + "com.example.package";
367    EXPECT_STREQ(p.c_str(), path)
368            << "Package path should be in /data/data/";
369}
370
371TEST_F(UtilsTest, CreatePkgPath_SecondaryUser) {
372    char path[PKG_PATH_MAX];
373
374    EXPECT_EQ(0, create_pkg_path(path, "com.example.package", "", 1))
375            << "Should successfully create package path.";
376
377    std::string p = std::string(TEST_DATA_DIR)
378                    + SECONDARY_USER_PREFIX
379                    + "1/com.example.package";
380    EXPECT_STREQ(p.c_str(), path)
381            << "Package path should be in /data/user/";
382}
383
384TEST_F(UtilsTest, CreateMovePath_Primary) {
385    char path[PKG_PATH_MAX];
386
387    EXPECT_EQ(0, create_move_path(path, "com.android.test", "shared_prefs", 0))
388            << "Should be able to create move path for primary user";
389
390    EXPECT_STREQ("/data/data/com.android.test/shared_prefs", path)
391            << "Primary user package directory should be created correctly";
392}
393
394TEST_F(UtilsTest, CreateMovePath_Fail_AppTooLong) {
395    char path[PKG_PATH_MAX];
396
397    EXPECT_EQ(-1, create_move_path(path, REALLY_LONG_APP_NAME, "shared_prefs", 0))
398            << "Should fail to create move path for primary user";
399}
400
401TEST_F(UtilsTest, CreateMovePath_Fail_LeafTooLong) {
402    char path[PKG_PATH_MAX];
403
404    EXPECT_EQ(-1, create_move_path(path, "com.android.test", REALLY_LONG_LEAF_NAME, 0))
405            << "Should fail to create move path for primary user";
406}
407
408TEST_F(UtilsTest, CopyAndAppend_Normal) {
409    //int copy_and_append(dir_rec_t* dst, dir_rec_t* src, char* suffix)
410    dir_rec_t dst;
411    dir_rec_t src;
412
413    src.path = (char*) "/data/";
414    src.len = strlen(src.path);
415
416    EXPECT_EQ(0, copy_and_append(&dst, &src, "app/"))
417            << "Should return error because postfix is too long.";
418
419    EXPECT_STREQ("/data/app/", dst.path)
420            << "Appended path should be correct";
421
422    EXPECT_EQ(10, (ssize_t) dst.len)
423            << "Appended path should be length of '/data/app/' (10)";
424}
425
426TEST_F(UtilsTest, AppendAndIncrement_Normal) {
427    size_t dst_size = 10;
428    char dst[dst_size];
429    char *dstp = dst;
430    const char* src = "FOO";
431
432    EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size))
433            << "String should append successfully";
434
435    EXPECT_STREQ("FOO", dst)
436            << "String should append correctly";
437
438    EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size))
439            << "String should append successfully again";
440
441    EXPECT_STREQ("FOOFOO", dst)
442            << "String should append correctly again";
443}
444
445TEST_F(UtilsTest, AppendAndIncrement_TooBig) {
446    size_t dst_size = 5;
447    char dst[dst_size];
448    char *dstp = dst;
449    const char* src = "FOO";
450
451    EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size))
452            << "String should append successfully";
453
454    EXPECT_STREQ("FOO", dst)
455            << "String should append correctly";
456
457    EXPECT_EQ(-1, append_and_increment(&dstp, src, &dst_size))
458            << "String should fail because it's too large to fit";
459}
460
461TEST_F(UtilsTest, CreateDataPath) {
462    EXPECT_EQ("/data", create_data_path(nullptr));
463    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b",
464            create_data_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b"));
465}
466
467TEST_F(UtilsTest, CreateDataAppPath) {
468    EXPECT_EQ("/data/app", create_data_app_path(nullptr));
469
470    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/app",
471            create_data_app_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b"));
472}
473
474TEST_F(UtilsTest, CreateDataUserPath) {
475    EXPECT_EQ("/data/data", create_data_user_ce_path(nullptr, 0));
476    EXPECT_EQ("/data/user/10", create_data_user_ce_path(nullptr, 10));
477
478    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/0",
479            create_data_user_ce_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0));
480    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/10",
481            create_data_user_ce_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10));
482}
483
484TEST_F(UtilsTest, CreateDataMediaPath) {
485    EXPECT_EQ("/data/media/0", create_data_media_path(nullptr, 0));
486    EXPECT_EQ("/data/media/10", create_data_media_path(nullptr, 10));
487
488    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/media/0",
489            create_data_media_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0));
490    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/media/10",
491            create_data_media_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10));
492}
493
494TEST_F(UtilsTest, CreateDataAppPackagePath) {
495    EXPECT_EQ("/data/app/com.example", create_data_app_package_path(nullptr, "com.example"));
496
497    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/app/com.example",
498            create_data_app_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", "com.example"));
499}
500
501TEST_F(UtilsTest, CreateDataUserPackagePath) {
502    EXPECT_EQ("/data/data/com.example", create_data_user_ce_package_path(nullptr, 0, "com.example"));
503    EXPECT_EQ("/data/user/10/com.example", create_data_user_ce_package_path(nullptr, 10, "com.example"));
504
505    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/0/com.example",
506            create_data_user_ce_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 0, "com.example"));
507    EXPECT_EQ("/mnt/expand/57f8f4bc-abf4-655f-bf67-946fc0f9f25b/user/10/com.example",
508            create_data_user_ce_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10, "com.example"));
509}
510
511}  // namespace installd
512}  // namespace android
513