1 /* 2 * Copyright (C) 2018 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.fuelgauge; 18 19 import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT; 20 import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE_RESID; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.Mockito.doReturn; 26 import static org.mockito.Mockito.mock; 27 import static org.mockito.Mockito.spy; 28 import static org.mockito.Mockito.verify; 29 import static org.mockito.Mockito.when; 30 31 import android.app.Activity; 32 import android.app.AppOpsManager; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.os.UserHandle; 36 import android.os.UserManager; 37 import android.util.Pair; 38 39 import androidx.preference.Preference; 40 import androidx.preference.PreferenceManager; 41 import androidx.preference.PreferenceScreen; 42 43 import com.android.settings.R; 44 import com.android.settings.core.InstrumentedPreferenceFragment; 45 import com.android.settings.fuelgauge.batterytip.AppInfo; 46 47 import org.junit.Before; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 import org.mockito.ArgumentCaptor; 51 import org.mockito.Mock; 52 import org.mockito.MockitoAnnotations; 53 import org.robolectric.Robolectric; 54 import org.robolectric.RobolectricTestRunner; 55 56 import java.util.ArrayList; 57 import java.util.Collections; 58 import java.util.List; 59 60 @RunWith(RobolectricTestRunner.class) 61 public class RestrictAppPreferenceControllerTest { 62 private static final int ALLOWED_UID = 111; 63 private static final String ALLOWED_PACKAGE_NAME = "com.android.allowed.package"; 64 private static final int RESTRICTED_UID = 222; 65 private static final String RESTRICTED_PACKAGE_NAME = "com.android.restricted.package"; 66 private static final int OTHER_USER_UID = UserHandle.PER_USER_RANGE + RESTRICTED_UID; 67 68 @Mock 69 private AppOpsManager mAppOpsManager; 70 @Mock 71 private InstrumentedPreferenceFragment mFragment; 72 @Mock 73 private UserManager mUserManager; 74 75 private AppOpsManager.PackageOps mRestrictedPackageOps; 76 private AppOpsManager.PackageOps mAllowedPackageOps; 77 private AppOpsManager.PackageOps mOtherUserPackageOps; 78 private List<AppOpsManager.PackageOps> mPackageOpsList; 79 private Preference mPreference; 80 private PreferenceScreen mPreferenceScreen; 81 private Context mContext; 82 83 @Before setUp()84 public void setUp() { 85 MockitoAnnotations.initMocks(this); 86 final List<AppOpsManager.OpEntry> allowOps = new ArrayList<>(); 87 allowOps.add(new AppOpsManager.OpEntry( 88 AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, AppOpsManager.MODE_ALLOWED, 89 Collections.emptyMap())); 90 final List<AppOpsManager.OpEntry> restrictedOps = new ArrayList<>(); 91 restrictedOps.add(new AppOpsManager.OpEntry( 92 AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, AppOpsManager.MODE_IGNORED, 93 Collections.emptyMap())); 94 mAllowedPackageOps = new AppOpsManager.PackageOps( 95 ALLOWED_PACKAGE_NAME, ALLOWED_UID, allowOps); 96 mRestrictedPackageOps = new AppOpsManager.PackageOps( 97 RESTRICTED_PACKAGE_NAME, RESTRICTED_UID, restrictedOps); 98 mOtherUserPackageOps = new AppOpsManager.PackageOps( 99 RESTRICTED_PACKAGE_NAME, OTHER_USER_UID, restrictedOps); 100 101 mContext = spy(Robolectric.setupActivity(Activity.class)); 102 doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE); 103 doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); 104 doReturn(mContext).when(mFragment).getContext(); 105 106 mPackageOpsList = new ArrayList<>(); 107 mPreference = new Preference(mContext); 108 mPreference.setKey(RestrictAppPreferenceController.KEY_RESTRICT_APP); 109 mPreferenceScreen = spy(new PreferenceScreen(mContext, null)); 110 when(mPreferenceScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); 111 when(mPreferenceScreen.getContext()).thenReturn(mContext); 112 when(mPreferenceScreen.findPreference( 113 RestrictAppPreferenceController.KEY_RESTRICT_APP)).thenReturn(mPreference); 114 115 final List<UserHandle> userHandles = new ArrayList<>(); 116 userHandles.add(new UserHandle(0)); 117 doReturn(userHandles).when(mUserManager).getUserProfiles(); 118 } 119 120 @Test updateState_oneApp_showCorrectSummary()121 public void updateState_oneApp_showCorrectSummary() { 122 mPackageOpsList.add(mRestrictedPackageOps); 123 doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any(int[].class)); 124 125 final RestrictAppPreferenceController controller = new RestrictAppPreferenceController( 126 mFragment); 127 controller.displayPreference(mPreferenceScreen); 128 controller.updateState(mPreference); 129 130 assertThat(mPreference.getSummary()).isEqualTo("Limiting battery usage for 1 app"); 131 } 132 133 @Test updateState_twoRestrictedAppsForPrimaryUser_visibleAndShowCorrectSummary()134 public void updateState_twoRestrictedAppsForPrimaryUser_visibleAndShowCorrectSummary() { 135 mPackageOpsList.add(mRestrictedPackageOps); 136 mPackageOpsList.add(mRestrictedPackageOps); 137 mPackageOpsList.add(mAllowedPackageOps); 138 mPackageOpsList.add(mOtherUserPackageOps); 139 doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any(int[].class)); 140 141 final RestrictAppPreferenceController controller = new RestrictAppPreferenceController( 142 mFragment); 143 controller.displayPreference(mPreferenceScreen); 144 controller.updateState(mPreference); 145 146 assertThat(mPreference.getSummary()).isEqualTo("Limiting battery usage for 2 apps"); 147 assertThat(mPreference.isVisible()).isTrue(); 148 } 149 150 @Test updateState_oneRestrictedAppForTwoUsers_showSummaryAndContainCorrectApp()151 public void updateState_oneRestrictedAppForTwoUsers_showSummaryAndContainCorrectApp() { 152 // Two packageOps share same package name but different uid. 153 mPackageOpsList.add(mRestrictedPackageOps); 154 mPackageOpsList.add(mOtherUserPackageOps); 155 doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any(int[].class)); 156 157 final RestrictAppPreferenceController controller = new RestrictAppPreferenceController( 158 mFragment); 159 controller.displayPreference(mPreferenceScreen); 160 controller.updateState(mPreference); 161 162 assertThat(mPreference.getSummary()).isEqualTo("Limiting battery usage for 1 app"); 163 assertThat(controller.mAppInfos).containsExactly( 164 new AppInfo.Builder() 165 .setUid(RESTRICTED_UID) 166 .setPackageName(RESTRICTED_PACKAGE_NAME) 167 .build()); 168 } 169 170 @Test updateState_zeroRestrictApp_inVisible()171 public void updateState_zeroRestrictApp_inVisible() { 172 mPackageOpsList.add(mAllowedPackageOps); 173 doReturn(mPackageOpsList).when(mAppOpsManager).getPackagesForOps(any(int[].class)); 174 175 final RestrictAppPreferenceController controller = new RestrictAppPreferenceController( 176 mFragment); 177 controller.displayPreference(mPreferenceScreen); 178 controller.updateState(mPreference); 179 180 assertThat(mPreference.isVisible()).isFalse(); 181 } 182 183 @Test handlePreferenceTreeClick_startFragment()184 public void handlePreferenceTreeClick_startFragment() { 185 final ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class); 186 187 final RestrictAppPreferenceController controller = new RestrictAppPreferenceController( 188 mFragment); 189 controller.handlePreferenceTreeClick(mPreference); 190 191 verify(mContext).startActivity(intent.capture()); 192 assertThat(intent.getValue().getStringExtra(EXTRA_SHOW_FRAGMENT)) 193 .isEqualTo(RestrictedAppDetails.class.getName()); 194 assertThat(intent.getValue().getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1)) 195 .isEqualTo(R.string.restricted_app_title); 196 } 197 } 198