• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.settings.applications;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.ArgumentMatchers.any;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.verify;
24 import static org.mockito.Mockito.when;
25 
26 import android.content.BroadcastReceiver;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.content.pm.ApplicationInfo;
30 import android.content.pm.PackageInfo;
31 import android.content.pm.PackageManager;
32 import android.net.Uri;
33 import android.os.UserHandle;
34 
35 import androidx.appcompat.app.AlertDialog;
36 import androidx.preference.PreferenceManager;
37 import androidx.preference.PreferenceScreen;
38 
39 import com.android.internal.logging.nano.MetricsProto;
40 import com.android.settings.testutils.FakeFeatureFactory;
41 import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
42 import com.android.settings.widget.EntityHeaderController;
43 import com.android.settingslib.applications.AppUtils;
44 import com.android.settingslib.applications.ApplicationsState;
45 import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
46 import com.android.settingslib.widget.LayoutPreference;
47 
48 import org.junit.After;
49 import org.junit.Before;
50 import org.junit.Test;
51 import org.junit.runner.RunWith;
52 import org.mockito.Answers;
53 import org.mockito.Mock;
54 import org.mockito.MockitoAnnotations;
55 import org.robolectric.RobolectricTestRunner;
56 import org.robolectric.RuntimeEnvironment;
57 import org.robolectric.annotation.Config;
58 import org.robolectric.util.ReflectionHelpers;
59 
60 @RunWith(RobolectricTestRunner.class)
61 @Config(shadows = ShadowEntityHeaderController.class)
62 public class AppInfoWithHeaderTest {
63 
64     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
65     private EntityHeaderController mHeaderController;
66 
67     private FakeFeatureFactory mFactory;
68     private TestFragment mAppInfoWithHeader;
69 
70     @Before
setUp()71     public void setUp() {
72         MockitoAnnotations.initMocks(this);
73         mFactory = FakeFeatureFactory.setupForTest();
74         when(mFactory.metricsFeatureProvider.getMetricsCategory(any(Object.class)))
75                 .thenReturn(MetricsProto.MetricsEvent.SETTINGS_APP_NOTIF_CATEGORY);
76         mAppInfoWithHeader = new TestFragment();
77         ShadowEntityHeaderController.setUseMock(mHeaderController);
78     }
79 
80     @After
tearDown()81     public void tearDown() {
82         ShadowEntityHeaderController.reset();
83     }
84 
85     @Test
testAppHeaderIsAdded()86     public void testAppHeaderIsAdded() {
87         mAppInfoWithHeader.onActivityCreated(null);
88 
89         verify(mAppInfoWithHeader.mScreen).addPreference(any(LayoutPreference.class));
90     }
91 
92     @Test
packageRemoved_noAppEntry_shouldFinishActivity()93     public void packageRemoved_noAppEntry_shouldFinishActivity() {
94         BroadcastReceiver packageRemovedReceiver =
95                 ReflectionHelpers.getField(mAppInfoWithHeader, "mPackageRemovedReceiver");
96         ReflectionHelpers.setField(mAppInfoWithHeader, "mAppEntry", null);
97 
98         final Intent packageRemovedBroadcast = new Intent();
99         packageRemovedBroadcast.setData(Uri.parse("package:com.android.settings"));
100         packageRemovedReceiver.onReceive(RuntimeEnvironment.application, packageRemovedBroadcast);
101 
102         assertThat(mAppInfoWithHeader.mPackageRemovedCalled).isTrue();
103     }
104 
105     @Test
packageRemoved_appEntryMatchesPackageName_shouldFinishActivity()106     public void packageRemoved_appEntryMatchesPackageName_shouldFinishActivity() {
107         BroadcastReceiver packageRemovedReceiver =
108                 ReflectionHelpers.getField(mAppInfoWithHeader, "mPackageRemovedReceiver");
109         final ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class);
110         entry.info = new ApplicationInfo();
111         entry.info.packageName = "com.android.settings";
112         ReflectionHelpers.setField(mAppInfoWithHeader, "mAppEntry", entry);
113 
114         final Intent packageRemovedBroadcast = new Intent();
115         packageRemovedBroadcast.setData(Uri.parse("package:" + entry.info.packageName));
116         packageRemovedReceiver.onReceive(RuntimeEnvironment.application, packageRemovedBroadcast);
117 
118         assertThat(mAppInfoWithHeader.mPackageRemovedCalled).isTrue();
119     }
120 
121     @Test
noExtraUserHandleInIntent_retrieveAppEntryWithMyUserId()122     public void noExtraUserHandleInIntent_retrieveAppEntryWithMyUserId()
123             throws PackageManager.NameNotFoundException {
124         final String packageName = "com.android.settings";
125 
126         mAppInfoWithHeader.mIntent.setData(Uri.fromParts("package", packageName, null));
127         final ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class);
128         entry.info = new ApplicationInfo();
129         entry.info.packageName = packageName;
130 
131         when(mAppInfoWithHeader.mState.getEntry(packageName,
132                 UserHandle.myUserId())).thenReturn(entry);
133         when(mAppInfoWithHeader.mPm.getPackageInfoAsUser(entry.info.packageName,
134                 PackageManager.MATCH_DISABLED_COMPONENTS |
135                         PackageManager.GET_SIGNING_CERTIFICATES |
136                         PackageManager.GET_PERMISSIONS, UserHandle.myUserId())).thenReturn(
137                 mAppInfoWithHeader.mPackageInfo);
138 
139         mAppInfoWithHeader.retrieveAppEntry();
140 
141         assertThat(mAppInfoWithHeader.mUserId).isEqualTo(UserHandle.myUserId());
142         assertThat(mAppInfoWithHeader.mPackageInfo).isNotNull();
143         assertThat(mAppInfoWithHeader.mAppEntry).isNotNull();
144     }
145 
146     @Test
extraUserHandleInIntent_retrieveAppEntryWithMyUserId()147     public void extraUserHandleInIntent_retrieveAppEntryWithMyUserId()
148             throws PackageManager.NameNotFoundException {
149         final int USER_ID = 1002;
150         final String packageName = "com.android.settings";
151 
152         mAppInfoWithHeader.mIntent.putExtra(Intent.EXTRA_USER_HANDLE, new UserHandle(USER_ID));
153         mAppInfoWithHeader.mIntent.setData(Uri.fromParts("package",
154                 packageName, null));
155         final ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class);
156         entry.info = new ApplicationInfo();
157         entry.info.packageName = packageName;
158 
159         when(mAppInfoWithHeader.mState.getEntry(packageName, USER_ID)).thenReturn(entry);
160         when(mAppInfoWithHeader.mPm.getPackageInfoAsUser(entry.info.packageName,
161                 PackageManager.MATCH_DISABLED_COMPONENTS |
162                         PackageManager.GET_SIGNING_CERTIFICATES |
163                         PackageManager.GET_PERMISSIONS, USER_ID)).thenReturn(
164                 mAppInfoWithHeader.mPackageInfo);
165 
166         mAppInfoWithHeader.retrieveAppEntry();
167 
168         assertThat(mAppInfoWithHeader.mUserId).isEqualTo(USER_ID);
169         assertThat(mAppInfoWithHeader.mPackageInfo).isNotNull();
170         assertThat(mAppInfoWithHeader.mAppEntry).isNotNull();
171     }
172 
173     public static class TestFragment extends AppInfoWithHeader {
174 
175         PreferenceManager mManager;
176         PreferenceScreen mScreen;
177         Context mShadowContext;
178         boolean mPackageRemovedCalled;
179         Intent mIntent;
180 
TestFragment()181         public TestFragment() {
182             mPm = mock(PackageManager.class);
183             mManager = mock(PreferenceManager.class);
184             mScreen = mock(PreferenceScreen.class);
185             mPackageInfo = new PackageInfo();
186             mPackageInfo.applicationInfo = new ApplicationInfo();
187             mState = mock(ApplicationsState.class);
188             mIntent = new Intent();
189             mShadowContext = RuntimeEnvironment.application;
190             ReflectionHelpers.setStaticField(AppUtils.class, "sInstantAppDataProvider",
191                     (InstantAppDataProvider) (info -> false));
192             when(mManager.getContext()).thenReturn(mShadowContext);
193         }
194 
195         @Override
getMetricsCategory()196         public int getMetricsCategory() {
197             return 0;
198         }
199 
200         @Override
refreshUi()201         protected boolean refreshUi() {
202             return false;
203         }
204 
205         @Override
createDialog(int id, int errorCode)206         protected AlertDialog createDialog(int id, int errorCode) {
207             return null;
208         }
209 
210         @Override
getPreferenceScreen()211         public PreferenceScreen getPreferenceScreen() {
212             return mScreen;
213         }
214 
215         @Override
getPreferenceManager()216         public PreferenceManager getPreferenceManager() {
217             return mManager;
218         }
219 
220         @Override
getContext()221         public Context getContext() {
222             return mShadowContext;
223         }
224 
225         @Override
onPackageRemoved()226         protected void onPackageRemoved() {
227             mPackageRemovedCalled = true;
228         }
229 
230         @Override
getIntent()231         protected Intent getIntent() { return mIntent; }
232     }
233 }
234