1 /* 2 * Copyright (C) 2020 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.systemui.qs.tiles 18 19 import android.content.Context 20 import android.os.Handler 21 import android.testing.AndroidTestingRunner 22 import android.testing.TestableLooper 23 import android.testing.TestableLooper.RunWithLooper 24 import android.view.View 25 import androidx.test.filters.SmallTest 26 import com.android.internal.logging.MetricsLogger 27 import com.android.systemui.R 28 import com.android.systemui.SysuiTestCase 29 import com.android.systemui.classifier.FalsingManagerFake 30 import com.android.systemui.plugins.ActivityStarter 31 import com.android.systemui.plugins.qs.QSTile 32 import com.android.systemui.plugins.statusbar.StatusBarStateController 33 import com.android.systemui.qs.QSHost 34 import com.android.systemui.qs.QsEventLogger 35 import com.android.systemui.qs.logging.QSLogger 36 import com.android.systemui.qs.tileimpl.QSTileImpl 37 import com.android.systemui.statusbar.policy.BatteryController 38 import com.android.systemui.util.settings.FakeSettings 39 import com.android.systemui.util.settings.SecureSettings 40 import com.google.common.truth.Truth.assertThat 41 import org.junit.After 42 import org.junit.Assert.assertEquals 43 import org.junit.Before 44 import org.junit.Test 45 import org.junit.runner.RunWith 46 import org.mockito.Mock 47 import org.mockito.Mockito.clearInvocations 48 import org.mockito.Mockito.never 49 import org.mockito.Mockito.verify 50 import org.mockito.Mockito.`when` 51 import org.mockito.MockitoAnnotations 52 53 @RunWith(AndroidTestingRunner::class) 54 @RunWithLooper(setAsMainLooper = true) 55 @SmallTest 56 class BatterySaverTileTest : SysuiTestCase() { 57 58 companion object { 59 private const val USER = 10 60 } 61 62 @Mock 63 private lateinit var userContext: Context 64 @Mock 65 private lateinit var qsHost: QSHost 66 @Mock 67 private lateinit var uiEventLogger: QsEventLogger 68 @Mock 69 private lateinit var metricsLogger: MetricsLogger 70 @Mock 71 private lateinit var statusBarStateController: StatusBarStateController 72 @Mock 73 private lateinit var activityStarter: ActivityStarter 74 @Mock 75 private lateinit var qsLogger: QSLogger 76 @Mock 77 private lateinit var batteryController: BatteryController 78 @Mock 79 private lateinit var view: View 80 private lateinit var secureSettings: SecureSettings 81 private lateinit var testableLooper: TestableLooper 82 private lateinit var tile: BatterySaverTile 83 84 @Before 85 fun setUp() { 86 MockitoAnnotations.initMocks(this) 87 testableLooper = TestableLooper.get(this) 88 `when`(qsHost.context).thenReturn(mContext) 89 `when`(qsHost.userContext).thenReturn(userContext) 90 `when`(userContext.userId).thenReturn(USER) 91 92 secureSettings = FakeSettings() 93 94 tile = BatterySaverTile( 95 qsHost, 96 uiEventLogger, 97 testableLooper.looper, 98 Handler(testableLooper.looper), 99 FalsingManagerFake(), 100 metricsLogger, 101 statusBarStateController, 102 activityStarter, 103 qsLogger, 104 batteryController, 105 secureSettings) 106 107 tile.initialize() 108 testableLooper.processAllMessages() 109 } 110 111 @After 112 fun tearDown() { 113 tile.destroy() 114 testableLooper.processAllMessages() 115 } 116 117 @Test 118 fun testSettingWithCorrectUser() { 119 assertEquals(USER, tile.mSetting.currentUser) 120 } 121 122 @Test 123 fun testSettingChangesUser() { 124 tile.userSwitch(USER + 1) 125 126 testableLooper.processAllMessages() 127 128 assertEquals(USER + 1, tile.mSetting.currentUser) 129 } 130 131 @Test 132 fun testClickingPowerSavePassesView() { 133 tile.onPowerSaveChanged(true) 134 tile.handleClick(view) 135 136 tile.onPowerSaveChanged(false) 137 tile.handleClick(view) 138 139 verify(batteryController).setPowerSaveMode(true, view) 140 verify(batteryController).setPowerSaveMode(false, view) 141 } 142 143 @Test 144 fun testStopListeningClearsViewInController() { 145 clearInvocations(batteryController) 146 tile.handleSetListening(true) 147 verify(batteryController, never()).clearLastPowerSaverStartView() 148 149 tile.handleSetListening(false) 150 verify(batteryController).clearLastPowerSaverStartView() 151 } 152 153 @Test 154 fun testIcon_whenBatterySaverDisabled_isOffState() { 155 val state = QSTile.BooleanState() 156 tile.onPowerSaveChanged(false) 157 158 tile.handleUpdateState(state, /* arg= */ null) 159 160 assertThat(state.icon) 161 .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_battery_saver_icon_off)) 162 } 163 164 @Test 165 fun testIcon_whenBatterySaverEnabled_isOnState() { 166 val state = QSTile.BooleanState() 167 tile.onPowerSaveChanged(true) 168 169 tile.handleUpdateState(state, /* arg= */ null) 170 171 assertThat(state.icon) 172 .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_battery_saver_icon_on)) 173 } 174 }