summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorSunil Ravi <sunilravi@google.com>2019-11-08 22:57:25 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-11-08 22:57:25 +0000
commit60b1df7a8c879e00b86d4ca1d3d7edfcac42f5fc (patch)
tree2ca865c7c86f2fd1293cd332428b1a63790df287 /service
parentd8b3d7c285b24a1b1e22721631c7bdb3c31ef3e1 (diff)
parent7a541e4f82801e22f62b4e6b91a641d32935df30 (diff)
Merge "wifi: MBO-OCE feature support (phase 1)"
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java9
-rw-r--r--service/java/com/android/server/wifi/MboOceController.java124
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHal.java101
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java4
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java15
5 files changed, 250 insertions, 3 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 87c7e049a..720b3dccb 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -221,6 +221,7 @@ public class ClientModeImpl extends StateMachine {
private final PasspointManager mPasspointManager;
private final WifiDataStall mWifiDataStall;
private final LinkProbeManager mLinkProbeManager;
+ private final MboOceController mMboOceController;
private final McastLockManagerFilterController mMcastLockManagerFilterController;
private final ActivityManager mActivityManager;
@@ -709,7 +710,8 @@ public class ClientModeImpl extends StateMachine {
SarManager sarManager, WifiTrafficPoller wifiTrafficPoller,
LinkProbeManager linkProbeManager,
BatteryStatsManager batteryStatsManager,
- SupplicantStateTracker supplicantStateTracker) {
+ SupplicantStateTracker supplicantStateTracker,
+ MboOceController mboOceController) {
super(TAG, looper);
mWifiInjector = wifiInjector;
mWifiMetrics = mWifiInjector.getWifiMetrics();
@@ -725,6 +727,7 @@ public class ClientModeImpl extends StateMachine {
mSarManager = sarManager;
mWifiTrafficPoller = wifiTrafficPoller;
mLinkProbeManager = linkProbeManager;
+ mMboOceController = mboOceController;
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
mBatteryStatsManager = batteryStatsManager;
@@ -1118,6 +1121,7 @@ public class ClientModeImpl extends StateMachine {
mPasspointManager.enableVerboseLogging(verbose);
mNetworkFactory.enableVerboseLogging(verbose);
mLinkProbeManager.enableVerboseLogging(mVerboseLoggingEnabled);
+ mMboOceController.enableVerboseLogging(mVerboseLoggingEnabled);
}
private static final String SYSTEM_PROPERTY_LOG_CONTROL_WIFIHAL = "log.tag.WifiHAL";
@@ -3303,6 +3307,8 @@ public class ClientModeImpl extends StateMachine {
mWifiDiagnostics.startPktFateMonitoring(mInterfaceName);
mWifiDiagnostics.startLogging(mInterfaceName);
+ mMboOceController.enable();
+
/**
* Enable bluetooth coexistence scan mode when bluetooth connection is active.
* When this mode is on, some of the low-level scan parameters used by the
@@ -3339,6 +3345,7 @@ public class ClientModeImpl extends StateMachine {
// exiting supplicant started state is now only applicable to client mode
mWifiDiagnostics.stopLogging(mInterfaceName);
+ mMboOceController.disable();
if (mIpClient != null && mIpClient.shutdown()) {
// Block to make sure IpClient has really shut down, lest cleanup
// race with, say, bringup code over in tethering.
diff --git a/service/java/com/android/server/wifi/MboOceController.java b/service/java/com/android/server/wifi/MboOceController.java
new file mode 100644
index 000000000..9104a42b7
--- /dev/null
+++ b/service/java/com/android/server/wifi/MboOceController.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2019 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.net.wifi.WifiManager.WIFI_FEATURE_MBO;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_OCE;
+
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+/**
+ * MboOceController is responsible for controlling MBO and OCE operations.
+ */
+public class MboOceController {
+ private static final String TAG = "MboOceController";
+
+ /** State of MBO/OCE module. */
+ private boolean mEnabled = false;
+ private boolean mIsMboSupported = false;
+ private boolean mIsOceSupported = false;
+ private boolean mVerboseLoggingEnabled = false;
+
+ private final WifiNative mWifiNative;
+ private final TelephonyManager mTelephonyManager;
+
+ /**
+ * Create new instance of MboOceController.
+ */
+ public MboOceController(TelephonyManager telephonyManager,
+ WifiNative wifiNative) {
+ mTelephonyManager = telephonyManager;
+ mWifiNative = wifiNative;
+ }
+
+ /**
+ * Enable MBO and OCE functionality.
+ */
+ public void enable() {
+ String iface = mWifiNative.getClientInterfaceName();
+ if (iface == null) {
+ return;
+ }
+ mIsMboSupported = (mWifiNative.getSupportedFeatureSet(iface) & WIFI_FEATURE_MBO) != 0;
+ mIsOceSupported = (mWifiNative.getSupportedFeatureSet(iface) & WIFI_FEATURE_OCE) != 0;
+ mEnabled = true;
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "Enable MBO-OCE MBO support: " + mIsMboSupported
+ + " OCE support: " + mIsOceSupported);
+ }
+ if (mIsMboSupported) {
+ // Register for data connection state change events (Cellular).
+ mTelephonyManager.listen(mDataConnectionStateListener,
+ PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
+ }
+ }
+
+ /**
+ * Disable MBO and OCE functionality.
+ */
+ public void disable() {
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "Disable MBO-OCE");
+ }
+ if (mIsMboSupported) {
+ // Un-register for data connection state change events (Cellular).
+ mTelephonyManager.listen(mDataConnectionStateListener, PhoneStateListener.LISTEN_NONE);
+ }
+ mEnabled = false;
+ }
+
+ /**
+ * Enable/Disable verbose logging.
+ *
+ * @param verbose true to enable and false to disable.
+ */
+ public void enableVerboseLogging(boolean verbose) {
+ mVerboseLoggingEnabled = verbose;
+ }
+
+ /**
+ * Listen for changes to the data connection state (Cellular).
+ */
+ private PhoneStateListener mDataConnectionStateListener = new PhoneStateListener(){
+ public void onDataConnectionStateChanged(int state, int networkType) {
+ boolean dataAvailable;
+
+ String iface = mWifiNative.getClientInterfaceName();
+ if (iface == null) {
+ return;
+ }
+ if (!mEnabled) {
+ Log.e(TAG, "onDataConnectionStateChanged called when MBO is disabled!!");
+ return;
+ }
+ if (state == TelephonyManager.DATA_CONNECTED) {
+ dataAvailable = true;
+ } else if (state == TelephonyManager.DATA_DISCONNECTED) {
+ dataAvailable = false;
+ } else {
+ Log.e(TAG, "onDataConnectionStateChanged unexpected State: " + state);
+ return;
+ }
+ if (mVerboseLoggingEnabled) {
+ Log.d(TAG, "Cell Data: " + dataAvailable);
+ }
+ mWifiNative.setMboCellularDataStatus(iface, dataAvailable);
+ }
+ };
+}
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
index 64a9c1f4e..f0baa61d5 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
@@ -16,6 +16,8 @@
package com.android.server.wifi;
import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_MBO;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_OCE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SAE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_WPA3_SUITE_B;
@@ -34,6 +36,7 @@ import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
import android.hardware.wifi.supplicant.V1_0.WpsConfigMethods;
import android.hardware.wifi.supplicant.V1_3.ConnectionCapabilities;
import android.hardware.wifi.supplicant.V1_3.WifiTechnology;
+import android.hardware.wifi.supplicant.V1_3.WpaDriverCapabilitiesMask;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
import android.net.wifi.ScanResult;
@@ -2696,6 +2699,64 @@ public class SupplicantStaIfaceHal {
return keyMgmtMask.value;
}
+ /**
+ * Get the driver supported features through supplicant.
+ *
+ * @param ifaceName Name of the interface.
+ * @return bitmask defined by WifiManager.WIFI_FEATURE_*.
+ */
+ public long getWpaDriverFeatureSet(@NonNull String ifaceName) {
+ final String methodStr = "getWpaDriverFeatureSet";
+ MutableInt drvCapabilitiesMask = new MutableInt(0);
+ long featureSet = 0;
+
+ if (isV1_3()) {
+ ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr);
+ if (iface == null) {
+ return 0;
+ }
+ // Get a v1.3 supplicant STA Interface
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface staIfaceV13 =
+ getStaIfaceMockableV1_3(iface);
+ if (staIfaceV13 == null) {
+ Log.e(TAG, methodStr
+ + ": SupplicantStaIface is null, cannot get wpa driver features");
+ return 0;
+ }
+
+ try {
+ staIfaceV13.getWpaDriverCapabilities(
+ (SupplicantStatus statusInternal, int drvCapabilities) -> {
+ if (statusInternal.code == SupplicantStatusCode.SUCCESS) {
+ drvCapabilitiesMask.value = drvCapabilities;
+ }
+ checkStatusAndLogFailure(statusInternal, methodStr);
+ });
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ } else {
+ Log.i(TAG, "Method " + methodStr + " is not supported in existing HAL");
+ return 0;
+ }
+
+ if ((drvCapabilitiesMask.value & WpaDriverCapabilitiesMask.MBO) != 0) {
+ featureSet |= WIFI_FEATURE_MBO;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, methodStr + ": MBO supported");
+ }
+ if ((drvCapabilitiesMask.value
+ & WpaDriverCapabilitiesMask.OCE) != 0) {
+ featureSet |= WIFI_FEATURE_OCE;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, methodStr + ": OCE supported");
+ }
+ }
+ }
+
+ return featureSet;
+ }
+
private @ScanResult.WifiStandard int getWifiStandardFromCap(ConnectionCapabilities capa) {
switch(capa.technology) {
case WifiTechnology.HE:
@@ -2988,4 +3049,44 @@ public class SupplicantStaIfaceHal {
protected DppEventCallback getDppCallback() {
return mDppCallback;
}
+
+ /**
+ * Set MBO cellular data availability.
+ *
+ * @param ifaceName Name of the interface.
+ * @param available true means cellular data available, false otherwise.
+ * @return None.
+ */
+ public boolean setMboCellularDataStatus(@NonNull String ifaceName, boolean available) {
+ final String methodStr = "setMboCellularDataStatus";
+
+ if (isV1_3()) {
+ ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr);
+ if (iface == null) {
+ return false;
+ }
+
+ // Get a v1.3 supplicant STA Interface
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface staIfaceV13 =
+ getStaIfaceMockableV1_3(iface);
+ if (staIfaceV13 == null) {
+ Log.e(TAG, methodStr
+ + ": SupplicantStaIface is null, cannot update cell status");
+ return false;
+ }
+
+ try {
+ SupplicantStatus status = staIfaceV13.setMboCellularDataStatus(available);
+ return checkStatusAndLogFailure(status, methodStr);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodStr);
+ }
+ } else {
+ Log.e(TAG, "Method " + methodStr + " is not supported in existing HAL");
+ return false;
+ }
+
+ return false;
+ }
+
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index abf9dfab1..13f6a8267 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -153,6 +153,7 @@ public class WifiInjector {
private final WifiThreadRunner mWifiThreadRunner;
private BssidBlocklistMonitor mBssidBlocklistMonitor;
private final MacAddressUtil mMacAddressUtil;
+ private final MboOceController mMboOceController;
public WifiInjector(Context context) {
if (context == null) {
@@ -306,12 +307,13 @@ public class WifiInjector {
mFrameworkFacade, wifiHandler, mContext);
SupplicantStateTracker supplicantStateTracker = new SupplicantStateTracker(
mContext, mWifiConfigManager, mBatteryStats, wifiHandler);
+ mMboOceController = new MboOceController(makeTelephonyManager(), mWifiNative);
mClientModeImpl = new ClientModeImpl(mContext, mFrameworkFacade,
wifiLooper, mUserManager,
this, mBackupManagerProxy, mCountryCode, mWifiNative,
new WrongPasswordNotifier(mContext, mFrameworkFacade),
mSarManager, mWifiTrafficPoller, mLinkProbeManager, mBatteryStats,
- supplicantStateTracker);
+ supplicantStateTracker, mMboOceController);
mActiveModeWarden = new ActiveModeWarden(this, wifiLooper,
mWifiNative, new DefaultModeManager(mContext), mBatteryStats, mWifiDiagnostics,
mContext, mClientModeImpl, mSettingsStore, mFrameworkFacade, mWifiPermissionsUtil);
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 2b3e50ed5..eeef34fc3 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -2725,7 +2725,8 @@ public class WifiNative {
*/
private long getSupportedFeatureSetInternal(@NonNull String ifaceName) {
return mSupplicantStaIfaceHal.getAdvancedKeyMgmtCapabilities(ifaceName)
- | mWifiVendorHal.getSupportedFeatureSet(ifaceName);
+ | mWifiVendorHal.getSupportedFeatureSet(ifaceName)
+ | mSupplicantStaIfaceHal.getWpaDriverFeatureSet(ifaceName);
}
/**
@@ -3346,6 +3347,18 @@ public class WifiNative {
return mWifiVendorHal.selectTxPowerScenario(sarInfo);
}
+ /**
+ * Set MBO cellular data status
+ *
+ * @param ifaceName Name of the interface.
+ * @param available cellular data status,
+ * true means cellular data available, false otherwise.
+ */
+ public void setMboCellularDataStatus(@NonNull String ifaceName, boolean available) {
+ mSupplicantStaIfaceHal.setMboCellularDataStatus(ifaceName, available);
+ return;
+ }
+
/********************************************************
* JNI operations
********************************************************/