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;
17 
18 import static com.android.settings.fuelgauge.BatteryBroadcastReceiver.BatteryUpdateType;
19 
20 import static com.google.common.truth.Truth.assertThat;
21 
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.ArgumentMatchers.eq;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.never;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 
31 import android.content.Context;
32 import android.content.Intent;
33 import android.content.IntentFilter;
34 import android.hardware.usb.UsbManager;
35 import android.os.BatteryManager;
36 import android.os.PowerManager;
37 
38 import com.android.settings.Utils;
39 
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 import org.mockito.ArgumentCaptor;
44 import org.mockito.Mock;
45 import org.mockito.MockitoAnnotations;
46 import org.robolectric.RobolectricTestRunner;
47 import org.robolectric.RuntimeEnvironment;
48 
49 @RunWith(RobolectricTestRunner.class)
50 public class BatteryBroadcastReceiverTest {
51 
52     private static final String BATTERY_INIT_LEVEL = "100%";
53     private static final String BATTERY_INIT_STATUS = "Not charging";
54     private static final int BATTERY_INTENT_LEVEL = 80;
55     private static final int BATTERY_INTENT_SCALE = 100;
56 
57     @Mock private BatteryBroadcastReceiver.OnBatteryChangedListener mBatteryListener;
58     private BatteryBroadcastReceiver mBatteryBroadcastReceiver;
59     private Context mContext;
60     private Intent mChargingIntent;
61 
62     @Before
setUp()63     public void setUp() {
64         MockitoAnnotations.initMocks(this);
65         mContext = spy(RuntimeEnvironment.application);
66 
67         mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(mContext);
68         mBatteryBroadcastReceiver.mBatteryLevel = BATTERY_INIT_LEVEL;
69         mBatteryBroadcastReceiver.mBatteryStatus = BATTERY_INIT_STATUS;
70         mBatteryBroadcastReceiver.mBatteryHealth = BatteryManager.BATTERY_HEALTH_UNKNOWN;
71         mBatteryBroadcastReceiver.mChargingStatus = BatteryManager.CHARGING_POLICY_DEFAULT;
72         mBatteryBroadcastReceiver.setBatteryChangedListener(mBatteryListener);
73 
74         mChargingIntent = new Intent(Intent.ACTION_BATTERY_CHANGED);
75         mChargingIntent.putExtra(BatteryManager.EXTRA_LEVEL, BATTERY_INTENT_LEVEL);
76         mChargingIntent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_INTENT_SCALE);
77         mChargingIntent.putExtra(
78                 BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_CHARGING);
79     }
80 
81     @Test
onReceive_batteryLevelChanged_dataUpdated()82     public void onReceive_batteryLevelChanged_dataUpdated() {
83         mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
84 
85         assertThat(mBatteryBroadcastReceiver.mBatteryLevel)
86                 .isEqualTo(Utils.getBatteryPercentage(mChargingIntent));
87         assertThat(mBatteryBroadcastReceiver.mBatteryStatus)
88                 .isEqualTo(
89                         Utils.getBatteryStatus(
90                                 mContext, mChargingIntent, /* compactStatus= */ false));
91         verify(mBatteryListener).onBatteryChanged(BatteryUpdateType.BATTERY_LEVEL);
92     }
93 
94     @Test
onReceive_batteryHealthChanged_dataUpdated()95     public void onReceive_batteryHealthChanged_dataUpdated() {
96         mChargingIntent.putExtra(
97                 BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_OVERHEAT);
98         mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
99 
100         assertThat(mBatteryBroadcastReceiver.mBatteryHealth)
101                 .isEqualTo(BatteryManager.BATTERY_HEALTH_OVERHEAT);
102         verify(mBatteryListener).onBatteryChanged(BatteryUpdateType.BATTERY_HEALTH);
103     }
104 
105     @Test
onReceive_chargingStatusChanged_dataUpdated()106     public void onReceive_chargingStatusChanged_dataUpdated() {
107         mChargingIntent.putExtra(
108                 BatteryManager.EXTRA_CHARGING_STATUS,
109                 BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
110         mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
111 
112         assertThat(mBatteryBroadcastReceiver.mChargingStatus)
113                 .isEqualTo(BatteryManager.CHARGING_POLICY_ADAPTIVE_LONGLIFE);
114         verify(mBatteryListener).onBatteryChanged(BatteryUpdateType.CHARGING_STATUS);
115     }
116 
117     @Test
onReceive_batteryNotPresent_shouldShowHelpMessage()118     public void onReceive_batteryNotPresent_shouldShowHelpMessage() {
119         mChargingIntent.putExtra(BatteryManager.EXTRA_PRESENT, false);
120 
121         mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
122 
123         verify(mBatteryListener).onBatteryChanged(BatteryUpdateType.BATTERY_NOT_PRESENT);
124     }
125 
126     @Test
onReceive_powerSaveModeChanged_listenerInvoked()127     public void onReceive_powerSaveModeChanged_listenerInvoked() {
128         mBatteryBroadcastReceiver.onReceive(
129                 mContext, new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
130 
131         verify(mBatteryListener).onBatteryChanged(BatteryUpdateType.BATTERY_SAVER);
132     }
133 
134     @Test
onReceive_batteryDataNotChanged_listenerNotInvoked()135     public void onReceive_batteryDataNotChanged_listenerNotInvoked() {
136         final String batteryLevel = Utils.getBatteryPercentage(mChargingIntent);
137         final String batteryStatus =
138                 Utils.getBatteryStatus(mContext, mChargingIntent, /* compactStatus= */ false);
139         mBatteryBroadcastReceiver.mBatteryLevel = batteryLevel;
140         mBatteryBroadcastReceiver.mBatteryStatus = batteryStatus;
141 
142         mBatteryBroadcastReceiver.onReceive(mContext, mChargingIntent);
143 
144         assertThat(mBatteryBroadcastReceiver.mBatteryLevel).isEqualTo(batteryLevel);
145         assertThat(mBatteryBroadcastReceiver.mBatteryStatus).isEqualTo(batteryStatus);
146         assertThat(mBatteryBroadcastReceiver.mBatteryHealth)
147                 .isEqualTo(BatteryManager.BATTERY_HEALTH_UNKNOWN);
148         assertThat(mBatteryBroadcastReceiver.mChargingStatus)
149                 .isEqualTo(BatteryManager.CHARGING_POLICY_DEFAULT);
150         verify(mBatteryListener, never()).onBatteryChanged(anyInt());
151     }
152 
153     @Test
onReceive_dockDefenderBypassed_listenerInvoked()154     public void onReceive_dockDefenderBypassed_listenerInvoked() {
155         mBatteryBroadcastReceiver.onReceive(
156                 mContext, new Intent(BatteryUtils.BYPASS_DOCK_DEFENDER_ACTION));
157 
158         verify(mBatteryListener).onBatteryChanged(BatteryUpdateType.BATTERY_STATUS);
159     }
160 
161     @Test
onReceive_usbPortComplianceChanged_listenerInvoked()162     public void onReceive_usbPortComplianceChanged_listenerInvoked() {
163         mBatteryBroadcastReceiver.onReceive(
164                 mContext, new Intent(UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED));
165 
166         verify(mBatteryListener).onBatteryChanged(BatteryUpdateType.BATTERY_STATUS);
167     }
168 
169     @Test
register_updateBatteryStatus()170     public void register_updateBatteryStatus() {
171         doReturn(mChargingIntent).when(mContext).registerReceiver(any(), any(), anyInt());
172 
173         mBatteryBroadcastReceiver.register();
174         mBatteryBroadcastReceiver.register();
175 
176         assertThat(mBatteryBroadcastReceiver.mBatteryLevel)
177                 .isEqualTo(Utils.getBatteryPercentage(mChargingIntent));
178         assertThat(mBatteryBroadcastReceiver.mBatteryStatus)
179                 .isEqualTo(
180                         Utils.getBatteryStatus(
181                                 mContext, mChargingIntent, /* compactStatus= */ false));
182         assertThat(mBatteryBroadcastReceiver.mBatteryHealth)
183                 .isEqualTo(BatteryManager.BATTERY_HEALTH_UNKNOWN);
184         assertThat(mBatteryBroadcastReceiver.mChargingStatus)
185                 .isEqualTo(BatteryManager.CHARGING_POLICY_DEFAULT);
186         // 2 times because register will force update the battery
187         verify(mBatteryListener, times(2)).onBatteryChanged(BatteryUpdateType.MANUAL);
188     }
189 
190     @Test
register_registerExpectedIntent()191     public void register_registerExpectedIntent() {
192         mBatteryBroadcastReceiver.register();
193 
194         ArgumentCaptor<IntentFilter> captor = ArgumentCaptor.forClass(IntentFilter.class);
195         verify(mContext)
196                 .registerReceiver(
197                         eq(mBatteryBroadcastReceiver),
198                         captor.capture(),
199                         eq(Context.RECEIVER_EXPORTED));
200         assertAction(captor, Intent.ACTION_BATTERY_CHANGED);
201         assertAction(captor, PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
202         assertAction(captor, BatteryUtils.BYPASS_DOCK_DEFENDER_ACTION);
203         assertAction(captor, UsbManager.ACTION_USB_PORT_COMPLIANCE_CHANGED);
204     }
205 
assertAction(ArgumentCaptor<IntentFilter> captor, String action)206     private void assertAction(ArgumentCaptor<IntentFilter> captor, String action) {
207         assertThat(captor.getValue().hasAction(action)).isTrue();
208     }
209 }
210