1/* 2 * Copyright (C) 2017 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 17package com.android.settings.fuelgauge; 18 19import static com.google.common.truth.Truth.assertThat; 20 21 22import static org.mockito.Matchers.any; 23import static org.mockito.Matchers.anyInt; 24import static org.mockito.Matchers.anyString; 25import static org.mockito.Matchers.eq; 26import static org.mockito.Mockito.doAnswer; 27import static org.mockito.Mockito.doReturn; 28import static org.mockito.Mockito.spy; 29import static org.mockito.Mockito.verify; 30 31import android.content.Context; 32import android.content.pm.ApplicationInfo; 33import android.content.pm.PackageManager; 34import android.graphics.drawable.Drawable; 35import android.os.Bundle; 36import android.support.v7.preference.Preference; 37import android.support.v7.preference.PreferenceCategory; 38import android.support.v7.preference.PreferenceGroup; 39import android.support.v7.preference.PreferenceManager; 40import android.util.IconDrawableFactory; 41 42import com.android.settings.SettingsActivity; 43import com.android.settings.testutils.SettingsRobolectricTestRunner; 44import com.android.settings.TestConfig; 45import com.android.settings.fuelgauge.anomaly.Anomaly; 46 47import org.junit.Before; 48import org.junit.Test; 49import org.junit.runner.RunWith; 50import org.mockito.ArgumentCaptor; 51import org.mockito.Mock; 52import org.mockito.MockitoAnnotations; 53import org.mockito.invocation.InvocationOnMock; 54import org.mockito.stubbing.Answer; 55import org.robolectric.RuntimeEnvironment; 56import org.robolectric.annotation.Config; 57 58import java.util.ArrayList; 59import java.util.List; 60 61@RunWith(SettingsRobolectricTestRunner.class) 62@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 63public class PowerUsageAnomalyDetailsTest { 64 private static final String NAME_APP_1 = "app1"; 65 private static final String NAME_APP_2 = "app2"; 66 private static final String NAME_APP_3 = "app3"; 67 private static final String PACKAGE_NAME_1 = "com.android.app1"; 68 private static final String PACKAGE_NAME_2 = "com.android.app2"; 69 private static final String PACKAGE_NAME_3 = "com.android.app3"; 70 private static final int USER_ID = 1; 71 72 @Mock 73 private SettingsActivity mSettingsActivity; 74 @Mock 75 private PreferenceManager mPreferenceManager; 76 @Mock 77 private Drawable mDrawable1; 78 @Mock 79 private Drawable mDrawable2; 80 @Mock 81 private Drawable mDrawable3; 82 @Mock 83 private PackageManager mPackageManager; 84 @Mock 85 private IconDrawableFactory mIconDrawableFactory; 86 @Mock 87 private ApplicationInfo mApplicationInfo; 88 private Context mContext; 89 private PowerUsageAnomalyDetails mFragment; 90 private PreferenceGroup mAbnormalListGroup; 91 private Bundle mBundle; 92 private List<Anomaly> mAnomalyList; 93 94 @Before 95 public void setUp() { 96 MockitoAnnotations.initMocks(this); 97 98 mContext = RuntimeEnvironment.application; 99 mAbnormalListGroup = spy(new PreferenceCategory(mContext)); 100 101 mAnomalyList = new ArrayList<>(); 102 Anomaly anomaly1 = new Anomaly.Builder() 103 .setType(Anomaly.AnomalyType.WAKE_LOCK) 104 .setPackageName(PACKAGE_NAME_1) 105 .setDisplayName(NAME_APP_1) 106 .build(); 107 mAnomalyList.add(anomaly1); 108 Anomaly anomaly2 = new Anomaly.Builder() 109 .setType(Anomaly.AnomalyType.WAKEUP_ALARM) 110 .setPackageName(PACKAGE_NAME_2) 111 .setDisplayName(NAME_APP_2) 112 .build(); 113 mAnomalyList.add(anomaly2); 114 Anomaly anomaly3 = new Anomaly.Builder() 115 .setType(Anomaly.AnomalyType.BLUETOOTH_SCAN) 116 .setPackageName(PACKAGE_NAME_3) 117 .setDisplayName(NAME_APP_3) 118 .build(); 119 mAnomalyList.add(anomaly3); 120 121 mFragment = spy(new PowerUsageAnomalyDetails()); 122 mFragment.mAbnormalListGroup = mAbnormalListGroup; 123 mFragment.mAnomalies = mAnomalyList; 124 mFragment.mBatteryUtils = new BatteryUtils(mContext); 125 mFragment.mPackageManager = mPackageManager; 126 mFragment.mIconDrawableFactory = mIconDrawableFactory; 127 doReturn(mPreferenceManager).when(mFragment).getPreferenceManager(); 128 doReturn(mContext).when(mPreferenceManager).getContext(); 129 } 130 131 @Test 132 public void testRefreshUi_displayCorrectTitleAndSummary() { 133 final List<Preference> testPreferences = new ArrayList<>(); 134 final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass( 135 Preference.class); 136 Answer<Void> prefCallable = new Answer<Void>() { 137 @Override 138 public Void answer(InvocationOnMock invocation) throws Throwable { 139 testPreferences.add(preferenceCaptor.getValue()); 140 return null; 141 } 142 }; 143 doAnswer(prefCallable).when(mAbnormalListGroup).addPreference(preferenceCaptor.capture()); 144 145 mFragment.refreshUi(); 146 147 final Preference wakelockPreference = testPreferences.get(0); 148 assertThat(wakelockPreference.getTitle()).isEqualTo(NAME_APP_1); 149 assertThat(wakelockPreference.getSummary()).isEqualTo("Keeping device awake"); 150 final Preference wakeupPreference = testPreferences.get(1); 151 assertThat(wakeupPreference.getTitle()).isEqualTo(NAME_APP_2); 152 assertThat(wakeupPreference.getSummary()).isEqualTo("Waking up device in background"); 153 final Preference bluetoothPreference = testPreferences.get(2); 154 assertThat(bluetoothPreference.getTitle()).isEqualTo(NAME_APP_3); 155 assertThat(bluetoothPreference.getSummary()).isEqualTo("Requesting location frequently"); 156 } 157 158 @Test 159 public void testRefreshUi_iconCorrect() { 160 doReturn(mDrawable1).when(mFragment).getBadgedIcon(eq(PACKAGE_NAME_1), anyInt()); 161 doReturn(mDrawable2).when(mFragment).getBadgedIcon(eq(PACKAGE_NAME_2), anyInt()); 162 doReturn(mDrawable3).when(mFragment).getBadgedIcon(eq(PACKAGE_NAME_3), anyInt()); 163 164 final List<Drawable> testIcons = new ArrayList<>(); 165 final ArgumentCaptor<Preference> preferenceCaptor = ArgumentCaptor.forClass( 166 Preference.class); 167 Answer<Void> prefCallable = new Answer<Void>() { 168 @Override 169 public Void answer(InvocationOnMock invocation) throws Throwable { 170 testIcons.add(preferenceCaptor.getValue().getIcon()); 171 return null; 172 } 173 }; 174 doAnswer(prefCallable).when(mAbnormalListGroup).addPreference(preferenceCaptor.capture()); 175 176 mFragment.refreshUi(); 177 178 assertThat(testIcons).containsExactly(mDrawable1, mDrawable2, mDrawable3); 179 } 180 181 @Test 182 public void testStartBatteryAbnormalPage_dataCorrect() { 183 final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); 184 Answer<Void> bundleCallable = new Answer<Void>() { 185 @Override 186 public Void answer(InvocationOnMock invocation) throws Exception { 187 mBundle = bundleCaptor.getValue(); 188 return null; 189 } 190 }; 191 doAnswer(bundleCallable).when(mSettingsActivity).startPreferencePanelAsUser(any(), 192 anyString(), 193 bundleCaptor.capture(), anyInt(), any(), any()); 194 195 PowerUsageAnomalyDetails.startBatteryAbnormalPage(mSettingsActivity, mFragment, 196 mAnomalyList); 197 198 assertThat(mBundle.getParcelableArrayList( 199 PowerUsageAnomalyDetails.EXTRA_ANOMALY_LIST)).isEqualTo(mAnomalyList); 200 } 201 202 @Test 203 public void testGetBadgedIcon_usePackageNameAndUserId() throws 204 PackageManager.NameNotFoundException { 205 doReturn(mApplicationInfo).when(mPackageManager).getApplicationInfo(PACKAGE_NAME_1, 206 PackageManager.GET_META_DATA); 207 208 mFragment.getBadgedIcon(PACKAGE_NAME_1, USER_ID); 209 210 // Verify that it uses the correct user id 211 verify(mIconDrawableFactory).getBadgedIcon(mApplicationInfo, USER_ID); 212 } 213} 214