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