From b7f35c58029fe5dce64813271ad4e8b1b6ea8893 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 25 Jul 2017 08:50:31 -0700 Subject: wifi(framework): Modify the SAR power levels interface Modifying the interface used to lower the tx power level for meeting SAR requirements based on recommendation from the nexus hardware team. The previous interface passed in a single power value in dBm for meeting SAR requirements. However, the SAR requirements are more complex than that. Based on the connection mode (802.11 a,b,g,n,ac) and the number of streams that are active (MIMO), the SAR power levels are very different. Using the previous interface would mean that we will have to use the lowest power level among all the connection modes to meet the SAR requirements. This would however result in us lowering the power much more than needed (~2 dBm) for many connection modes. Instead, we're switching to a more generic interface where the framework informs the wifi chip that we're entering a special tx power mode scenario (today, there is only 1 for voice call). The chip can then lookup the extensive table of power levels for different connection modes which are pre-populated by the OEM's in the BDF file to set the power level (depending on the scenario framework sends and the active connection mode). Bug: 62437848 Test: Unit tests. Test: Manual tests. Change-Id: I26737259cf56b44ab18d907ab23603e14a7e3739 --- .../android/server/wifi/WifiStateMachineTest.java | 84 ++++++++++++++++------ .../com/android/server/wifi/WifiVendorHalTest.java | 51 ++++++++----- 2 files changed, 96 insertions(+), 39 deletions(-) (limited to 'tests') diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java index 10d6460ab..427d700b1 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java @@ -1902,7 +1902,7 @@ public class WifiStateMachineTest { * setting/resetting Tx power limit. */ @Test - public void testVoiceCallSar_disabledTxPowerLimit_WifiOn() throws Exception { + public void testVoiceCallSar_disabledTxPowerScenario_WifiOn() throws Exception { loadComponentsInStaMode(); mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); @@ -1915,7 +1915,7 @@ public class WifiStateMachineTest { * setting/resetting Tx power limit. */ @Test - public void testVoiceCallSar_enabledTxPowerLimit_WifiOn() throws Exception { + public void testVoiceCallSar_enabledTxPowerScenario_WifiOn() throws Exception { mResources.setBoolean( R.bool.config_wifi_framework_enable_voice_call_sar_tx_power_limit, true); initializeWsm(); @@ -1933,16 +1933,13 @@ public class WifiStateMachineTest { * {@link TelephonyManager#CALL_STATE_OFFHOOK}. */ @Test - public void testVoiceCallSar_enabledTxPowerLimitCallStateOffHook_WhenWifiTurnedOn() + public void testVoiceCallSar_enabledTxPowerScenarioCallStateOffHook_WhenWifiTurnedOn() throws Exception { - int powerLevelInDbm = -45; - mResources.setInteger( - R.integer.config_wifi_framework_voice_call_sar_tx_power_limit_in_dbm, - powerLevelInDbm); mResources.setBoolean( R.bool.config_wifi_framework_enable_voice_call_sar_tx_power_limit, true); initializeWsm(); + when(mWifiNative.selectTxPowerScenario(anyInt())).thenReturn(true); when(mTelephonyManager.isOffhook()).thenReturn(true); loadComponentsInStaMode(); @@ -1950,7 +1947,7 @@ public class WifiStateMachineTest { assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); assertEquals("DisconnectedState", getCurrentState().getName()); assertNotNull(mPhoneStateListener); - verify(mWifiNative).setTxPowerLimit(eq(powerLevelInDbm)); + verify(mWifiNative).selectTxPowerScenario(eq(WifiNative.TX_POWER_SCENARIO_VOICE_CALL)); } /** @@ -1959,12 +1956,13 @@ public class WifiStateMachineTest { * {@link TelephonyManager#CALL_STATE_IDLE}. */ @Test - public void testVoiceCallSar_enabledTxPowerLimitCallStateIdle_WhenWifiTurnedOn() + public void testVoiceCallSar_enabledTxPowerScenarioCallStateIdle_WhenWifiTurnedOn() throws Exception { mResources.setBoolean( R.bool.config_wifi_framework_enable_voice_call_sar_tx_power_limit, true); initializeWsm(); + when(mWifiNative.selectTxPowerScenario(anyInt())).thenReturn(true); when(mTelephonyManager.isIdle()).thenReturn(true); loadComponentsInStaMode(); @@ -1972,7 +1970,30 @@ public class WifiStateMachineTest { assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); assertEquals("DisconnectedState", getCurrentState().getName()); assertNotNull(mPhoneStateListener); - verify(mWifiNative).resetTxPowerLimit(); + } + + /** + * Test that we do register the telephony call state listener on devices which do support + * setting/resetting Tx power limit and set the tx power level if we're in state + * {@link TelephonyManager#CALL_STATE_OFFHOOK}. This test checks if the + * {@link WifiNative#selectTxPowerScenario(int)} failure is handled correctly. + */ + @Test + public void testVoiceCallSar_enabledTxPowerScenarioCallStateOffHook_WhenWifiTurnedOn_Fails() + throws Exception { + mResources.setBoolean( + R.bool.config_wifi_framework_enable_voice_call_sar_tx_power_limit, true); + initializeWsm(); + + when(mWifiNative.selectTxPowerScenario(anyInt())).thenReturn(false); + when(mTelephonyManager.isOffhook()).thenReturn(true); + + loadComponentsInStaMode(); + mWsm.setOperationalMode(WifiStateMachine.CONNECT_MODE); + assertEquals(WifiStateMachine.CONNECT_MODE, mWsm.getOperationalModeForTest()); + assertEquals("DisconnectedState", getCurrentState().getName()); + assertNotNull(mPhoneStateListener); + verify(mWifiNative).selectTxPowerScenario(eq(WifiNative.TX_POWER_SCENARIO_VOICE_CALL)); } /** @@ -1981,16 +2002,14 @@ public class WifiStateMachineTest { * {@link TelephonyManager#CALL_STATE_OFFHOOK}. */ @Test - public void testVoiceCallSar_enabledTxPowerLimitCallStateOffHook_WhenWifiOn() throws Exception { - int powerLevelInDbm = -45; - mResources.setInteger( - R.integer.config_wifi_framework_voice_call_sar_tx_power_limit_in_dbm, - powerLevelInDbm); - testVoiceCallSar_enabledTxPowerLimit_WifiOn(); + public void testVoiceCallSar_enabledTxPowerScenarioCallStateOffHook_WhenWifiOn() + throws Exception { + when(mWifiNative.selectTxPowerScenario(anyInt())).thenReturn(true); + testVoiceCallSar_enabledTxPowerScenario_WifiOn(); mPhoneStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK, ""); mLooper.dispatchAll(); - verify(mWifiNative).setTxPowerLimit(eq(powerLevelInDbm)); + verify(mWifiNative).selectTxPowerScenario(eq(WifiNative.TX_POWER_SCENARIO_VOICE_CALL)); } /** @@ -1999,12 +2018,31 @@ public class WifiStateMachineTest { * {@link TelephonyManager#CALL_STATE_IDLE}. */ @Test - public void testVoiceCallSar_enabledTxPowerLimitCallStateIdle_WhenWifiOn() throws Exception { - testVoiceCallSar_enabledTxPowerLimit_WifiOn(); + public void testVoiceCallSar_enabledTxPowerScenarioCallStateIdle_WhenWifiOn() throws Exception { + when(mWifiNative.selectTxPowerScenario(anyInt())).thenReturn(true); + testVoiceCallSar_enabledTxPowerScenario_WifiOn(); mPhoneStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_IDLE, ""); mLooper.dispatchAll(); - verify(mWifiNative).resetTxPowerLimit(); + verify(mWifiNative, atLeastOnce()) + .selectTxPowerScenario(eq(WifiNative.TX_POWER_SCENARIO_NORMAL)); + } + + /** + * Test that we invoke the corresponding WifiNative method when + * {@link PhoneStateListener#onCallStateChanged(int, String)} is invoked with state + * {@link TelephonyManager#CALL_STATE_OFFHOOK}. This test checks if the + * {@link WifiNative#selectTxPowerScenario(int)} failure is handled correctly. + */ + @Test + public void testVoiceCallSar_enabledTxPowerScenarioCallStateOffHook_WhenWifiOn_Fails() + throws Exception { + when(mWifiNative.selectTxPowerScenario(anyInt())).thenReturn(false); + testVoiceCallSar_enabledTxPowerScenario_WifiOn(); + + mPhoneStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK, ""); + mLooper.dispatchAll(); + verify(mWifiNative).selectTxPowerScenario(eq(WifiNative.TX_POWER_SCENARIO_VOICE_CALL)); } /** @@ -2014,18 +2052,18 @@ public class WifiStateMachineTest { * wifi is off (state machine is not in SupplicantStarted state). */ @Test - public void testVoiceCallSar_enabledTxPowerLimitCallState_WhenWifiOff() throws Exception { + public void testVoiceCallSar_enabledTxPowerScenarioCallState_WhenWifiOff() throws Exception { mResources.setBoolean( R.bool.config_wifi_framework_enable_voice_call_sar_tx_power_limit, true); initializeWsm(); mPhoneStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK, ""); mLooper.dispatchAll(); - verify(mWifiNative, never()).setTxPowerLimit(anyInt()); + verify(mWifiNative, never()).selectTxPowerScenario(anyInt()); mPhoneStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_IDLE, ""); mLooper.dispatchAll(); - verify(mWifiNative, never()).resetTxPowerLimit(); + verify(mWifiNative, never()).selectTxPowerScenario(anyInt()); } /** diff --git a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java index 3f2f389c5..84de9d227 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java @@ -1844,48 +1844,67 @@ public class WifiVendorHalTest { } /** - * Test the new setTxPowerLimit HIDL method invocation. This should return failure if the + * Test the new selectTxPowerScenario HIDL method invocation. This should return failure if the * HAL service is exposing the 1.0 interface. */ @Test - public void testSetTxPowerLimit() throws RemoteException { - int powerLevelInDbm = -45; - + public void testSelectTxPowerScenario() throws RemoteException { assertTrue(mWifiVendorHal.startVendorHal(true)); // Should fail because we exposed the 1.0 IWifiChip. - assertFalse(mWifiVendorHal.setTxPowerLimit(powerLevelInDbm)); - verify(mIWifiChipV11, never()).setTxPowerLimit(eq(powerLevelInDbm)); + assertFalse( + mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_VOICE_CALL)); + verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt()); mWifiVendorHal.stopVendorHal(); // Now expose the 1.1 IWifiChip. mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper()); - when(mIWifiChipV11.setTxPowerLimit(anyInt())).thenReturn(mWifiStatusSuccess); + when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess); assertTrue(mWifiVendorHal.startVendorHal(true)); - assertTrue(mWifiVendorHal.setTxPowerLimit(powerLevelInDbm)); - verify(mIWifiChipV11).setTxPowerLimit(eq(powerLevelInDbm)); + assertTrue( + mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_VOICE_CALL)); + verify(mIWifiChipV11).selectTxPowerScenario( + eq(android.hardware.wifi.V1_1.IWifiChip.TxPowerScenario.VOICE_CALL)); + verify(mIWifiChipV11, never()).resetTxPowerScenario(); mWifiVendorHal.stopVendorHal(); } /** - * Test the new setTxPowerLimit HIDL method invocation. This should return failure if the + * Test the new resetTxPowerScenario HIDL method invocation. This should return failure if the * HAL service is exposing the 1.0 interface. */ @Test - public void testResetTxPowerLimit() throws RemoteException { + public void testResetTxPowerScenario() throws RemoteException { assertTrue(mWifiVendorHal.startVendorHal(true)); // Should fail because we exposed the 1.0 IWifiChip. - assertFalse(mWifiVendorHal.resetTxPowerLimit()); - verify(mIWifiChipV11, never()).resetTxPowerLimit(); + assertFalse(mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_NORMAL)); + verify(mIWifiChipV11, never()).resetTxPowerScenario(); mWifiVendorHal.stopVendorHal(); // Now expose the 1.1 IWifiChip. mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper()); - when(mIWifiChipV11.resetTxPowerLimit()).thenReturn(mWifiStatusSuccess); + when(mIWifiChipV11.resetTxPowerScenario()).thenReturn(mWifiStatusSuccess); + + assertTrue(mWifiVendorHal.startVendorHal(true)); + assertTrue(mWifiVendorHal.selectTxPowerScenario(WifiNative.TX_POWER_SCENARIO_NORMAL)); + verify(mIWifiChipV11).resetTxPowerScenario(); + verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt()); + mWifiVendorHal.stopVendorHal(); + } + + /** + * Test the new selectTxPowerScenario HIDL method invocation with a bad scenario index. + */ + @Test + public void testInvalidSelectTxPowerScenario() throws RemoteException { + // Expose the 1.1 IWifiChip. + mWifiVendorHal = new WifiVendorHalSpyV1_1(mHalDeviceManager, mLooper.getLooper()); + when(mIWifiChipV11.selectTxPowerScenario(anyInt())).thenReturn(mWifiStatusSuccess); assertTrue(mWifiVendorHal.startVendorHal(true)); - assertTrue(mWifiVendorHal.resetTxPowerLimit()); - verify(mIWifiChipV11).resetTxPowerLimit(); + assertFalse(mWifiVendorHal.selectTxPowerScenario(-6)); + verify(mIWifiChipV11, never()).selectTxPowerScenario(anyInt()); + verify(mIWifiChipV11, never()).resetTxPowerScenario(); mWifiVendorHal.stopVendorHal(); } -- cgit v1.2.3