1 /* 2 * Copyright (C) 2022 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.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.Mockito.doReturn; 24 import static org.mockito.Mockito.inOrder; 25 import static org.mockito.Mockito.never; 26 import static org.mockito.Mockito.spy; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.verifyNoInteractions; 29 30 import android.content.Context; 31 import android.content.Intent; 32 import android.content.pm.PackageManager; 33 import android.os.UserHandle; 34 35 import com.android.settings.TestUtils; 36 import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleRadioButtonsController; 37 38 import org.junit.After; 39 import org.junit.Before; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 import org.mockito.InOrder; 43 import org.mockito.Mock; 44 import org.mockito.MockitoAnnotations; 45 import org.robolectric.RobolectricTestRunner; 46 import org.robolectric.RuntimeEnvironment; 47 import org.robolectric.annotation.Config; 48 import org.robolectric.annotation.Implementation; 49 import org.robolectric.annotation.Implements; 50 import org.robolectric.annotation.Resetter; 51 52 import java.util.ArrayList; 53 import java.util.Arrays; 54 55 @RunWith(RobolectricTestRunner.class) 56 @Config(shadows = {BatterySettingsMigrateCheckerTest.ShadowUserHandle.class}) 57 public final class BatterySettingsMigrateCheckerTest { 58 59 private static final Intent BOOT_COMPLETED_INTENT = new Intent(Intent.ACTION_BOOT_COMPLETED); 60 private static final int UID = 2003; 61 private static final String PACKAGE_NAME = "com.android.test.app"; 62 63 private Context mContext; 64 private BatterySettingsMigrateChecker mBatterySettingsMigrateChecker; 65 66 @Mock private PackageManager mPackageManager; 67 @Mock private BatteryOptimizeUtils mBatteryOptimizeUtils; 68 69 @Before setUp()70 public void setUp() throws Exception { 71 MockitoAnnotations.initMocks(this); 72 mContext = spy(RuntimeEnvironment.application); 73 BatteryUtils.getInstance(mContext).reset(); 74 doReturn(mContext).when(mContext).getApplicationContext(); 75 doReturn(mPackageManager).when(mContext).getPackageManager(); 76 doReturn(UID) 77 .when(mPackageManager) 78 .getPackageUid(PACKAGE_NAME, PackageManager.GET_META_DATA); 79 BatterySettingsMigrateChecker.sBatteryOptimizeUtils = mBatteryOptimizeUtils; 80 mBatterySettingsMigrateChecker = new BatterySettingsMigrateChecker(); 81 } 82 83 @After resetShadows()84 public void resetShadows() { 85 ShadowUserHandle.reset(); 86 } 87 88 @Test onReceive_invalidScheduledLevel_resetScheduledValue()89 public void onReceive_invalidScheduledLevel_resetScheduledValue() { 90 final int invalidScheduledLevel = 5; 91 setScheduledLevel(invalidScheduledLevel); 92 93 mBatterySettingsMigrateChecker.onReceive(mContext, BOOT_COMPLETED_INTENT); 94 95 assertThat(getScheduledLevel()) 96 .isEqualTo(BatterySaverScheduleRadioButtonsController.TRIGGER_LEVEL_MIN); 97 } 98 99 @Test onReceive_validScheduledLevel_notResetScheduledValue()100 public void onReceive_validScheduledLevel_notResetScheduledValue() { 101 final int validScheduledLevel = BatterySaverScheduleRadioButtonsController.TRIGGER_LEVEL_MIN; 102 setScheduledLevel(validScheduledLevel); 103 104 mBatterySettingsMigrateChecker.onReceive(mContext, BOOT_COMPLETED_INTENT); 105 106 assertThat(getScheduledLevel()).isEqualTo(validScheduledLevel); 107 } 108 109 @Test onReceive_validSpecialScheduledLevel_notResetScheduledValue()110 public void onReceive_validSpecialScheduledLevel_notResetScheduledValue() { 111 final int validScheduledLevel = 0; 112 setScheduledLevel(validScheduledLevel); 113 114 mBatterySettingsMigrateChecker.onReceive(mContext, BOOT_COMPLETED_INTENT); 115 116 assertThat(getScheduledLevel()).isEqualTo(validScheduledLevel); 117 } 118 119 @Test onReceive_nullIntnt_noAction()120 public void onReceive_nullIntnt_noAction() { 121 final int invalidScheduledLevel = 5; 122 setScheduledLevel(invalidScheduledLevel); 123 124 mBatterySettingsMigrateChecker.onReceive(mContext, null); 125 126 assertThat(getScheduledLevel()).isEqualTo(invalidScheduledLevel); 127 } 128 129 @Test onReceive_invalidIntent_noAction()130 public void onReceive_invalidIntent_noAction() { 131 final int invalidScheduledLevel = 5; 132 setScheduledLevel(invalidScheduledLevel); 133 134 mBatterySettingsMigrateChecker.onReceive(mContext, new Intent()); 135 136 assertThat(getScheduledLevel()).isEqualTo(invalidScheduledLevel); 137 } 138 139 @Test onReceive_nonOwner_noAction()140 public void onReceive_nonOwner_noAction() { 141 ShadowUserHandle.setUid(1); 142 final int invalidScheduledLevel = 5; 143 setScheduledLevel(invalidScheduledLevel); 144 145 mBatterySettingsMigrateChecker.onReceive(mContext, BOOT_COMPLETED_INTENT); 146 147 assertThat(getScheduledLevel()).isEqualTo(invalidScheduledLevel); 148 } 149 150 @Test verifyBatteryOptimizeModeApps_inAllowList_resetOptimizationMode()151 public void verifyBatteryOptimizeModeApps_inAllowList_resetOptimizationMode() throws Exception { 152 doReturn(BatteryOptimizeUtils.MODE_RESTRICTED) 153 .when(mBatteryOptimizeUtils) 154 .getAppOptimizationMode(); 155 156 mBatterySettingsMigrateChecker.verifyBatteryOptimizeModeApps( 157 mContext, BatteryOptimizeUtils.MODE_OPTIMIZED, Arrays.asList(PACKAGE_NAME)); 158 159 final InOrder inOrder = inOrder(mBatteryOptimizeUtils); 160 inOrder.verify(mBatteryOptimizeUtils).getAppOptimizationMode(); 161 inOrder.verify(mBatteryOptimizeUtils) 162 .setAppUsageState( 163 BatteryOptimizeUtils.MODE_OPTIMIZED, 164 BatteryOptimizeHistoricalLogEntry.Action.FORCE_RESET); 165 } 166 167 @Test verifyBatteryOptimizeModeApps_optimizedMode_noAction()168 public void verifyBatteryOptimizeModeApps_optimizedMode_noAction() throws Exception { 169 doReturn(BatteryOptimizeUtils.MODE_OPTIMIZED) 170 .when(mBatteryOptimizeUtils) 171 .getAppOptimizationMode(); 172 173 mBatterySettingsMigrateChecker.verifyBatteryOptimizeModeApps( 174 mContext, BatteryOptimizeUtils.MODE_OPTIMIZED, Arrays.asList(PACKAGE_NAME)); 175 176 verify(mBatteryOptimizeUtils, never()).setAppUsageState(anyInt(), any()); 177 } 178 179 @Test verifyBatteryOptimizeModeApps_notInAllowList_noAction()180 public void verifyBatteryOptimizeModeApps_notInAllowList_noAction() throws Exception { 181 doReturn(BatteryOptimizeUtils.MODE_RESTRICTED) 182 .when(mBatteryOptimizeUtils) 183 .getAppOptimizationMode(); 184 185 mBatterySettingsMigrateChecker.verifyBatteryOptimizeModeApps( 186 mContext, BatteryOptimizeUtils.MODE_OPTIMIZED, new ArrayList<String>()); 187 188 verifyNoInteractions(mBatteryOptimizeUtils); 189 } 190 setScheduledLevel(int scheduledLevel)191 private void setScheduledLevel(int scheduledLevel) { 192 TestUtils.setScheduledLevel(mContext, scheduledLevel); 193 } 194 getScheduledLevel()195 private int getScheduledLevel() { 196 return TestUtils.getScheduledLevel(mContext); 197 } 198 199 @Implements(UserHandle.class) 200 public static class ShadowUserHandle { 201 // Sets the default as thte OWNER role. 202 private static int sUid = 0; 203 setUid(int uid)204 public static void setUid(int uid) { 205 sUid = uid; 206 } 207 208 @Implementation myUserId()209 public static int myUserId() { 210 return sUid; 211 } 212 213 @Resetter reset()214 public static void reset() { 215 sUid = 0; 216 } 217 } 218 } 219