diff options
author | Ahmed ElArabawy <arabawy@google.com> | 2018-03-09 10:30:50 -0800 |
---|---|---|
committer | Ahmed ElArabawy <arabawy@google.com> | 2018-05-02 16:47:03 -0700 |
commit | d55d1c65e5f4569652492828e4ab3eb201921ae8 (patch) | |
tree | b1aedba7810af11c51f59900aba9fb3ae27b9a97 /service | |
parent | 6b9f7ba3c20a01689c1027043b6e6eb5b253348e (diff) |
WiFi: Move SAR implementation to SarManager
This commit is the first stage of extending SAR Support in WiFi.
This stage include removing SAR handling from the WifiStateMachine and
putting it in a separate SarManager.
No new functionality is added yet in this stage.
Note that unit test cases for SAR related functionality in WifiStateMachine
are removed and added to SarManager
Bug: 65174506
Test: Run Wifi unit test suite
Test: ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: I0a08180cfff22002f75a6966009e62b9c66044c3
Signed-off-by: Ahmed ElArabawy <arabawy@google.com>
Diffstat (limited to 'service')
3 files changed, 262 insertions, 65 deletions
diff --git a/service/java/com/android/server/wifi/SarManager.java b/service/java/com/android/server/wifi/SarManager.java new file mode 100644 index 000000000..da48a8537 --- /dev/null +++ b/service/java/com/android/server/wifi/SarManager.java @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.wifi; + +import static android.telephony.TelephonyManager.CALL_STATE_IDLE; +import static android.telephony.TelephonyManager.CALL_STATE_OFFHOOK; +import static android.telephony.TelephonyManager.CALL_STATE_RINGING; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.wifi.WifiManager; +import android.os.Looper; +import android.telephony.PhoneStateListener; +import android.telephony.TelephonyManager; +import android.util.Log; + +import com.android.internal.R; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.List; + +/** + * This class provides the Support for SAR to control WiFi TX power limits. + * It deals with the following: + * - Tracking the STA state through calls from the ClientModeManager. + * - Tracking the state of the Cellular calls or data. + * - Based on above, selecting the SAR profile to use and programming it in wifi hal. + */ +public class SarManager { + + /* For Logging */ + private static final String TAG = "WifiSarManager"; + private boolean mVerboseLoggingEnabled = true; + + /* Configuration for SAR */ + private boolean mEnableSarTxPowerLimit; + + /* Current SAR Scenario */ + private int mCurrentSarScenario = WifiNative.TX_POWER_SCENARIO_NORMAL; + + /* Booleans for Cell and wifi states */ + private boolean mCellOn = false; + private boolean mWifiStaEnabled = false; + /** + * Other parameters passed in or created in the constructor. + */ + private final Context mContext; + private final TelephonyManager mTelephonyManager; + private final WifiPhoneStateListener mPhoneStateListener; + private final WifiNative mWifiNative; + private final Looper mLooper; + + /** + * Create new instance of SarManager. + */ + SarManager(Context context, + TelephonyManager telephonyManager, + Looper looper, + WifiNative wifiNative) { + mContext = context; + mTelephonyManager = telephonyManager; + mWifiNative = wifiNative; + mLooper = looper; + mPhoneStateListener = new WifiPhoneStateListener(looper); + + registerListeners(); + } + + /** + * Starts the SAR Manager by initializing the different listeners + */ + private void registerListeners() { + /* First read the configuration for SAR Support */ + mEnableSarTxPowerLimit = mContext.getResources().getBoolean( + R.bool.config_wifi_framework_enable_voice_call_sar_tx_power_limit); + + /* Only Start listening for events if SAR is enabled */ + if (mEnableSarTxPowerLimit) { + Log.d(TAG, "Registering Listeners for the SAR Manager"); + + /* Listen for Phone State changes */ + registerPhoneListener(); + } + } + + /** + * Report Cell state event + */ + private void onCellStateChangeEvent(int state) { + boolean currentCellOn = mCellOn; + + switch (state) { + case CALL_STATE_OFFHOOK: + case CALL_STATE_RINGING: + mCellOn = true; + break; + + case CALL_STATE_IDLE: + mCellOn = false; + break; + + default: + Log.e(TAG, "Invalid Cell State: " + state); + } + + if (mCellOn != currentCellOn) { + updateSarScenario(); + } + } + + /** + * Update Wifi Client State + */ + public void setClientWifiState(int state) { + /* No action is taken if SAR is not enabled */ + if (!mEnableSarTxPowerLimit) return; + + if (state == WifiManager.WIFI_STATE_DISABLED && mWifiStaEnabled) { + mWifiStaEnabled = false; + } else if (state == WifiManager.WIFI_STATE_ENABLED && !mWifiStaEnabled) { + mWifiStaEnabled = true; + + /* Since no wifi interface was up, + time for SAR scenario to take effect */ + sendTxPowerScenario(mCurrentSarScenario); + } + } + + /** + * Enable/disable verbose logging. + */ + public void enableVerboseLogging(int verbose) { + Log.d(TAG, "Inside enableVerboseLogging: " + verbose); + if (verbose > 0) { + mVerboseLoggingEnabled = true; + } else { + mVerboseLoggingEnabled = false; + } + } + + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.println("*** WiFi SAR Manager Dump ***"); + pw.println("Current SAR Scenario is " + scenarioToString(mCurrentSarScenario)); + } + + /** + * Register the phone listener. + */ + private void registerPhoneListener() { + Log.i(TAG, "Registering for telephony call state changes"); + mTelephonyManager.listen( + mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); + } + + /** + * Listen for phone call state events to set/reset TX power limits for SAR requirements. + */ + private class WifiPhoneStateListener extends PhoneStateListener { + WifiPhoneStateListener(Looper looper) { + super(looper); + } + + @Override + public void onCallStateChanged(int state, String incomingNumber) { + Log.d(TAG, "Received Phone State Change: " + state); + + /* In case of an unsolicited event */ + if (!mEnableSarTxPowerLimit) return; + + onCellStateChangeEvent(state); + } + } + + /** + * update the Current SAR Scenario based on factors including: + * - Do we have an ongoing cellular voice call. + */ + private void updateSarScenario() { + int newSarScenario; + + if (mCellOn) { + newSarScenario = WifiNative.TX_POWER_SCENARIO_VOICE_CALL; + } else { + newSarScenario = WifiNative.TX_POWER_SCENARIO_NORMAL; + } + + if (newSarScenario != mCurrentSarScenario) { + + // Only update HAL with new scenario if WiFi interface is enabled + if (mWifiStaEnabled) { + Log.d(TAG, "Sending SAR Scenario #" + scenarioToString(newSarScenario)); + sendTxPowerScenario(newSarScenario); + } + + mCurrentSarScenario = newSarScenario; + } + } + + /** + * sendTxPowerScenario() + * Update HAL with the new power scenario. + */ + private void sendTxPowerScenario(int newSarScenario) { + if (!mWifiNative.selectTxPowerScenario(newSarScenario)) { + Log.e(TAG, "Failed to set TX power scenario"); + } + } + + /** + * Convert SAR Scenario to string + */ + private String scenarioToString(int scenario) { + String str; + switch(scenario) { + case WifiNative.TX_POWER_SCENARIO_NORMAL: + str = "TX_POWER_SCENARIO_NORMAL"; + break; + case WifiNative.TX_POWER_SCENARIO_VOICE_CALL: + str = "TX_POWER_SCENARIO_VOICE_CALL"; + break; + default: + str = "Invalid Scenario"; + break; + } + + return str; + } +} diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java index a64075006..7fc49ece2 100644 --- a/service/java/com/android/server/wifi/WifiInjector.java +++ b/service/java/com/android/server/wifi/WifiInjector.java @@ -137,6 +137,7 @@ public class WifiInjector { private final WakeupController mWakeupController; private final INetworkManagementService mNwManagementService; private final ScanRequestProxy mScanRequestProxy; + private final SarManager mSarManager; private final boolean mUseRealLogger; @@ -252,10 +253,13 @@ public class WifiInjector { mWifiPermissionsUtil, mWifiMetrics, mClock); // mWifiStateMachine has an implicit dependency on mJavaRuntime due to WifiDiagnostics. mJavaRuntime = Runtime.getRuntime(); + mSarManager = new SarManager(mContext, makeTelephonyManager(), wifiStateMachineLooper, + mWifiNative); mWifiStateMachine = new WifiStateMachine(mContext, mFrameworkFacade, wifiStateMachineLooper, UserManager.get(mContext), this, mBackupManagerProxy, mCountryCode, mWifiNative, - new WrongPasswordNotifier(mContext, mFrameworkFacade)); + new WrongPasswordNotifier(mContext, mFrameworkFacade), + mSarManager); IBinder b = mFrameworkFacade.getService(Context.NETWORKMANAGEMENT_SERVICE); mWifiStateMachinePrime = new WifiStateMachinePrime(this, mContext, wifiStateMachineLooper, mWifiNative, new DefaultModeManager(mContext, wifiStateMachineLooper), @@ -358,6 +362,10 @@ public class WifiInjector { return mWifiApConfigStore; } + public SarManager getSarManager() { + return mSarManager; + } + public WifiStateMachine getWifiStateMachine() { return mWifiStateMachine; } diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index af0b8c257..6b0bec244 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -21,8 +21,6 @@ import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING; import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING; import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN; -import static android.telephony.TelephonyManager.CALL_STATE_IDLE; -import static android.telephony.TelephonyManager.CALL_STATE_OFFHOOK; import android.app.ActivityManager; import android.app.PendingIntent; @@ -81,7 +79,6 @@ import android.os.UserManager; import android.os.WorkSource; import android.provider.Settings; import android.system.OsConstants; -import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; @@ -199,6 +196,7 @@ public class WifiStateMachine extends StateMachine { private final WifiCountryCode mCountryCode; // Object holding most recent wifi score report and bad Linkspeed count private final WifiScoreReport mWifiScoreReport; + private final SarManager mSarManager; public WifiScoreReport getWifiScoreReport() { return mWifiScoreReport; } @@ -643,9 +641,6 @@ public class WifiStateMachine extends StateMachine { /* Indicates that diagnostics should time out a connection start event. */ private static final int CMD_DIAGS_CONNECT_TIMEOUT = BASE + 252; - /* Used to set the tx power limit for SAR during the start of a phone call. */ - private static final int CMD_SELECT_TX_POWER_SCENARIO = BASE + 253; - // Start subscription provisioning with a given provider private static final int CMD_START_SUBSCRIPTION_PROVISIONING = BASE + 254; @@ -709,7 +704,6 @@ public class WifiStateMachine extends StateMachine { private final int mThresholdMinimumRssi24; private final boolean mEnableChipWakeUpWhenAssociated; private final boolean mEnableRssiPollWhenAssociated; - private final boolean mEnableVoiceCallSarTxPowerLimit; int mRunningBeaconCount = 0; @@ -771,7 +765,6 @@ public class WifiStateMachine extends StateMachine { } return mTelephonyManager; } - private final WifiPhoneStateListener mPhoneStateListener; private final IBatteryStats mBatteryStats; @@ -789,7 +782,8 @@ public class WifiStateMachine extends StateMachine { UserManager userManager, WifiInjector wifiInjector, BackupManagerProxy backupManagerProxy, WifiCountryCode countryCode, WifiNative wifiNative, - WrongPasswordNotifier wrongPasswordNotifier) { + WrongPasswordNotifier wrongPasswordNotifier, + SarManager sarManager) { super("WifiStateMachine", looper); mWifiInjector = wifiInjector; mWifiMetrics = mWifiInjector.getWifiMetrics(); @@ -801,6 +795,7 @@ public class WifiStateMachine extends StateMachine { mWifiNative = wifiNative; mBackupManagerProxy = backupManagerProxy; mWrongPasswordNotifier = wrongPasswordNotifier; + mSarManager = sarManager; // TODO refactor WifiNative use of context out into it's own class mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, ""); @@ -827,7 +822,6 @@ public class WifiStateMachine extends StateMachine { mFacade.makeSupplicantStateTracker(context, mWifiConfigManager, getHandler()); mLinkProperties = new LinkProperties(); - mPhoneStateListener = new WifiPhoneStateListener(looper); mMcastLockManagerFilterController = new McastLockManagerFilterController(); mNetworkInfo.setIsAvailable(false); @@ -922,8 +916,6 @@ public class WifiStateMachine extends StateMachine { R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz); mThresholdMinimumRssi24 = context.getResources().getInteger( R.integer.config_wifi_framework_wifi_score_bad_rssi_threshold_24GHz); - mEnableVoiceCallSarTxPowerLimit = mContext.getResources().getBoolean( - R.bool.config_wifi_framework_enable_voice_call_sar_tx_power_limit); mEnableChipWakeUpWhenAssociated = true; mEnableRssiPollWhenAssociated = true; @@ -3216,40 +3208,6 @@ public class WifiStateMachine extends StateMachine { } } - /** - * Register the phone listener if we need to set/reset the power limits during voice call for - * this device. - */ - private void maybeRegisterPhoneListener() { - if (mEnableVoiceCallSarTxPowerLimit) { - logd("Registering for telephony call state changes"); - getTelephonyManager().listen( - mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); - } - } - - /** - * Listen for phone call state events to set/reset TX power limits for SAR requirements. - */ - private class WifiPhoneStateListener extends PhoneStateListener { - WifiPhoneStateListener(Looper looper) { - super(looper); - } - - @Override - public void onCallStateChanged(int state, String incomingNumber) { - if (mEnableVoiceCallSarTxPowerLimit) { - if (state == CALL_STATE_OFFHOOK) { - sendMessage(CMD_SELECT_TX_POWER_SCENARIO, - WifiNative.TX_POWER_SCENARIO_VOICE_CALL); - } else if (state == CALL_STATE_IDLE) { - sendMessage(CMD_SELECT_TX_POWER_SCENARIO, - WifiNative.TX_POWER_SCENARIO_NORMAL); - } - } - } - } - /** * Dynamically change the MAC address to use the locally randomized * MAC address generated for each network. @@ -3416,7 +3374,6 @@ public class WifiStateMachine extends StateMachine { Log.e(TAG, "Failed to load from config store"); } maybeRegisterNetworkFactory(); - maybeRegisterPhoneListener(); break; case CMD_SCREEN_STATE_CHANGED: handleScreenStateChanged(message.arg1 != 0); @@ -3448,7 +3405,6 @@ public class WifiStateMachine extends StateMachine { case CMD_ROAM_WATCHDOG_TIMER: case CMD_DISABLE_P2P_WATCHDOG_TIMER: case CMD_DISABLE_EPHEMERAL_NETWORK: - case CMD_SELECT_TX_POWER_SCENARIO: messageHandlingStatus = MESSAGE_HANDLING_STATUS_DISCARD; break; case CMD_SET_OPERATIONAL_MODE: @@ -3762,14 +3718,6 @@ public class WifiStateMachine extends StateMachine { * driver are changed to reduce interference with bluetooth */ mWifiNative.setBluetoothCoexistenceScanMode(mInterfaceName, mBluetoothConnectionActive); - // Check if there is a voice call on-going and set/reset the tx power limit appropriately. - if (mEnableVoiceCallSarTxPowerLimit) { - if (getTelephonyManager().isOffhook()) { - sendMessage(CMD_SELECT_TX_POWER_SCENARIO, WifiNative.TX_POWER_SCENARIO_VOICE_CALL); - } else { - sendMessage(CMD_SELECT_TX_POWER_SCENARIO, WifiNative.TX_POWER_SCENARIO_NORMAL); - } - } // initialize network state setNetworkDetailedState(DetailedState.DISCONNECTED); @@ -3903,6 +3851,8 @@ public class WifiStateMachine extends StateMachine { mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISCONNECTED); // Inform p2p service that wifi is up and ready when applicable p2pSendMessage(WifiStateMachine.CMD_ENABLE_P2P); + // Inform sar manager that wifi is Enabled + mSarManager.setClientWifiState(WifiManager.WIFI_STATE_ENABLED); } @Override @@ -3916,6 +3866,8 @@ public class WifiStateMachine extends StateMachine { mWifiConnectivityManager.setWifiEnabled(false); // Inform metrics that Wifi is being disabled (Toggled, airplane enabled, etc) mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_DISABLED); + // Inform sar manager that wifi is being disabled + mSarManager.setClientWifiState(WifiManager.WIFI_STATE_DISABLED); if (!mWifiNative.removeAllNetworks(mInterfaceName)) { loge("Failed to remove networks on exiting connect mode"); @@ -4530,14 +4482,6 @@ public class WifiStateMachine extends StateMachine { case CMD_ENABLE_WIFI_CONNECTIVITY_MANAGER: mWifiConnectivityManager.enable(message.arg1 == 1 ? true : false); break; - case CMD_SELECT_TX_POWER_SCENARIO: - int txPowerScenario = message.arg1; - logd("Setting Tx power scenario to " + txPowerScenario); - if (!mWifiNative.selectTxPowerScenario(txPowerScenario)) { - loge("Failed to set TX power scenario"); - } - break; - default: return NOT_HANDLED; } |