summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRebecca Silberstein <silberst@google.com>2017-05-25 04:48:43 -0700
committerRebecca Silberstein <silberst@google.com>2017-06-06 11:14:55 -0700
commit1f6626d7488bba014b42bab8bbcd4720694df485 (patch)
tree546240ddc94ad22de73db2ed3ff6ea65c6abfcf6 /service
parent2f47b2755faffaa1a011ddeb8527bd9c99bb6106 (diff)
WifiStateMachine: add mode to softap update
Plumb the softap target mode in to WifiStateMachine so we can add it to the softap state change broadcast. Also cleaned up some of the error and stopping states noticed due to the mode updates and tests. This removes extra calls to clear the requests and uses the ap state change broadcast to notify registered callers about the LOHS stopping instead of attempting to get intermediate state. Bug: 62076211 Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: Icff0a9b30e1eb9e5aa945d289d274da7ec8910eb
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/SoftApModeConfiguration.java42
-rw-r--r--service/java/com/android/server/wifi/WifiController.java3
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java65
-rw-r--r--service/java/com/android/server/wifi/WifiStateMachine.java26
4 files changed, 94 insertions, 42 deletions
diff --git a/service/java/com/android/server/wifi/SoftApModeConfiguration.java b/service/java/com/android/server/wifi/SoftApModeConfiguration.java
new file mode 100644
index 000000000..e8805602e
--- /dev/null
+++ b/service/java/com/android/server/wifi/SoftApModeConfiguration.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 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 android.net.wifi.WifiConfiguration;
+
+/**
+ * Object holding the parameters needed to start SoftAp mode.
+ *
+ * Initially, this will hold the WifiConfiguration and mode.
+ */
+public class SoftApModeConfiguration {
+ final int mTargetMode;
+ final WifiConfiguration mConfig;
+
+ SoftApModeConfiguration(int targetMode, WifiConfiguration config) {
+ mTargetMode = targetMode;
+ mConfig = config;
+ }
+
+ public int getTargetMode() {
+ return mTargetMode;
+ }
+
+ public WifiConfiguration getWifiConfiguration() {
+ return mConfig;
+ }
+}
diff --git a/service/java/com/android/server/wifi/WifiController.java b/service/java/com/android/server/wifi/WifiController.java
index ed82b2b2d..c1b186142 100644
--- a/service/java/com/android/server/wifi/WifiController.java
+++ b/service/java/com/android/server/wifi/WifiController.java
@@ -30,7 +30,6 @@ import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
-import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
@@ -480,7 +479,7 @@ public class WifiController extends StateMachine {
if (msg.arg2 == 0) { // previous wifi state has not been saved yet
mSettingsStore.setWifiSavedState(WifiSettingsStore.WIFI_DISABLED);
}
- mWifiStateMachine.setHostApRunning((WifiConfiguration) msg.obj,
+ mWifiStateMachine.setHostApRunning((SoftApModeConfiguration) msg.obj,
true);
transitionTo(mApEnabledState);
}
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 1b3334d5f..d32a579ac 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -19,6 +19,7 @@ package com.android.server.wifi;
import static android.net.wifi.WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_FAILURE_REASON;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME;
+import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_MODE;
import static android.net.wifi.WifiManager.EXTRA_WIFI_AP_STATE;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
@@ -27,8 +28,6 @@ import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
-import static com.android.server.connectivity.tethering.IControlsTethering.STATE_LOCAL_ONLY;
-import static com.android.server.connectivity.tethering.IControlsTethering.STATE_TETHERED;
import static com.android.server.wifi.LocalOnlyHotspotRequestInfo.HOTSPOT_NO_ERROR;
import static com.android.server.wifi.WifiController.CMD_AIRPLANE_TOGGLED;
import static com.android.server.wifi.WifiController.CMD_BATTERY_CHANGED;
@@ -486,7 +485,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- final int currentState = intent.getIntExtra(EXTRA_WIFI_AP_STATE,
+ final int currState = intent.getIntExtra(EXTRA_WIFI_AP_STATE,
WIFI_AP_STATE_DISABLED);
final int prevState = intent.getIntExtra(EXTRA_PREVIOUS_WIFI_AP_STATE,
WIFI_AP_STATE_DISABLED);
@@ -494,7 +493,9 @@ public class WifiServiceImpl extends IWifiManager.Stub {
HOTSPOT_NO_ERROR);
final String ifaceName =
intent.getStringExtra(EXTRA_WIFI_AP_INTERFACE_NAME);
- handleWifiApStateChange(currentState, prevState, errorCode, ifaceName);
+ final int mode = intent.getIntExtra(EXTRA_WIFI_AP_MODE,
+ WifiManager.IFACE_IP_MODE_UNSPECIFIED);
+ handleWifiApStateChange(currState, prevState, errorCode, ifaceName, mode);
}
},
new IntentFilter(WifiManager.WIFI_AP_STATE_CHANGED_ACTION));
@@ -821,7 +822,9 @@ public class WifiServiceImpl extends IWifiManager.Stub {
}
// null wifiConfig is a meaningful input for CMD_SET_AP
if (wifiConfig == null || isValid(wifiConfig)) {
- mWifiController.sendMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig);
+ int mode = WifiManager.IFACE_IP_MODE_UNSPECIFIED;
+ SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(mode, wifiConfig);
+ mWifiController.sendMessage(CMD_SET_AP, enabled ? 1 : 0, 0, softApConfig);
} else {
Slog.e(TAG, "Invalid WifiConfiguration");
}
@@ -895,14 +898,12 @@ public class WifiServiceImpl extends IWifiManager.Stub {
// between a tether request and a hotspot request (tethering wins).
sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE);
- mLocalOnlyHotspotRequests.clear();
break;
case WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR:
// there was an error setting up the hotspot... trigger onFailed for the
// registered LOHS requestors
sendHotspotFailedMessageToAllLOHSRequestInfoEntriesLocked(
LocalOnlyHotspotCallback.ERROR_GENERIC);
- mLocalOnlyHotspotRequests.clear();
updateInterfaceIpStateInternal(null, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
break;
case WifiManager.IFACE_IP_MODE_UNSPECIFIED:
@@ -933,12 +934,15 @@ public class WifiServiceImpl extends IWifiManager.Stub {
mLog.trace("startSoftAp uid=%").c(Binder.getCallingUid()).flush();
- // TODO: determine if we need to stop softap and clean up state if a tethering request comes
- // from the user while we are just setting up. For now, the second CMD_START_AP will be
- // ignored in WifiStateMachine. This will still bring up tethering and the registered LOHS
- // requests will be cleared when we get the interface ip tethered status.
+ synchronized (mLocalOnlyHotspotRequests) {
+ // If a tethering request comes in while we have LOHS running (or requested), call stop
+ // for softap mode and restart softap with the tethering config.
+ if (!mLocalOnlyHotspotRequests.isEmpty()) {
+ stopSoftApInternal();
+ }
- return startSoftApInternal(wifiConfig, STATE_TETHERED);
+ return startSoftApInternal(wifiConfig, WifiManager.IFACE_IP_MODE_TETHERED);
+ }
}
/**
@@ -951,8 +955,8 @@ public class WifiServiceImpl extends IWifiManager.Stub {
// null wifiConfig is a meaningful input for CMD_SET_AP
if (wifiConfig == null || isValid(wifiConfig)) {
- // TODO: need a way to set the mode
- mWifiController.sendMessage(CMD_SET_AP, 1, 0, wifiConfig);
+ SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(mode, wifiConfig);
+ mWifiController.sendMessage(CMD_SET_AP, 1, 0, softApConfig);
return true;
}
Slog.e(TAG, "Invalid WifiConfiguration");
@@ -969,12 +973,21 @@ public class WifiServiceImpl extends IWifiManager.Stub {
// NETWORK_STACK is a signature only permission.
enforceNetworkStackPermission();
+ // only permitted callers are allowed to this point - they must have gone through
+ // connectivity service since this method is protected with the NETWORK_STACK PERMISSION
+
mLog.trace("stopSoftAp uid=%").c(Binder.getCallingUid()).flush();
- // add checks here to make sure this is the proper caller - apps can't disable tethering or
- // instances of local only hotspot that they didn't start. return false for those cases
+ synchronized (mLocalOnlyHotspotRequests) {
+ // If a tethering request comes in while we have LOHS running (or requested), call stop
+ // for softap mode and restart softap with the tethering config.
+ if (!mLocalOnlyHotspotRequests.isEmpty()) {
+ mLog.trace("Call to stop Tethering while LOHS is active,"
+ + " Registered LOHS callers will be updated when softap stopped.");
+ }
- return stopSoftApInternal();
+ return stopSoftApInternal();
+ }
}
/**
@@ -984,11 +997,6 @@ public class WifiServiceImpl extends IWifiManager.Stub {
private boolean stopSoftApInternal() {
mLog.trace("stopSoftApInternal uid=%").c(Binder.getCallingUid()).flush();
- // we have an allowed caller - clear local only hotspot if it was enabled
- synchronized (mLocalOnlyHotspotRequests) {
- mLocalOnlyHotspotRequests.clear();
- mLocalOnlyHotspotConfig = null;
- }
mWifiController.sendMessage(CMD_SET_AP, 0, 0);
return true;
}
@@ -997,11 +1005,11 @@ public class WifiServiceImpl extends IWifiManager.Stub {
* Private method to handle SoftAp state changes
*/
private void handleWifiApStateChange(
- int currentState, int previousState, int errorCode, String ifaceName) {
+ int currentState, int previousState, int errorCode, String ifaceName, int mode) {
// The AP state update from WifiStateMachine for softap
Slog.d(TAG, "handleWifiApStateChange: currentState=" + currentState
+ " previousState=" + previousState + " errorCode= " + errorCode
- + " ifaceName=" + ifaceName);
+ + " ifaceName=" + ifaceName + " mode=" + mode);
// check if we have a failure - since it is possible (worst case scenario where
// WifiController and WifiStateMachine are out of sync wrt modes) to get two FAILED
@@ -1055,6 +1063,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
try {
requestor.sendHotspotFailedMessage(arg1);
+ requestor.unlinkDeathRecipient();
} catch (RemoteException e) {
// This will be cleaned up by binder death handling
}
@@ -1074,6 +1083,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
for (LocalOnlyHotspotRequestInfo requestor : mLocalOnlyHotspotRequests.values()) {
try {
requestor.sendHotspotStoppedMessage();
+ requestor.unlinkDeathRecipient();
} catch (RemoteException e) {
// This will be cleaned up by binder death handling
}
@@ -1184,7 +1194,7 @@ public class WifiServiceImpl extends IWifiManager.Stub {
// this is the first request, then set up our config and start LOHS
mLocalOnlyHotspotConfig =
WifiApConfigStore.generateLocalOnlyHotspotConfig(mContext);
- startSoftApInternal(mLocalOnlyHotspotConfig, STATE_LOCAL_ONLY);
+ startSoftApInternal(mLocalOnlyHotspotConfig, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
}
mLocalOnlyHotspotRequests.put(pid, request);
@@ -2388,8 +2398,9 @@ public class WifiServiceImpl extends IWifiManager.Stub {
}
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING)) {
- // Turn mobile hotspot off
- setWifiApEnabled(null, false);
+ // Turn mobile hotspot off - will also clear any registered LOHS requests when it is
+ // shut down
+ stopSoftApInternal();
}
if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_WIFI)) {
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index 5ac8a3520..19c4812b0 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -1607,7 +1607,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
/**
* TODO: doc
*/
- public void setHostApRunning(WifiConfiguration wifiConfig, boolean enable) {
+ public void setHostApRunning(SoftApModeConfiguration wifiConfig, boolean enable) {
if (enable) {
sendMessage(CMD_START_AP, wifiConfig);
} else {
@@ -2806,11 +2806,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
- private void setWifiApState(int wifiApState, int reason) {
- setWifiApState(wifiApState, reason, null);
- }
-
- private void setWifiApState(int wifiApState, int reason, String ifaceName) {
+ private void setWifiApState(int wifiApState, int reason, String ifaceName, int mode) {
final int previousWifiApState = mWifiApState.get();
try {
@@ -2839,9 +2835,9 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
if (ifaceName == null) {
loge("Updating wifiApState with a null iface name");
- } else {
- intent.putExtra(WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME, ifaceName);
}
+ intent.putExtra(WifiManager.EXTRA_WIFI_AP_INTERFACE_NAME, ifaceName);
+ intent.putExtra(WifiManager.EXTRA_WIFI_AP_MODE, mode);
mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
}
@@ -4287,7 +4283,8 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
case CMD_START_AP:
/* Cannot start soft AP while in client mode */
loge("Failed to start soft AP with a running supplicant");
- setWifiApState(WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL);
+ setWifiApState(WIFI_AP_STATE_FAILED, WifiManager.SAP_START_FAILURE_GENERAL,
+ null, WifiManager.IFACE_IP_MODE_UNSPECIFIED);
break;
case CMD_SET_OPERATIONAL_MODE:
mOperationalMode = message.arg1;
@@ -6678,6 +6675,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
class SoftApState extends State {
private SoftApManager mSoftApManager;
private String mIfaceName;
+ private int mMode;
private class SoftApListener implements SoftApManager.Listener {
@Override
@@ -6688,7 +6686,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
sendMessage(CMD_START_AP_FAILURE);
}
- setWifiApState(state, reason, mIfaceName);
+ setWifiApState(state, reason, mIfaceName, mMode);
}
}
@@ -6698,11 +6696,13 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
if (message.what != CMD_START_AP) {
throw new RuntimeException("Illegal transition to SoftApState: " + message);
}
+ SoftApModeConfiguration config = (SoftApModeConfiguration) message.obj;
+ mMode = config.getTargetMode();
IApInterface apInterface = mWifiNative.setupForSoftApMode();
if (apInterface == null) {
setWifiApState(WIFI_AP_STATE_FAILED,
- WifiManager.SAP_START_FAILURE_GENERAL);
+ WifiManager.SAP_START_FAILURE_GENERAL, null, mMode);
/**
* Transition to InitialState to reset the
* driver/HAL back to the initial state.
@@ -6718,13 +6718,12 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
// the enabled broadcast, but since we had an error getting the name, we most likely
// won't be able to fully start softap mode.
}
- WifiConfiguration config = (WifiConfiguration) message.obj;
checkAndSetConnectivityInstance();
mSoftApManager = mWifiInjector.makeSoftApManager(mNwService,
new SoftApListener(),
apInterface,
- config);
+ config.getWifiConfiguration());
mSoftApManager.start();
mWifiStateTracker.updateState(WifiStateTracker.SOFT_AP);
}
@@ -6733,6 +6732,7 @@ public class WifiStateMachine extends StateMachine implements WifiNative.WifiRss
public void exit() {
mSoftApManager = null;
mIfaceName = null;
+ mMode = WifiManager.IFACE_IP_MODE_UNSPECIFIED;
}
@Override