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 package com.android.settings.fuelgauge.batterytip; 17 18 import static com.android.settings.fuelgauge.batterytip.tips.BatteryTip.TipType 19 .SMART_BATTERY_MANAGER; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import static org.mockito.Matchers.any; 24 import static org.mockito.Matchers.eq; 25 import static org.mockito.Mockito.doReturn; 26 import static org.mockito.Mockito.spy; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.content.Context; 31 import android.os.Bundle; 32 import android.support.v7.preference.Preference; 33 import android.support.v7.preference.PreferenceCategory; 34 import android.support.v7.preference.PreferenceGroup; 35 import android.support.v7.preference.PreferenceManager; 36 import android.support.v7.preference.PreferenceScreen; 37 import android.text.format.DateUtils; 38 39 import com.android.internal.logging.nano.MetricsProto; 40 import com.android.settings.R; 41 import com.android.settings.SettingsActivity; 42 import com.android.settings.core.InstrumentedPreferenceFragment; 43 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; 44 import com.android.settings.fuelgauge.batterytip.tips.SummaryTip; 45 import com.android.settings.testutils.FakeFeatureFactory; 46 import com.android.settings.testutils.SettingsRobolectricTestRunner; 47 48 import org.junit.Before; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 import org.mockito.Answers; 52 import org.mockito.Mock; 53 import org.mockito.MockitoAnnotations; 54 import org.robolectric.RuntimeEnvironment; 55 56 import java.util.ArrayList; 57 import java.util.List; 58 59 @RunWith(SettingsRobolectricTestRunner.class) 60 public class BatteryTipPreferenceControllerTest { 61 62 private static final String KEY_PREF = "battery_tip"; 63 private static final String KEY_TIP = "key_battery_tip"; 64 private static final long AVERAGE_TIME_MS = DateUtils.HOUR_IN_MILLIS; 65 66 @Mock 67 private BatteryTipPreferenceController.BatteryTipListener mBatteryTipListener; 68 @Mock 69 private PreferenceScreen mPreferenceScreen; 70 @Mock 71 private BatteryTip mBatteryTip; 72 @Mock 73 private SettingsActivity mSettingsActivity; 74 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 75 private PreferenceManager mPreferenceManager; 76 @Mock 77 private InstrumentedPreferenceFragment mFragment; 78 79 private Context mContext; 80 private PreferenceGroup mPreferenceGroup; 81 private BatteryTipPreferenceController mBatteryTipPreferenceController; 82 private List<BatteryTip> mOldBatteryTips; 83 private List<BatteryTip> mNewBatteryTips; 84 private Preference mPreference; 85 private FakeFeatureFactory mFeatureFactory; 86 87 @Before 88 public void setUp() { 89 MockitoAnnotations.initMocks(this); 90 mContext = RuntimeEnvironment.application; 91 92 mPreferenceGroup = spy(new PreferenceCategory(mContext)); 93 when(mPreferenceScreen.getContext()).thenReturn(mContext); 94 when(mPreferenceGroup.getPreferenceManager()).thenReturn(mPreferenceManager); 95 doReturn(mPreferenceGroup).when(mPreferenceScreen).findPreference(KEY_PREF); 96 mPreference = new Preference(mContext); 97 mPreference.setKey(KEY_TIP); 98 mFeatureFactory = FakeFeatureFactory.setupForTest(); 99 100 mOldBatteryTips = new ArrayList<>(); 101 mOldBatteryTips.add(new SummaryTip(BatteryTip.StateType.NEW, AVERAGE_TIME_MS)); 102 mNewBatteryTips = new ArrayList<>(); 103 mNewBatteryTips.add(new SummaryTip(BatteryTip.StateType.INVISIBLE, AVERAGE_TIME_MS)); 104 105 mBatteryTipPreferenceController = new BatteryTipPreferenceController(mContext, KEY_PREF, 106 mSettingsActivity, mFragment, mBatteryTipListener); 107 mBatteryTipPreferenceController.mPreferenceGroup = mPreferenceGroup; 108 mBatteryTipPreferenceController.mPrefContext = mContext; 109 } 110 111 @Test 112 public void testDisplayPreference_addSummaryTip() { 113 mBatteryTipPreferenceController.displayPreference(mPreferenceScreen); 114 115 assertOnlyContainsSummaryTip(mPreferenceGroup); 116 } 117 118 @Test 119 public void testUpdateBatteryTips_updateTwice_firstShowSummaryTipThenRemoveIt() { 120 // Display summary tip because its state is new 121 mBatteryTipPreferenceController.updateBatteryTips(mOldBatteryTips); 122 assertOnlyContainsSummaryTip(mPreferenceGroup); 123 124 // Remove summary tip because its new state is invisible 125 mBatteryTipPreferenceController.updateBatteryTips(mNewBatteryTips); 126 assertThat(mPreferenceGroup.getPreferenceCount()).isEqualTo(0); 127 } 128 129 @Test 130 public void testUpdateBatteryTips_logBatteryTip() { 131 mBatteryTipPreferenceController.updateBatteryTips(mOldBatteryTips); 132 133 verify(mFeatureFactory.metricsFeatureProvider).action(mContext, 134 MetricsProto.MetricsEvent.ACTION_SUMMARY_TIP, 135 BatteryTip.StateType.NEW); 136 } 137 138 @Test 139 public void testSaveAndRestore() { 140 mBatteryTipPreferenceController.updateBatteryTips(mOldBatteryTips); 141 final Bundle bundle = new Bundle(); 142 mBatteryTipPreferenceController.saveInstanceState(bundle); 143 144 final BatteryTipPreferenceController controller = new BatteryTipPreferenceController( 145 mContext, KEY_PREF, mSettingsActivity, mFragment, mBatteryTipListener); 146 controller.mPreferenceGroup = mPreferenceGroup; 147 controller.mPrefContext = mContext; 148 controller.restoreInstanceState(bundle); 149 150 assertOnlyContainsSummaryTip(mPreferenceGroup); 151 } 152 153 @Test 154 public void testRestoreFromNull_shouldNotCrash() { 155 final Bundle bundle = new Bundle(); 156 // Battery tip list is null at this time 157 mBatteryTipPreferenceController.saveInstanceState(bundle); 158 159 final BatteryTipPreferenceController controller = new BatteryTipPreferenceController( 160 mContext, KEY_PREF, mSettingsActivity, mFragment, mBatteryTipListener); 161 162 // Should not crash 163 controller.restoreInstanceState(bundle); 164 } 165 166 @Test 167 public void testHandlePreferenceTreeClick_noDialog_invokeCallback() { 168 when(mBatteryTip.getType()).thenReturn(SMART_BATTERY_MANAGER); 169 List<BatteryTip> batteryTips = new ArrayList<>(); 170 batteryTips.add(mBatteryTip); 171 doReturn(mPreference).when(mBatteryTip).buildPreference(any()); 172 doReturn(false).when(mBatteryTip).shouldShowDialog(); 173 doReturn(KEY_TIP).when(mBatteryTip).getKey(); 174 mBatteryTipPreferenceController.updateBatteryTips(batteryTips); 175 176 mBatteryTipPreferenceController.handlePreferenceTreeClick(mPreference); 177 178 verify(mBatteryTipListener).onBatteryTipHandled(mBatteryTip); 179 } 180 181 private void assertOnlyContainsSummaryTip(final PreferenceGroup preferenceGroup) { 182 assertThat(preferenceGroup.getPreferenceCount()).isEqualTo(1); 183 184 final Preference preference = preferenceGroup.getPreference(0); 185 assertThat(preference.getTitle()).isEqualTo( 186 mContext.getString(R.string.battery_tip_summary_title)); 187 assertThat(preference.getSummary()).isEqualTo( 188 mContext.getString(R.string.battery_tip_summary_summary)); 189 } 190 } 191