diff options
author | Sunil Ravi <sunilravi@google.com> | 2019-11-08 22:57:25 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-11-08 22:57:25 +0000 |
commit | 60b1df7a8c879e00b86d4ca1d3d7edfcac42f5fc (patch) | |
tree | 2ca865c7c86f2fd1293cd332428b1a63790df287 /service | |
parent | d8b3d7c285b24a1b1e22721631c7bdb3c31ef3e1 (diff) | |
parent | 7a541e4f82801e22f62b4e6b91a641d32935df30 (diff) |
Merge "wifi: MBO-OCE feature support (phase 1)"
Diffstat (limited to 'service')
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 ********************************************************/ |