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