diff options
author | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-03-05 03:10:06 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-03-05 03:10:06 +0000 |
commit | 9afdb0d7a3d154f40fed74391d710d598aa6b42d (patch) | |
tree | 1362daf66d1fceccfb6dd38b9c8259d42e90002e | |
parent | 63ff1fa99d221be188c8ebaf719d91ea155270e9 (diff) | |
parent | 68c66ceb7fbb8af3022d521339129c5be53eb833 (diff) | |
download | telephony-android10-sidebranch.tar.gz |
Merge "DeviceStateMonitor and unit test polish" am: 68c66ceb7fandroid10-sidebranch
Change-Id: I4775e8d10bf8e1d259ecc50780d2abc1779ef109
-rw-r--r-- | src/java/com/android/internal/telephony/DeviceStateMonitor.java | 15 | ||||
-rw-r--r-- | tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java | 261 |
2 files changed, 232 insertions, 44 deletions
diff --git a/src/java/com/android/internal/telephony/DeviceStateMonitor.java b/src/java/com/android/internal/telephony/DeviceStateMonitor.java index 6010274d0d..3547f3c6ce 100644 --- a/src/java/com/android/internal/telephony/DeviceStateMonitor.java +++ b/src/java/com/android/internal/telephony/DeviceStateMonitor.java @@ -79,9 +79,6 @@ public class DeviceStateMonitor extends Handler { static final int EVENT_WIFI_CONNECTION_CHANGED = 7; static final int EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH = 8; - // TODO(b/74006656) load hysteresis values from a property when DeviceStateMonitor starts - private static final int HYSTERESIS_KBPS = 50; - private static final int WIFI_UNAVAILABLE = 0; private static final int WIFI_AVAILABLE = 1; @@ -264,8 +261,14 @@ public class DeviceStateMonitor extends Handler { mIsTetheringOn = false; mIsLowDataExpected = false; - log("DeviceStateMonitor mIsPowerSaveOn=" + mIsPowerSaveOn + ",mIsScreenOn=" - + mIsScreenOn + ",mIsCharging=" + mIsCharging, false); + log("DeviceStateMonitor mIsTetheringOn=" + mIsTetheringOn + + ", mIsScreenOn=" + mIsScreenOn + + ", mIsCharging=" + mIsCharging + + ", mIsPowerSaveOn=" + mIsPowerSaveOn + + ", mIsLowDataExpected=" + mIsLowDataExpected + + ", mIsWifiConnected=" + mIsWifiConnected + + ", mIsAlwaysSignalStrengthReportingEnabled=" + + mIsAlwaysSignalStrengthReportingEnabled, false); final IntentFilter filter = new IntentFilter(); filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); @@ -733,6 +736,8 @@ public class DeviceStateMonitor extends Handler { ipw.println("mIsLowDataExpected=" + mIsLowDataExpected); ipw.println("mUnsolicitedResponseFilter=" + mUnsolicitedResponseFilter); ipw.println("mIsWifiConnected=" + mIsWifiConnected); + ipw.println("mIsAlwaysSignalStrengthReportingEnabled=" + + mIsAlwaysSignalStrengthReportingEnabled); ipw.println("Local logs:"); ipw.increaseIndent(); mLocalLog.dump(fd, ipw, args); diff --git a/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java b/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java index 0133946cd7..8c9ed3fd89 100644 --- a/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java +++ b/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java @@ -17,16 +17,23 @@ package com.android.internal.telephony; import static android.hardware.radio.V1_0.DeviceStateType.CHARGING_STATE; import static android.hardware.radio.V1_0.DeviceStateType.LOW_DATA_EXPECTED; +import static android.hardware.radio.V1_0.DeviceStateType.POWER_SAVE_MODE; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.nullable; -import static org.mockito.Mockito.times; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static java.util.Arrays.asList; +import android.annotation.IntDef; import android.content.Intent; +import android.hardware.radio.V1_2.IndicationFilter; import android.net.ConnectivityManager; import android.os.BatteryManager; import android.os.Message; @@ -34,26 +41,125 @@ import android.test.suitebuilder.annotation.MediumTest; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; -import androidx.test.filters.FlakyTest; - import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Map; @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper public class DeviceStateMonitorTest extends TelephonyTest { + // No indication filter set + private static final int INDICATION_FILTERS_NONE = 0; + + // All implemented indiation filters set so far + // which is a subset of IndicationFilter.ALL + private static final int INDICATION_FILTERS_ALL = + IndicationFilter.SIGNAL_STRENGTH + | IndicationFilter.FULL_NETWORK_STATE + | IndicationFilter.DATA_CALL_DORMANCY_CHANGED + | IndicationFilter.LINK_CAPACITY_ESTIMATE + | IndicationFilter.PHYSICAL_CHANNEL_CONFIG; + + // INDICATION_FILTERS_ALL but excludes Indication.SIGNAL_STRENGTH + private static final int INDICATION_FILTERS_WHEN_TETHERING_ON = + INDICATION_FILTERS_ALL & ~IndicationFilter.SIGNAL_STRENGTH; + private static final int INDICATION_FILTERS_WHEN_CHARGING = INDICATION_FILTERS_ALL; + private static final int INDICATION_FILTERS_WHEN_SCREEN_ON = INDICATION_FILTERS_ALL; + + /** @hide */ + @IntDef(prefix = {"STATE_TYPE_"}, value = { + STATE_TYPE_RIL_CONNECTED, + STATE_TYPE_SCREEN, + STATE_TYPE_POWER_SAVE_MODE, + STATE_TYPE_CHARGING, + STATE_TYPE_TETHERING, + STATE_TYPE_RADIO_AVAILABLE, + STATE_TYPE_WIFI_CONNECTED, + STATE_TYPE_ALWAYS_SIGNAL_STRENGTH_REPORTED, + }) + @Retention(RetentionPolicy.SOURCE) + private @interface StateType {} + + // Keep the same value as correspoinding event + // See state2Event() for detail + private static final int STATE_TYPE_RIL_CONNECTED = 0; + // EVENT_UPDATE_NODE_CHANGED is not here, it will be removed in aosp soon + private static final int STATE_TYPE_SCREEN = 2; + private static final int STATE_TYPE_POWER_SAVE_MODE = 3; + private static final int STATE_TYPE_CHARGING = 4; + private static final int STATE_TYPE_TETHERING = 5; + private static final int STATE_TYPE_RADIO_AVAILABLE = 6; + private static final int STATE_TYPE_WIFI_CONNECTED = 7; + private static final int STATE_TYPE_ALWAYS_SIGNAL_STRENGTH_REPORTED = 8; + + /** @hide */ + @IntDef(prefix = {"STATE_"}, value = { + STATE_OFF, + STATE_ON + }) + @Retention(RetentionPolicy.SOURCE) + private @interface StateStatus {} + + private static final int STATE_OFF = 0; + private static final int STATE_ON = 1; + + // The keys are the single IndicationFilter flags, + // The values are the array of states, when one state turn on, the corresponding + // IndicationFilter flag should NOT be turned off. + private static final Map<Integer, int[]> INDICATION_FILTER_2_TRIGGERS = Map.of( + IndicationFilter.SIGNAL_STRENGTH, new int[] { + STATE_TYPE_ALWAYS_SIGNAL_STRENGTH_REPORTED, STATE_TYPE_CHARGING, STATE_TYPE_SCREEN}, + IndicationFilter.FULL_NETWORK_STATE, new int[] { + STATE_TYPE_CHARGING, STATE_TYPE_SCREEN, STATE_TYPE_TETHERING}, + IndicationFilter.DATA_CALL_DORMANCY_CHANGED, new int[] { + STATE_TYPE_CHARGING, STATE_TYPE_SCREEN, STATE_TYPE_TETHERING}, + IndicationFilter.LINK_CAPACITY_ESTIMATE, new int[] { + STATE_TYPE_CHARGING, STATE_TYPE_SCREEN, STATE_TYPE_TETHERING}, + IndicationFilter.PHYSICAL_CHANNEL_CONFIG, new int[] { + STATE_TYPE_CHARGING, STATE_TYPE_SCREEN, STATE_TYPE_TETHERING} + ); private DeviceStateMonitor mDSM; + // Given a stateType, return the event type that can change the state + private int state2Event(@StateType int stateType) { + // As long as we keep the same value, we can directly return the stateType + return stateType; + } + + private void updateState(@StateType int stateType, @StateStatus int stateValue) { + final int event = state2Event(stateType); + mDSM.obtainMessage(event, stateValue, 0 /* arg2, not used*/).sendToTarget(); + processAllMessages(); + } + + private void updateAllStatesToOff() { + updateState(STATE_TYPE_RIL_CONNECTED, STATE_OFF); + updateState(STATE_TYPE_SCREEN, STATE_OFF); + updateState(STATE_TYPE_POWER_SAVE_MODE, STATE_OFF); + updateState(STATE_TYPE_CHARGING, STATE_OFF); + updateState(STATE_TYPE_TETHERING, STATE_OFF); + updateState(STATE_TYPE_RADIO_AVAILABLE, STATE_OFF); + updateState(STATE_TYPE_WIFI_CONNECTED, STATE_OFF); + updateState(STATE_TYPE_ALWAYS_SIGNAL_STRENGTH_REPORTED, STATE_OFF); + } @Before public void setUp() throws Exception { super.setUp(getClass().getSimpleName()); mDSM = new DeviceStateMonitor(mPhone); - processAllMessages(); + + // Initialize with ALL states off + updateAllStatesToOff(); + + // eliminate the accumuted impact on Mockito.verify() + reset(mSimulatedCommandsVerifier); } @After @@ -62,7 +168,76 @@ public class DeviceStateMonitorTest extends TelephonyTest { super.tearDown(); } - @Test @FlakyTest + /** + * Verify the behavior of CI.setUnsolResponseFilter(). + * Keeping other state unchanged, when one state change. setUnsolResponseFilter() + * should be called with right IndicationFilter flag set. + */ + @Test @MediumTest + public void testSetUnsolResponseFilter_singleStateChange() { + for (int indicationFilter : INDICATION_FILTER_2_TRIGGERS.keySet()) { + for (int state : INDICATION_FILTER_2_TRIGGERS.get(indicationFilter)) { + verifySetUnsolResponseFilter(state, indicationFilter); + } + } + } + + private void verifySetUnsolResponseFilter(int state, int indicationFilter) { + reset(mSimulatedCommandsVerifier); + // In the beginning, all states are off + + // Turn on the state + updateState(state, STATE_ON); + + // Keep other states off, then specified indication filter should NOT be turn off + ArgumentCaptor<Integer> acIndicationFilter = ArgumentCaptor.forClass(Integer.class); + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter( + acIndicationFilter.capture(), nullable(Message.class)); + assertTrue((acIndicationFilter.getValue() & indicationFilter) != 0); + + // Turn off the state again + updateState(state, STATE_OFF); + + // Keep other states off, then no filter flag is on + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter( + eq(INDICATION_FILTERS_NONE), nullable(Message.class)); + } + + @Test + public void testSetUnsolResponseFilter_noReduandantCall() { + // initially all state off, turn screen on + updateState(STATE_TYPE_SCREEN, STATE_ON); + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter(anyInt(), + nullable(Message.class)); + reset(mSimulatedCommandsVerifier); + + updateState(STATE_TYPE_CHARGING, STATE_ON); + verify(mSimulatedCommandsVerifier, never()).setUnsolResponseFilter(anyInt(), + nullable(Message.class)); + + updateState(STATE_TYPE_POWER_SAVE_MODE, STATE_ON); + verify(mSimulatedCommandsVerifier, never()).setUnsolResponseFilter(anyInt(), + nullable(Message.class)); + } + + @Test + public void testScreenOnOff() { + // screen was off by default, turn it on now + updateState(STATE_TYPE_SCREEN, STATE_ON); + processAllMessages(); + + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter( + eq(INDICATION_FILTERS_WHEN_SCREEN_ON), nullable(Message.class)); + + // turn screen off + updateState(STATE_TYPE_SCREEN, STATE_OFF); + processAllMessages(); + + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter( + eq(INDICATION_FILTERS_NONE), nullable(Message.class)); + } + + @Test public void testTethering() { // Turn tethering on Intent intent = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); @@ -70,8 +245,8 @@ public class DeviceStateMonitorTest extends TelephonyTest { mContext.sendBroadcast(intent); processAllMessages(); - verify(mSimulatedCommandsVerifier, times(1)).setUnsolResponseFilter(eq(6), - nullable(Message.class)); + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter( + eq(INDICATION_FILTERS_WHEN_TETHERING_ON), nullable(Message.class)); // Turn tethering off intent = new Intent(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); @@ -79,21 +254,23 @@ public class DeviceStateMonitorTest extends TelephonyTest { mContext.sendBroadcast(intent); processAllMessages(); - verify(mSimulatedCommandsVerifier, times(1)).setUnsolResponseFilter(eq(0), - nullable(Message.class)); + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter( + eq(INDICATION_FILTERS_NONE), nullable(Message.class)); - verify(mSimulatedCommandsVerifier, times(1)).sendDeviceState(eq(LOW_DATA_EXPECTED), + verify(mSimulatedCommandsVerifier).sendDeviceState(eq(LOW_DATA_EXPECTED), eq(true), nullable(Message.class)); } - @Test @FlakyTest + @Test public void testCharging() { // Charging Intent intent = new Intent(BatteryManager.ACTION_CHARGING); mContext.sendBroadcast(intent); processAllMessages(); - verify(mSimulatedCommandsVerifier, times(1)).sendDeviceState(eq(CHARGING_STATE), + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter( + eq(INDICATION_FILTERS_WHEN_CHARGING), nullable(Message.class)); + verify(mSimulatedCommandsVerifier).sendDeviceState(eq(CHARGING_STATE), eq(true), nullable(Message.class)); // Not charging @@ -101,55 +278,61 @@ public class DeviceStateMonitorTest extends TelephonyTest { mContext.sendBroadcast(intent); processAllMessages(); - verify(mSimulatedCommandsVerifier, times(1)).setUnsolResponseFilter(eq(0), - nullable(Message.class)); - - verify(mSimulatedCommandsVerifier, times(1)).sendDeviceState(eq(LOW_DATA_EXPECTED), + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter( + eq(INDICATION_FILTERS_NONE), nullable(Message.class)); + verify(mSimulatedCommandsVerifier).sendDeviceState(eq(LOW_DATA_EXPECTED), eq(true), nullable(Message.class)); - - verify(mSimulatedCommandsVerifier, times(1)).sendDeviceState(eq(CHARGING_STATE), + verify(mSimulatedCommandsVerifier).sendDeviceState(eq(CHARGING_STATE), eq(false), nullable(Message.class)); } - @Test @FlakyTest + @Test public void testReset() { - mDSM.obtainMessage(6).sendToTarget(); - - verify(mSimulatedCommandsVerifier, times(1)).setUnsolResponseFilter(eq(-1), - nullable(Message.class)); + testResetFromEvent(DeviceStateMonitor.EVENT_RIL_CONNECTED); + testResetFromEvent(DeviceStateMonitor.EVENT_RADIO_AVAILABLE); } - private void sendStates(int screenState, int chargingState, int wifiState) { - mDSM.obtainMessage( - DeviceStateMonitor.EVENT_SCREEN_STATE_CHANGED, screenState, 0).sendToTarget(); - mDSM.obtainMessage( - DeviceStateMonitor.EVENT_CHARGING_STATE_CHANGED, chargingState, 0).sendToTarget(); - mDSM.obtainMessage( - DeviceStateMonitor.EVENT_WIFI_CONNECTION_CHANGED, wifiState, 0).sendToTarget(); + private void testResetFromEvent(int event) { + reset(mSimulatedCommandsVerifier); + mDSM.obtainMessage(event).sendToTarget(); processAllMessages(); + + verify(mSimulatedCommandsVerifier).sendDeviceState(eq(CHARGING_STATE), + anyBoolean(), nullable(Message.class)); + verify(mSimulatedCommandsVerifier).sendDeviceState(eq(LOW_DATA_EXPECTED), + anyBoolean(), nullable(Message.class)); + verify(mSimulatedCommandsVerifier).sendDeviceState(eq(POWER_SAVE_MODE), + anyBoolean(), nullable(Message.class)); + verify(mSimulatedCommandsVerifier).setUnsolResponseFilter(anyInt(), + nullable(Message.class)); } @Test @MediumTest - public void testWifi() { - // screen off - sendStates(0, 0, 0); + public void testComputeCellInfoMinInternal() { + // by default, screen is off, charging is off and wifi is off assertEquals( DeviceStateMonitor.CELL_INFO_INTERVAL_LONG_MS, mDSM.computeCellInfoMinInterval()); - // screen off, but charging - sendStates(0, 1, 0); + + // keep screen off, but turn charging on + updateState(STATE_TYPE_CHARGING, STATE_ON); assertEquals( DeviceStateMonitor.CELL_INFO_INTERVAL_LONG_MS, mDSM.computeCellInfoMinInterval()); - // screen on, no wifi - sendStates(1, 0, 0); + + // turn screen on, turn charging off and keep wifi off + updateState(STATE_TYPE_SCREEN, STATE_ON); + updateState(STATE_TYPE_CHARGING, STATE_OFF); assertEquals( DeviceStateMonitor.CELL_INFO_INTERVAL_SHORT_MS, mDSM.computeCellInfoMinInterval()); + // screen on, but on wifi - sendStates(1, 0, 1); + updateState(STATE_TYPE_WIFI_CONNECTED, STATE_ON); assertEquals( DeviceStateMonitor.CELL_INFO_INTERVAL_LONG_MS, mDSM.computeCellInfoMinInterval()); + // screen on, charging - sendStates(1, 1, 0); + updateState(STATE_TYPE_WIFI_CONNECTED, STATE_OFF); + updateState(STATE_TYPE_CHARGING, STATE_OFF); assertEquals( DeviceStateMonitor.CELL_INFO_INTERVAL_SHORT_MS, mDSM.computeCellInfoMinInterval()); } |