• 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 package com.android.settings.datausage;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 import static org.mockito.ArgumentMatchers.any;
20 import static org.mockito.ArgumentMatchers.anyBoolean;
21 import static org.mockito.ArgumentMatchers.nullable;
22 import static org.mockito.Matchers.eq;
23 import static org.mockito.Mockito.doAnswer;
24 import static org.mockito.Mockito.doNothing;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.spy;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
29 
30 import android.content.Context;
31 import android.content.pm.ApplicationInfo;
32 import android.os.Process;
33 import android.support.v7.preference.PreferenceManager;
34 import android.support.v7.preference.PreferenceScreen;
35 
36 import com.android.internal.logging.nano.MetricsProto;
37 import com.android.settings.R;
38 import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
39 import com.android.settings.datausage.UnrestrictedDataAccess.AccessPreference;
40 import com.android.settings.testutils.FakeFeatureFactory;
41 import com.android.settings.testutils.SettingsRobolectricTestRunner;
42 import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
43 import com.android.settingslib.applications.ApplicationsState.AppEntry;
44 
45 import org.junit.Before;
46 import org.junit.Test;
47 import org.junit.runner.RunWith;
48 import org.mockito.Mock;
49 import org.mockito.MockitoAnnotations;
50 import org.robolectric.RuntimeEnvironment;
51 import org.robolectric.annotation.Config;
52 import org.robolectric.util.ReflectionHelpers;
53 
54 import java.util.ArrayList;
55 
56 @RunWith(SettingsRobolectricTestRunner.class)
57 @Config(shadows = ShadowRestrictedLockUtils.class)
58 public class UnrestrictedDataAccessTest {
59 
60     @Mock
61     private AppEntry mAppEntry;
62     private UnrestrictedDataAccess mFragment;
63     private FakeFeatureFactory mFeatureFactory;
64     @Mock
65     private PreferenceScreen mPreferenceScreen;
66     @Mock
67     private PreferenceManager mPreferenceManager;
68     @Mock
69     private DataSaverBackend mDataSaverBackend;
70 
71     @Before
setUp()72     public void setUp() {
73         MockitoAnnotations.initMocks(this);
74         mFeatureFactory = FakeFeatureFactory.setupForTest();
75         mFragment = spy(new UnrestrictedDataAccess());
76     }
77 
78     @Test
testShouldAddPreferenceForApps()79     public void testShouldAddPreferenceForApps() {
80         mAppEntry.info = new ApplicationInfo();
81         mAppEntry.info.uid = Process.FIRST_APPLICATION_UID + 10;
82 
83         assertThat(mFragment.shouldAddPreference(mAppEntry)).isTrue();
84     }
85 
86     @Test
testShouldNotAddPreferenceForNonApps()87     public void testShouldNotAddPreferenceForNonApps() {
88         mAppEntry.info = new ApplicationInfo();
89         mAppEntry.info.uid = Process.FIRST_APPLICATION_UID - 10;
90 
91         assertThat(mFragment.shouldAddPreference(mAppEntry)).isFalse();
92     }
93 
94     @Test
logSpecialPermissionChange()95     public void logSpecialPermissionChange() {
96         mFragment.logSpecialPermissionChange(true, "app");
97         verify(mFeatureFactory.metricsFeatureProvider).action(nullable(Context.class),
98                 eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_UNL_DATA_ALLOW), eq("app"));
99 
100         mFragment.logSpecialPermissionChange(false, "app");
101         verify(mFeatureFactory.metricsFeatureProvider).action(nullable(Context.class),
102                 eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_UNL_DATA_DENY), eq("app"));
103     }
104 
105     @Test
testOnRebuildComplete_restricted_shouldBeDisabled()106     public void testOnRebuildComplete_restricted_shouldBeDisabled() {
107         final Context context = RuntimeEnvironment.application;
108         doReturn(context).when(mFragment).getContext();
109         when(mPreferenceManager.getContext()).thenReturn(context);
110         doReturn(true).when(mFragment).shouldAddPreference(any(AppEntry.class));
111         doNothing().when(mFragment).setLoading(anyBoolean(), anyBoolean());
112         doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
113         when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
114         ReflectionHelpers.setField(mFragment, "mDataSaverBackend", mDataSaverBackend);
115 
116         final String testPkg1 = "com.example.one";
117         final String testPkg2 = "com.example.two";
118         ShadowRestrictedLockUtils.setRestrictedPkgs(testPkg2);
119 
120         doAnswer((invocation) -> {
121             final AccessPreference preference = invocation.getArgument(0);
122             final AppEntry entry = preference.getEntryForTest();
123             // Verify preference is disabled by admin and the summary is changed accordingly.
124             if (testPkg1.equals(entry.info.packageName)) {
125                 assertThat(preference.isDisabledByAdmin()).isFalse();
126                 assertThat(preference.getSummary()).isEqualTo("");
127             } else if (testPkg2.equals(entry.info.packageName)) {
128                 assertThat(preference.isDisabledByAdmin()).isTrue();
129                 assertThat(preference.getSummary()).isEqualTo(
130                         context.getString(R.string.disabled_by_admin));
131             }
132             assertThat(preference.isChecked()).isFalse();
133             preference.performClick();
134             // Verify that when the preference is clicked, support details intent is launched
135             // if the preference is disabled by admin, otherwise the switch is toggled.
136             if (testPkg1.equals(entry.info.packageName)) {
137                 assertThat(preference.isChecked()).isTrue();
138                 assertThat(ShadowRestrictedLockUtils.hasAdminSupportDetailsIntentLaunched())
139                         .isFalse();
140             } else if (testPkg2.equals(entry.info.packageName)) {
141                 assertThat(preference.isChecked()).isFalse();
142                 assertThat(ShadowRestrictedLockUtils.hasAdminSupportDetailsIntentLaunched())
143                         .isTrue();
144             }
145             ShadowRestrictedLockUtils.clearAdminSupportDetailsIntentLaunch();
146             return null;
147         }).when(mPreferenceScreen).addPreference(any(AccessPreference.class));
148         mFragment.onRebuildComplete(createAppEntries(testPkg1, testPkg2));
149     }
150 
createAppEntries(String... packageNames)151     private ArrayList<AppEntry> createAppEntries(String... packageNames) {
152         final ArrayList<AppEntry> appEntries = new ArrayList<>();
153         for (int i = 0; i < packageNames.length; ++i) {
154             final ApplicationInfo info = new ApplicationInfo();
155             info.packageName = packageNames[i];
156             info.uid = Process.FIRST_APPLICATION_UID + i;
157             info.sourceDir = info.packageName;
158             final AppEntry appEntry = spy(new AppEntry(RuntimeEnvironment.application, info, i));
159             appEntry.extraInfo = new DataUsageState(false, false);
160             doNothing().when(appEntry).ensureLabel(any(Context.class));
161             ReflectionHelpers.setField(appEntry, "info", info);
162             appEntries.add(appEntry);
163         }
164         return appEntries;
165     }
166 }
167