• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.settings.applications;
18 
19 import static android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION;
20 
21 import static com.android.settings.Utils.PROPERTY_APP_HIBERNATION_ENABLED;
22 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
23 
24 import static com.google.common.truth.Truth.assertThat;
25 
26 import static org.mockito.ArgumentMatchers.anyInt;
27 import static org.mockito.ArgumentMatchers.anyLong;
28 import static org.mockito.ArgumentMatchers.anyString;
29 import static org.mockito.ArgumentMatchers.eq;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.spy;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34 
35 import android.app.usage.IUsageStatsManager;
36 import android.app.usage.UsageStats;
37 import android.app.usage.UsageStatsManager;
38 import android.apphibernation.AppHibernationManager;
39 import android.content.Context;
40 import android.content.pm.PackageInfo;
41 import android.content.pm.PackageManager;
42 import android.content.pm.ParceledListSlice;
43 import android.content.res.Resources;
44 import android.os.Looper;
45 import android.os.RemoteException;
46 import android.provider.DeviceConfig;
47 
48 import androidx.preference.Preference;
49 import androidx.preference.PreferenceManager;
50 import androidx.preference.PreferenceScreen;
51 import androidx.test.core.app.ApplicationProvider;
52 import androidx.test.ext.junit.runners.AndroidJUnit4;
53 
54 import org.junit.Before;
55 import org.junit.Test;
56 import org.junit.runner.RunWith;
57 import org.mockito.Mock;
58 import org.mockito.MockitoAnnotations;
59 
60 import java.util.Arrays;
61 
62 @RunWith(AndroidJUnit4.class)
63 public class HibernatedAppsPreferenceControllerTest {
64 
65     public static final String HIBERNATED_PACKAGE_NAME = "hibernated_package";
66     public static final String AUTO_REVOKED_PACKAGE_NAME = "auto_revoked_package";
67     public static final String PERMISSION = "permission";
68     @Mock
69     PackageManager mPackageManager;
70     @Mock
71     AppHibernationManager mAppHibernationManager;
72     @Mock
73     IUsageStatsManager mIUsageStatsManager;
74     PreferenceScreen mPreferenceScreen;
75     private static final String KEY = "key";
76     private Context mContext;
77     private HibernatedAppsPreferenceController mController;
78 
79     @Before
setUp()80     public void setUp() {
81         if (Looper.myLooper() == null) {
82             Looper.prepare();
83         }
84         MockitoAnnotations.initMocks(this);
85         DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED,
86                 "true", false);
87         mContext = spy(ApplicationProvider.getApplicationContext());
88         when(mContext.getPackageManager()).thenReturn(mPackageManager);
89         when(mContext.getSystemService(AppHibernationManager.class))
90                 .thenReturn(mAppHibernationManager);
91         when(mContext.getSystemService(UsageStatsManager.class)).thenReturn(
92                 new UsageStatsManager(mContext, mIUsageStatsManager));
93 
94         PreferenceManager manager = new PreferenceManager(mContext);
95         mPreferenceScreen = manager.createPreferenceScreen(mContext);
96         Preference preference = mock(Preference.class);
97         when(preference.getKey()).thenReturn(KEY);
98         mPreferenceScreen.addPreference(preference);
99 
100         mController = new HibernatedAppsPreferenceController(mContext, KEY,
101                 command -> command.run(), command -> command.run());
102     }
103 
104     @Test
getAvailabilityStatus_featureDisabled_shouldNotReturnAvailable()105     public void getAvailabilityStatus_featureDisabled_shouldNotReturnAvailable() {
106         DeviceConfig.setProperty(NAMESPACE_APP_HIBERNATION, PROPERTY_APP_HIBERNATION_ENABLED,
107                 "false", true);
108 
109         assertThat((mController).getAvailabilityStatus()).isNotEqualTo(AVAILABLE);
110     }
111 
112     @Test
getSummary_getsRightCountForHibernatedPackage()113     public void getSummary_getsRightCountForHibernatedPackage() {
114         final PackageInfo hibernatedPkg = getHibernatedPackage();
115         when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(
116                 Arrays.asList(hibernatedPkg, new PackageInfo()));
117         when(mContext.getResources()).thenReturn(mock(Resources.class));
118 
119         mController.displayPreference(mPreferenceScreen);
120         mController.onResume();
121 
122         verify(mContext.getResources()).getQuantityString(anyInt(), eq(1), eq(1));
123     }
124 
125     @Test
getSummary_getsRightCountForUnusedAutoRevokedPackage()126     public void getSummary_getsRightCountForUnusedAutoRevokedPackage() {
127         final PackageInfo autoRevokedPkg = getAutoRevokedPackage();
128         when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(
129                 Arrays.asList(autoRevokedPkg, new PackageInfo()));
130         when(mContext.getResources()).thenReturn(mock(Resources.class));
131 
132         mController.displayPreference(mPreferenceScreen);
133         mController.onResume();
134 
135         verify(mContext.getResources()).getQuantityString(anyInt(), eq(1), eq(1));
136     }
137 
138     @Test
getSummary_getsRightCountForUsedAutoRevokedPackage()139     public void getSummary_getsRightCountForUsedAutoRevokedPackage() {
140         final PackageInfo usedAutoRevokedPkg = getAutoRevokedPackage();
141         setAutoRevokedPackageUsageStats();
142         when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(
143                 Arrays.asList(usedAutoRevokedPkg, new PackageInfo()));
144         when(mContext.getResources()).thenReturn(mock(Resources.class));
145 
146         mController.displayPreference(mPreferenceScreen);
147         mController.onResume();
148 
149         verify(mContext.getResources()).getQuantityString(anyInt(), eq(0), eq(0));
150     }
151 
getHibernatedPackage()152     private PackageInfo getHibernatedPackage() {
153         final PackageInfo pi = new PackageInfo();
154         pi.packageName = HIBERNATED_PACKAGE_NAME;
155         pi.requestedPermissions = new String[] {PERMISSION};
156         when(mAppHibernationManager.getHibernatingPackagesForUser())
157                 .thenReturn(Arrays.asList(pi.packageName));
158         when(mPackageManager.getPermissionFlags(
159                 pi.requestedPermissions[0], pi.packageName, mContext.getUser()))
160                 .thenReturn(PackageManager.FLAG_PERMISSION_AUTO_REVOKED);
161         return pi;
162     }
163 
getAutoRevokedPackage()164     private PackageInfo getAutoRevokedPackage() {
165         final PackageInfo pi = new PackageInfo();
166         pi.packageName = AUTO_REVOKED_PACKAGE_NAME;
167         pi.requestedPermissions = new String[] {PERMISSION};
168         when(mPackageManager.getPermissionFlags(
169                 pi.requestedPermissions[0], pi.packageName, mContext.getUser()))
170                 .thenReturn(PackageManager.FLAG_PERMISSION_AUTO_REVOKED);
171         return pi;
172     }
173 
setAutoRevokedPackageUsageStats()174     private void setAutoRevokedPackageUsageStats() {
175         final UsageStats us = new UsageStats();
176         us.mPackageName = AUTO_REVOKED_PACKAGE_NAME;
177         us.mLastTimeVisible = System.currentTimeMillis();
178         try {
179             when(mIUsageStatsManager.queryUsageStats(
180                     anyInt(), anyLong(), anyLong(), anyString(), anyInt()))
181                     .thenReturn(new ParceledListSlice(Arrays.asList(us)));
182         } catch (RemoteException e) {
183             // no-op
184         }
185     }
186 }
187