• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 package com.android.server.pm;
18 
19 import android.content.pm.ApplicationInfo;
20 import android.content.pm.PackageManager;
21 import android.content.pm.PackageStats;
22 import android.os.SystemClock;
23 import android.os.UserHandle;
24 import android.test.AndroidTestCase;
25 import android.util.Log;
26 
27 import com.android.internal.util.ArrayUtils;
28 
29 import java.util.Arrays;
30 
31 public class InstallerTest extends AndroidTestCase {
32     private static final String TAG = "InstallerTest";
33 
34     private Installer mInstaller;
35 
36     private final Timer mManual = new Timer("Manual");
37     private final Timer mQuota = new Timer("Quota");
38 
39     private static class Timer {
40         private final String mTitle;
41         private long mStart;
42         private long mTotal;
43 
Timer(String title)44         public Timer(String title) {
45             mTitle = title;
46         }
47 
start()48         public void start() {
49             mStart = SystemClock.currentTimeMicro();
50         }
51 
stop()52         public void stop() {
53             mTotal += SystemClock.currentTimeMicro() - mStart;
54         }
55 
reset()56         public void reset() {
57             mStart = 0;
58             mTotal = 0;
59         }
60 
61         @Override
toString()62         public String toString() {
63             return mTitle + ": " + (mTotal / 1000) + "ms";
64         }
65     }
66 
67     @Override
setUp()68     public void setUp() throws Exception {
69         mInstaller = new Installer(getContext());
70         mInstaller.onStart();
71         mManual.reset();
72         mQuota.reset();
73     }
74 
75     @Override
tearDown()76     public void tearDown() throws Exception {
77         Log.i(TAG, mManual.toString());
78         Log.i(TAG, mQuota.toString());
79         mInstaller = null;
80     }
81 
testGetAppSize()82     public void testGetAppSize() throws Exception {
83         int[] appIds = null;
84 
85         final PackageManager pm = getContext().getPackageManager();
86         for (ApplicationInfo app : pm.getInstalledApplications(0)) {
87             final int userId = UserHandle.getUserId(app.uid);
88             final int appId = UserHandle.getAppId(app.uid);
89 
90             if (ArrayUtils.contains(appIds, appId)) {
91                 continue;
92             } else {
93                 appIds = ArrayUtils.appendInt(appIds, appId);
94             }
95 
96             final String[] packageNames = pm.getPackagesForUid(app.uid);
97             final long[] ceDataInodes = new long[packageNames.length];
98             final String[] codePaths = new String[packageNames.length];
99 
100             for (int i = 0; i < packageNames.length; i++) {
101                 final ApplicationInfo info = pm.getApplicationInfo(packageNames[i], 0);
102                 codePaths[i] = info.getCodePath();
103             }
104 
105             final PackageStats stats = new PackageStats(app.packageName);
106             final PackageStats quotaStats = new PackageStats(app.packageName);
107 
108             mManual.start();
109             mInstaller.getAppSize(app.volumeUuid, packageNames, userId, 0,
110                     appId, ceDataInodes, codePaths, stats);
111             mManual.stop();
112 
113             mQuota.start();
114             mInstaller.getAppSize(app.volumeUuid, packageNames, userId, Installer.FLAG_USE_QUOTA,
115                     appId, ceDataInodes, codePaths, quotaStats);
116             mQuota.stop();
117 
118             checkEquals(Arrays.toString(packageNames) + " UID=" + app.uid, stats, quotaStats);
119         }
120     }
121 
testGetUserSize()122     public void testGetUserSize() throws Exception {
123         final int[] appIds = getAppIds(UserHandle.USER_SYSTEM);
124 
125         final PackageStats stats = new PackageStats("android");
126         final PackageStats quotaStats = new PackageStats("android");
127 
128         mManual.start();
129         mInstaller.getUserSize(null, UserHandle.USER_SYSTEM, 0,
130                 appIds, stats);
131         mManual.stop();
132 
133         mQuota.start();
134         mInstaller.getUserSize(null, UserHandle.USER_SYSTEM, Installer.FLAG_USE_QUOTA,
135                 appIds, quotaStats);
136         mQuota.stop();
137 
138         checkEquals(Arrays.toString(appIds), stats, quotaStats);
139     }
140 
testGetExternalSize()141     public void testGetExternalSize() throws Exception {
142         final int[] appIds = getAppIds(UserHandle.USER_SYSTEM);
143 
144         mManual.start();
145         final long[] stats = mInstaller.getExternalSize(null, UserHandle.USER_SYSTEM, 0, appIds);
146         mManual.stop();
147 
148         mQuota.start();
149         final long[] quotaStats = mInstaller.getExternalSize(null, UserHandle.USER_SYSTEM,
150                 Installer.FLAG_USE_QUOTA, appIds);
151         mQuota.stop();
152 
153         for (int i = 0; i < stats.length; i++) {
154             checkEquals("#" + i, stats[i], quotaStats[i]);
155         }
156     }
157 
getAppIds(int userId)158     private int[] getAppIds(int userId) {
159         int[] appIds = null;
160         for (ApplicationInfo app : getContext().getPackageManager().getInstalledApplicationsAsUser(
161                 PackageManager.MATCH_UNINSTALLED_PACKAGES, userId)) {
162             final int appId = UserHandle.getAppId(app.uid);
163             if (!ArrayUtils.contains(appIds, appId)) {
164                 appIds = ArrayUtils.appendInt(appIds, appId);
165             }
166         }
167         return appIds;
168     }
169 
checkEquals(String msg, PackageStats a, PackageStats b)170     private static void checkEquals(String msg, PackageStats a, PackageStats b) {
171         checkEquals(msg + " codeSize", a.codeSize, b.codeSize);
172         checkEquals(msg + " dataSize", a.dataSize, b.dataSize);
173         checkEquals(msg + " cacheSize", a.cacheSize, b.cacheSize);
174         checkEquals(msg + " externalCodeSize", a.externalCodeSize, b.externalCodeSize);
175         checkEquals(msg + " externalDataSize", a.externalDataSize, b.externalDataSize);
176         checkEquals(msg + " externalCacheSize", a.externalCacheSize, b.externalCacheSize);
177     }
178 
checkEquals(String msg, long expected, long actual)179     private static void checkEquals(String msg, long expected, long actual) {
180         if (expected != actual) {
181             Log.e(TAG, msg + " expected " + expected + " actual " + actual);
182         }
183     }
184 }
185