summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorAhmed ElArabawy <arabawy@google.com>2018-03-09 10:30:50 -0800
committerAhmed ElArabawy <arabawy@google.com>2018-05-02 16:47:03 -0700
commitd55d1c65e5f4569652492828e4ab3eb201921ae8 (patch)
treeb1aedba7810af11c51f59900aba9fb3ae27b9a97 /service
parent6b9f7ba3c20a01689c1027043b6e6eb5b253348e (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')
-rw-r--r--service/java/com/android/server/wifi/SarManager.java245
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java10
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java72
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;
}