AppCollectorTest.java revision 579e5581d5339dbdc79b9176fcc2fad660d155db
1/*
2 * Copyright (C) 2016 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
17package com.android.server.storage;
18
19import android.app.usage.StorageStats;
20import android.app.usage.StorageStatsManager;
21import android.content.pm.UserInfo;
22import android.content.Context;
23import android.content.pm.ApplicationInfo;
24import android.content.pm.IPackageStatsObserver;
25import android.content.pm.PackageManager;
26import android.content.pm.PackageStats;
27import android.os.UserHandle;
28import android.os.UserManager;
29import android.os.storage.VolumeInfo;
30import android.test.AndroidTestCase;
31import android.util.ArrayMap;
32import android.util.Log;
33
34import org.junit.Before;
35import org.junit.Test;
36import org.junit.runner.RunWith;
37import org.junit.runners.JUnit4;
38import org.mockito.Mock;
39import org.mockito.Mockito;
40import org.mockito.MockitoAnnotations;
41import org.mockito.invocation.InvocationOnMock;
42import org.mockito.stubbing.Answer;
43
44import java.util.ArrayList;
45import java.util.List;
46import java.util.Map;
47import java.util.concurrent.CountDownLatch;
48import java.util.concurrent.TimeUnit;
49
50import static com.google.common.truth.Truth.assertThat;
51import static org.mockito.Matchers.any;
52import static org.mockito.Matchers.anyInt;
53import static org.mockito.Matchers.anyString;
54import static org.mockito.Matchers.eq;
55import static org.mockito.Mockito.doAnswer;
56import static org.mockito.Mockito.when;
57
58@RunWith(JUnit4.class)
59public class AppCollectorTest extends AndroidTestCase {
60    private static final long TIMEOUT = TimeUnit.MINUTES.toMillis(1);
61    @Mock private Context mContext;
62    @Mock private PackageManager mPm;
63    @Mock private UserManager mUm;
64    @Mock private StorageStatsManager mSsm;
65    private List<UserInfo> mUsers;
66    private Map<Integer, List<ApplicationInfo>> mUserApps;
67
68    @Before
69    public void setUp() throws Exception {
70        super.setUp();
71        MockitoAnnotations.initMocks(this);
72        when(mContext.getPackageManager()).thenReturn(mPm);
73        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUm);
74        when(mContext.getSystemService(Context.STORAGE_STATS_SERVICE)).thenReturn(mSsm);
75
76        // Set up the app list.
77        doAnswer((InvocationOnMock invocation) -> {
78            Integer userId = (Integer) invocation.getArguments()[1];
79            return mUserApps.get(userId);
80        }).when(mPm).getInstalledApplicationsAsUser(anyInt(), anyInt());
81
82        // Set up the user list with a single user (0).
83        mUsers = new ArrayList<>();
84        mUsers.add(new UserInfo(0, "", 0));
85
86        mUserApps = new ArrayMap<>();
87        mUserApps.put(0, new ArrayList<>());
88        when(mUm.getUsers()).thenReturn(mUsers);
89    }
90
91    @Test
92    public void testNoApps() throws Exception {
93        VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
94        volume.fsUuid = "testuuid";
95        AppCollector collector = new AppCollector(mContext, volume);
96
97        assertThat(collector.getPackageStats(TIMEOUT)).isEmpty();
98    }
99
100    @Test
101    public void testAppOnExternalVolume() throws Exception {
102        addApplication("com.test.app", "differentuuid", 0);
103        VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
104        volume.fsUuid = "testuuid";
105        AppCollector collector = new AppCollector(mContext, volume);
106
107        assertThat(collector.getPackageStats(TIMEOUT)).isEmpty();
108    }
109
110    @Test
111    public void testOneValidApp() throws Exception {
112        addApplication("com.test.app", "testuuid", 0);
113        VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
114        volume.fsUuid = "testuuid";
115        AppCollector collector = new AppCollector(mContext, volume);
116        PackageStats stats = new PackageStats("com.test.app");
117
118        when(mSsm.queryStatsForPackage(eq("testuuid"),
119                eq("com.test.app"), eq(UserHandle.of(0)))).thenReturn(new StorageStats());
120        assertThat(collector.getPackageStats(TIMEOUT)).containsExactly(stats);
121    }
122
123    @Test
124    public void testMultipleUsersOneApp() throws Exception {
125        addApplication("com.test.app", "testuuid", 0);
126        mUserApps.put(1, new ArrayList<>());
127        addApplication("com.test.app", "testuuid", 1);
128        mUsers.add(new UserInfo(1, "", 0));
129
130        VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
131        volume.fsUuid = "testuuid";
132        AppCollector collector = new AppCollector(mContext, volume);
133        PackageStats stats = new PackageStats("com.test.app");
134        PackageStats otherStats = new PackageStats("com.test.app");
135        otherStats.userHandle = 1;
136
137        when(mSsm.queryStatsForPackage(eq("testuuid"),
138                eq("com.test.app"), eq(UserHandle.of(0)))).thenReturn(new StorageStats());
139        when(mSsm.queryStatsForPackage(eq("testuuid"),
140                eq("com.test.app"), eq(UserHandle.of(1)))).thenReturn(new StorageStats());
141        assertThat(collector.getPackageStats(TIMEOUT)).containsExactly(stats, otherStats);
142    }
143
144    @Test(expected=NullPointerException.class)
145    public void testNullVolumeShouldCauseNPE() throws Exception {
146        AppCollector collector = new AppCollector(mContext, null);
147    }
148
149    @Test
150    public void testAppNotFoundDoesntCauseCrash() throws Exception {
151        VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
152        addApplication("com.test.app", "uuid", 0);
153        mUsers.add(new UserInfo(1, "", 0));
154        mUserApps.put(1, new ArrayList<>());
155        AppCollector collector = new AppCollector(mContext, volume);
156        when(mSsm.queryStatsForPackage(anyString(), anyString(), any(UserHandle.class))).thenThrow(
157                new IllegalStateException());
158
159        assertThat(collector.getPackageStats(TIMEOUT)).isEmpty();
160    }
161
162    private void addApplication(String packageName, String uuid, int userId) {
163        ApplicationInfo info = new ApplicationInfo();
164        info.packageName = packageName;
165        info.volumeUuid = uuid;
166        List<ApplicationInfo> userApps = mUserApps.get(userId);
167        if (userApps == null) {
168            userApps = new ArrayList<>();
169            mUserApps.put(userId, userApps);
170        }
171        userApps.add(info);
172    }
173}
174