diff options
Diffstat (limited to 'service/java/com/android/server/wifi/WifiShellCommand.java')
-rw-r--r-- | service/java/com/android/server/wifi/WifiShellCommand.java | 1185 |
1 files changed, 0 insertions, 1185 deletions
diff --git a/service/java/com/android/server/wifi/WifiShellCommand.java b/service/java/com/android/server/wifi/WifiShellCommand.java deleted file mode 100644 index b297604a8..000000000 --- a/service/java/com/android/server/wifi/WifiShellCommand.java +++ /dev/null @@ -1,1185 +0,0 @@ -/* - * 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 static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; -import static android.net.wifi.WifiConfiguration.METERED_OVERRIDE_METERED; -import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; - -import android.content.Context; -import android.content.pm.ParceledListSlice; -import android.net.ConnectivityManager; -import android.net.MacAddress; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkRequest; -import android.net.wifi.IActionListener; -import android.net.wifi.IScoreUpdateObserver; -import android.net.wifi.IWifiConnectedNetworkScorer; -import android.net.wifi.ScanResult; -import android.net.wifi.SoftApConfiguration; -import android.net.wifi.SupplicantState; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiNetworkSpecifier; -import android.net.wifi.WifiNetworkSuggestion; -import android.net.wifi.WifiScanner; -import android.net.wifi.nl80211.WifiNl80211Manager; -import android.os.BasicShellCommandHandler; -import android.os.Binder; -import android.os.Process; -import android.os.RemoteException; -import android.os.SystemClock; -import android.text.TextUtils; -import android.util.Pair; - -import com.android.server.wifi.util.ApConfigUtil; -import com.android.server.wifi.util.ArrayUtils; -import com.android.server.wifi.util.GeneralUtil; -import com.android.server.wifi.util.ScanResultUtil; - -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -/** - * Interprets and executes 'adb shell cmd wifi [args]'. - * - * To add new commands: - * - onCommand: Add a case "<command>" execute. Return a 0 - * if command executed successfully. - * - onHelp: add a description string. - * - * Permissions: currently root permission is required for some commands. Others will - * enforce the corresponding API permissions. - */ -public class WifiShellCommand extends BasicShellCommandHandler { - private static String SHELL_PACKAGE_NAME = "com.android.shell"; - // These don't require root access. - // However, these do perform permission checks in the corresponding WifiService methods. - private static final String[] NON_PRIVILEGED_COMMANDS = { - "add-suggestion", - "add-network", - "connect-network", - "forget-network", - "get-country-code", - "help", - "-h", - "list-scan-results", - "list-networks", - "list-suggestions", - "remove-suggestion", - "remove-all-suggestions", - "reset-connected-score", - "set-connected-score", - "set-scan-always-available", - "set-verbose-logging", - "set-wifi-enabled", - "start-scan", - "start-softap", - "status", - "stop-softap", - }; - - private static final Map<String, Pair<NetworkRequest, ConnectivityManager.NetworkCallback>> - sActiveRequests = new ConcurrentHashMap<>(); - - private final ClientModeImpl mClientModeImpl; - private final WifiLockManager mWifiLockManager; - private final WifiNetworkSuggestionsManager mWifiNetworkSuggestionsManager; - private final WifiConfigManager mWifiConfigManager; - private final WifiNative mWifiNative; - private final HostapdHal mHostapdHal; - private final WifiCountryCode mWifiCountryCode; - private final WifiLastResortWatchdog mWifiLastResortWatchdog; - private final WifiServiceImpl mWifiService; - private final Context mContext; - private final ConnectivityManager mConnectivityManager; - private final WifiCarrierInfoManager mWifiCarrierInfoManager; - private final ActiveModeWarden mActiveModeWarden; - - WifiShellCommand(WifiInjector wifiInjector, WifiServiceImpl wifiService, Context context) { - mClientModeImpl = wifiInjector.getClientModeImpl(); - mWifiLockManager = wifiInjector.getWifiLockManager(); - mWifiNetworkSuggestionsManager = wifiInjector.getWifiNetworkSuggestionsManager(); - mWifiConfigManager = wifiInjector.getWifiConfigManager(); - mHostapdHal = wifiInjector.getHostapdHal(); - mWifiNative = wifiInjector.getWifiNative(); - mWifiCountryCode = wifiInjector.getWifiCountryCode(); - mWifiLastResortWatchdog = wifiInjector.getWifiLastResortWatchdog(); - mWifiService = wifiService; - mContext = context; - mConnectivityManager = context.getSystemService(ConnectivityManager.class); - mWifiCarrierInfoManager = wifiInjector.getWifiCarrierInfoManager(); - mActiveModeWarden = wifiInjector.getActiveModeWarden(); - } - - @Override - public int onCommand(String cmd) { - // Treat no command as help command. - if (cmd == null || cmd.equals("")) { - cmd = "help"; - } - // Explicit exclusion from root permission - if (ArrayUtils.indexOf(NON_PRIVILEGED_COMMANDS, cmd) == -1) { - final int uid = Binder.getCallingUid(); - if (uid != Process.ROOT_UID) { - throw new SecurityException( - "Uid " + uid + " does not have access to " + cmd + " wifi command"); - } - } - - final PrintWriter pw = getOutPrintWriter(); - try { - switch (cmd) { - case "set-ipreach-disconnect": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - mClientModeImpl.setIpReachabilityDisconnectEnabled(enabled); - return 0; - } - case "get-ipreach-disconnect": - pw.println("IPREACH_DISCONNECT state is " - + mClientModeImpl.getIpReachabilityDisconnectEnabled()); - return 0; - case "set-poll-rssi-interval-msecs": - int newPollIntervalMsecs; - try { - newPollIntervalMsecs = Integer.parseInt(getNextArgRequired()); - } catch (NumberFormatException e) { - pw.println( - "Invalid argument to 'set-poll-rssi-interval-msecs' " - + "- must be a positive integer"); - return -1; - } - - if (newPollIntervalMsecs < 1) { - pw.println( - "Invalid argument to 'set-poll-rssi-interval-msecs' " - + "- must be a positive integer"); - return -1; - } - - mClientModeImpl.setPollRssiIntervalMsecs(newPollIntervalMsecs); - return 0; - case "get-poll-rssi-interval-msecs": - pw.println("ClientModeImpl.mPollRssiIntervalMsecs = " - + mClientModeImpl.getPollRssiIntervalMsecs()); - return 0; - case "force-hi-perf-mode": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - if (!mWifiLockManager.forceHiPerfMode(enabled)) { - pw.println("Command execution failed"); - } - return 0; - } - case "force-low-latency-mode": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - if (!mWifiLockManager.forceLowLatencyMode(enabled)) { - pw.println("Command execution failed"); - } - return 0; - } - case "network-suggestions-set-user-approved": { - String packageName = getNextArgRequired(); - boolean approved = getNextArgRequiredTrueOrFalse("yes", "no"); - mWifiNetworkSuggestionsManager.setHasUserApprovedForApp(approved, packageName); - return 0; - } - case "network-suggestions-has-user-approved": { - String packageName = getNextArgRequired(); - boolean hasUserApproved = - mWifiNetworkSuggestionsManager.hasUserApprovedForApp(packageName); - pw.println(hasUserApproved ? "yes" : "no"); - return 0; - } - case "imsi-protection-exemption-set-user-approved-for-carrier": { - String arg1 = getNextArgRequired(); - int carrierId = -1; - try { - carrierId = Integer.parseInt(arg1); - } catch (NumberFormatException e) { - pw.println("Invalid argument to " - + "'imsi-protection-exemption-set-user-approved-for-carrier' " - + "- carrierId must be an Integer"); - return -1; - } - boolean approved = getNextArgRequiredTrueOrFalse("yes", "no"); - mWifiCarrierInfoManager - .setHasUserApprovedImsiPrivacyExemptionForCarrier(approved, carrierId); - return 0; - } - case "imsi-protection-exemption-has-user-approved-for-carrier": { - String arg1 = getNextArgRequired(); - int carrierId = -1; - try { - carrierId = Integer.parseInt(arg1); - } catch (NumberFormatException e) { - pw.println("Invalid argument to " - + "'imsi-protection-exemption-has-user-approved-for-carrier' " - + "- 'carrierId' must be an Integer"); - return -1; - } - boolean hasUserApproved = mWifiCarrierInfoManager - .hasUserApprovedImsiPrivacyExemptionForCarrier(carrierId); - pw.println(hasUserApproved ? "yes" : "no"); - return 0; - } - case "imsi-protection-exemption-clear-user-approved-for-carrier": { - String arg1 = getNextArgRequired(); - int carrierId = -1; - try { - carrierId = Integer.parseInt(arg1); - } catch (NumberFormatException e) { - pw.println("Invalid argument to " - + "'imsi-protection-exemption-clear-user-approved-for-carrier' " - + "- 'carrierId' must be an Integer"); - return -1; - } - mWifiCarrierInfoManager.clearImsiPrivacyExemptionForCarrier(carrierId); - return 0; - } - case "network-requests-remove-user-approved-access-points": { - String packageName = getNextArgRequired(); - mClientModeImpl.removeNetworkRequestUserApprovedAccessPointsForApp(packageName); - return 0; - } - case "clear-user-disabled-networks": { - mWifiConfigManager.clearUserTemporarilyDisabledList(); - return 0; - } - case "send-link-probe": { - return sendLinkProbe(pw); - } - case "force-softap-channel": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - if (enabled) { - int apChannelMHz; - try { - apChannelMHz = Integer.parseInt(getNextArgRequired()); - } catch (NumberFormatException e) { - pw.println("Invalid argument to 'force-softap-channel enabled' " - + "- must be a positive integer"); - return -1; - } - int apChannel = ScanResult.convertFrequencyMhzToChannel(apChannelMHz); - int band = ApConfigUtil.convertFrequencyToBand(apChannelMHz); - if (apChannel == -1 || band == -1 || !isApChannelMHzValid(apChannelMHz)) { - pw.println("Invalid argument to 'force-softap-channel enabled' " - + "- must be a valid WLAN channel"); - return -1; - } - - if ((band == SoftApConfiguration.BAND_5GHZ - && !mWifiService.is5GHzBandSupported()) - || (band == SoftApConfiguration.BAND_6GHZ - && !mWifiService.is6GHzBandSupported())) { - pw.println("Invalid argument to 'force-softap-channel enabled' " - + "- channel band is not supported by the device"); - return -1; - } - - mHostapdHal.enableForceSoftApChannel(apChannel, band); - return 0; - } else { - mHostapdHal.disableForceSoftApChannel(); - return 0; - } - } - case "start-softap": { - SoftApConfiguration config = buildSoftApConfiguration(pw); - if (mWifiService.startTetheredHotspot(config)) { - pw.println("Soft AP started successfully"); - } else { - pw.println("Soft AP failed to start. Please check config parameters"); - } - return 0; - } - case "stop-softap": { - if (mWifiService.stopSoftAp()) { - pw.println("Soft AP stopped successfully"); - } else { - pw.println("Soft AP failed to stop"); - } - return 0; - } - case "force-country-code": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - if (enabled) { - String countryCode = getNextArgRequired(); - if (!(countryCode.length() == 2 - && countryCode.chars().allMatch(Character::isLetter))) { - pw.println("Invalid argument to 'force-country-code enabled' " - + "- must be a two-letter string"); - return -1; - } - mWifiCountryCode.enableForceCountryCode(countryCode); - return 0; - } else { - mWifiCountryCode.disableForceCountryCode(); - return 0; - } - } - case "get-country-code": { - pw.println("Wifi Country Code = " - + mWifiCountryCode.getCountryCode()); - return 0; - } - case "set-wifi-watchdog": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - mWifiLastResortWatchdog.setWifiWatchdogFeature(enabled); - return 0; - } - case "get-wifi-watchdog": { - pw.println("wifi watchdog state is " - + mWifiLastResortWatchdog.getWifiWatchdogFeature()); - return 0; - } - case "set-wifi-enabled": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - mWifiService.setWifiEnabled(SHELL_PACKAGE_NAME, enabled); - return 0; - } - case "set-scan-always-available": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - mWifiService.setScanAlwaysAvailable(enabled); - return 0; - } - case "get-softap-supported-features": - // This command is used for vts to check softap supported features. - if (ApConfigUtil.isAcsSupported(mContext)) { - pw.println("wifi_softap_acs_supported"); - } - if (ApConfigUtil.isWpa3SaeSupported(mContext)) { - pw.println("wifi_softap_wpa3_sae_supported"); - } - return 0; - case "settings-reset": - mWifiService.factoryReset(SHELL_PACKAGE_NAME); - return 0; - case "list-scan-results": - List<ScanResult> scanResults = - mWifiService.getScanResults(SHELL_PACKAGE_NAME, null); - if (scanResults.isEmpty()) { - pw.println("No scan results"); - } else { - ScanResultUtil.dumpScanResults(pw, scanResults, - SystemClock.elapsedRealtime()); - } - return 0; - case "start-scan": - mWifiService.startScan(SHELL_PACKAGE_NAME, null); - return 0; - case "list-networks": - ParceledListSlice<WifiConfiguration> networks = - mWifiService.getConfiguredNetworks(SHELL_PACKAGE_NAME, null); - if (networks == null || networks.getList().isEmpty()) { - pw.println("No networks"); - } else { - pw.println("Network Id SSID Security type"); - for (WifiConfiguration network : networks.getList()) { - String securityType = null; - if (WifiConfigurationUtil.isConfigForSaeNetwork(network)) { - securityType = "wpa3"; - } else if (WifiConfigurationUtil.isConfigForPskNetwork(network)) { - securityType = "wpa2"; - } else if (WifiConfigurationUtil.isConfigForEapNetwork(network)) { - securityType = "eap"; - } else if (WifiConfigurationUtil.isConfigForOweNetwork(network)) { - securityType = "owe"; - } else if (WifiConfigurationUtil.isConfigForOpenNetwork(network)) { - securityType = "open"; - } - pw.println(String.format("%-12d %-32s %-4s", - network.networkId, WifiInfo.sanitizeSsid(network.SSID), - securityType)); - } - } - return 0; - case "connect-network": { - CountDownLatch countDownLatch = new CountDownLatch(1); - IActionListener.Stub actionListener = new IActionListener.Stub() { - @Override - public void onSuccess() throws RemoteException { - pw.println("Connection initiated "); - countDownLatch.countDown(); - } - - @Override - public void onFailure(int i) throws RemoteException { - pw.println("Connection failed"); - countDownLatch.countDown(); - } - }; - WifiConfiguration config = buildWifiConfiguration(pw); - mWifiService.connect( - config, -1, new Binder(), actionListener, actionListener.hashCode()); - // wait for status. - countDownLatch.await(500, TimeUnit.MILLISECONDS); - setAutoJoin(pw, config.SSID, config.allowAutojoin); - return 0; - } - case "add-network": { - CountDownLatch countDownLatch = new CountDownLatch(1); - IActionListener.Stub actionListener = new IActionListener.Stub() { - @Override - public void onSuccess() throws RemoteException { - pw.println("Save successful"); - countDownLatch.countDown(); - } - - @Override - public void onFailure(int i) throws RemoteException { - pw.println("Save failed"); - countDownLatch.countDown(); - } - }; - WifiConfiguration config = buildWifiConfiguration(pw); - mWifiService.save( - config, new Binder(), actionListener, actionListener.hashCode()); - // wait for status. - countDownLatch.await(500, TimeUnit.MILLISECONDS); - setAutoJoin(pw, config.SSID, config.allowAutojoin); - return 0; - } - case "forget-network": { - String networkId = getNextArgRequired(); - CountDownLatch countDownLatch = new CountDownLatch(1); - IActionListener.Stub actionListener = new IActionListener.Stub() { - @Override - public void onSuccess() throws RemoteException { - pw.println("Forget successful"); - countDownLatch.countDown(); - } - - @Override - public void onFailure(int i) throws RemoteException { - pw.println("Forget failed"); - countDownLatch.countDown(); - } - }; - mWifiService.forget( - Integer.parseInt(networkId), new Binder(), actionListener, - actionListener.hashCode()); - // wait for status. - countDownLatch.await(500, TimeUnit.MILLISECONDS); - return 0; - } - case "status": - printStatus(pw); - return 0; - case "set-verbose-logging": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - mWifiService.enableVerboseLogging(enabled ? 1 : 0); - return 0; - } - case "add-suggestion": { - WifiNetworkSuggestion suggestion = buildSuggestion(pw); - mWifiService.addNetworkSuggestions( - Arrays.asList(suggestion), SHELL_PACKAGE_NAME, null); - return 0; - } - case "remove-suggestion": { - String ssid = getNextArgRequired(); - List<WifiNetworkSuggestion> suggestions = - mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME); - WifiNetworkSuggestion suggestion = suggestions.stream() - .filter(s -> s.getSsid().equals(ssid)) - .findAny() - .orElse(null); - if (suggestion == null) { - pw.println("No matching suggestion to remove"); - return -1; - } - mWifiService.removeNetworkSuggestions( - Arrays.asList(suggestion), SHELL_PACKAGE_NAME); - return 0; - } - case "remove-all-suggestions": - mWifiService.removeNetworkSuggestions( - Collections.emptyList(), SHELL_PACKAGE_NAME); - return 0; - case "list-suggestions": { - List<WifiNetworkSuggestion> suggestions = - mWifiService.getNetworkSuggestions(SHELL_PACKAGE_NAME); - printWifiNetworkSuggestions(pw, suggestions); - return 0; - } - case "list-all-suggestions": { - Set<WifiNetworkSuggestion> suggestions = - mWifiNetworkSuggestionsManager.getAllNetworkSuggestions(); - printWifiNetworkSuggestions(pw, suggestions); - return 0; - } - case "list-suggestions-from-app": { - String packageName = getNextArgRequired(); - List<WifiNetworkSuggestion> suggestions = - mWifiService.getNetworkSuggestions(packageName); - printWifiNetworkSuggestions(pw, suggestions); - return 0; - } - case "add-request": { - NetworkRequest networkRequest = buildNetworkRequest(pw); - ConnectivityManager.NetworkCallback networkCallback = - new ConnectivityManager.NetworkCallback(); - pw.println("Adding request: " + networkRequest); - mConnectivityManager.requestNetwork(networkRequest, networkCallback); - String ssid = getAllArgs()[1]; - sActiveRequests.put(ssid, Pair.create(networkRequest, networkCallback)); - return 0; - } - case "remove-request": { - String ssid = getNextArgRequired(); - Pair<NetworkRequest, ConnectivityManager.NetworkCallback> nrAndNc = - sActiveRequests.remove(ssid); - if (nrAndNc == null) { - pw.println("No matching request to remove"); - return -1; - } - pw.println("Removing request: " + nrAndNc.first); - mConnectivityManager.unregisterNetworkCallback(nrAndNc.second); - return 0; - } - case "remove-all-requests": - if (sActiveRequests.isEmpty()) { - pw.println("No active requests"); - return -1; - } - for (Pair<NetworkRequest, ConnectivityManager.NetworkCallback> nrAndNc - : sActiveRequests.values()) { - pw.println("Removing request: " + nrAndNc.first); - mConnectivityManager.unregisterNetworkCallback(nrAndNc.second); - } - sActiveRequests.clear(); - return 0; - case "list-requests": - if (sActiveRequests.isEmpty()) { - pw.println("No active requests"); - } else { - pw.println("SSID NetworkRequest"); - for (Map.Entry<String, - Pair<NetworkRequest, ConnectivityManager.NetworkCallback>> entry : - sActiveRequests.entrySet()) { - pw.println(String.format("%-32s %-4s", - entry.getKey(), entry.getValue().first)); - } - } - return 0; - case "network-requests-set-user-approved": { - String packageName = getNextArgRequired(); - boolean approved = getNextArgRequiredTrueOrFalse("yes", "no"); - mClientModeImpl.setNetworkRequestUserApprovedApp(packageName, approved); - return 0; - } - case "network-requests-has-user-approved": { - String packageName = getNextArgRequired(); - boolean hasUserApproved = - mClientModeImpl.hasNetworkRequestUserApprovedApp(packageName); - pw.println(hasUserApproved ? "yes" : "no"); - return 0; - } - case "set-connected-score": { - int score = Integer.parseInt(getNextArgRequired()); - CountDownLatch countDownLatch = new CountDownLatch(2); - GeneralUtil.Mutable<IScoreUpdateObserver> scoreUpdateObserverMutable = - new GeneralUtil.Mutable<>(); - GeneralUtil.Mutable<Integer> sessionIdMutable = new GeneralUtil.Mutable<>(); - IWifiConnectedNetworkScorer.Stub connectedScorer = - new IWifiConnectedNetworkScorer.Stub() { - @Override - public void onStart(int sessionId) { - sessionIdMutable.value = sessionId; - countDownLatch.countDown(); - } - @Override - public void onStop(int sessionId) { - // clear the external scorer on disconnect. - mWifiService.clearWifiConnectedNetworkScorer(); - } - @Override - public void onSetScoreUpdateObserver(IScoreUpdateObserver observerImpl) { - scoreUpdateObserverMutable.value = observerImpl; - countDownLatch.countDown(); - } - }; - mWifiService.clearWifiConnectedNetworkScorer(); // clear any previous scorer - if (mWifiService.setWifiConnectedNetworkScorer(new Binder(), connectedScorer)) { - // wait for retrieving the session id & score observer. - countDownLatch.await(1000, TimeUnit.MILLISECONDS); - } - if (scoreUpdateObserverMutable.value == null - || sessionIdMutable.value == null) { - pw.println("Did not receive session id and/or the score update observer. " - + "Is the device connected to a wifi network?"); - mWifiService.clearWifiConnectedNetworkScorer(); - return -1; - } - pw.println("Updating score: " + score + " for session id: " - + sessionIdMutable.value); - try { - scoreUpdateObserverMutable.value.notifyScoreUpdate( - sessionIdMutable.value, score); - } catch (RemoteException e) { - pw.println("Failed to send the score update"); - mWifiService.clearWifiConnectedNetworkScorer(); - return -1; - } - return 0; - } - case "reset-connected-score": { - mWifiService.clearWifiConnectedNetworkScorer(); // clear any previous scorer - return 0; - } - case "set-emergency-callback-mode": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - mActiveModeWarden.emergencyCallbackModeChanged(enabled); - return 0; - } - case "set-emergency-call-state": { - boolean enabled = getNextArgRequiredTrueOrFalse("enabled", "disabled"); - mActiveModeWarden.emergencyCallStateChanged(enabled); - return 0; - } - default: - return handleDefaultCommands(cmd); - } - } catch (IllegalArgumentException e) { - pw.println("Invalid args for " + cmd + ": " + e); - return -1; - } catch (Exception e) { - pw.println("Exception while executing WifiShellCommand: "); - e.printStackTrace(pw); - return -1; - } - } - - private boolean getNextArgRequiredTrueOrFalse(String trueString, String falseString) - throws IllegalArgumentException { - String nextArg = getNextArgRequired(); - if (trueString.equals(nextArg)) { - return true; - } else if (falseString.equals(nextArg)) { - return false; - } else { - throw new IllegalArgumentException("Expected '" + trueString + "' or '" + falseString - + "' as next arg but got '" + nextArg + "'"); - } - } - - private WifiConfiguration buildWifiConfiguration(PrintWriter pw) { - String ssid = getNextArgRequired(); - String type = getNextArgRequired(); - WifiConfiguration configuration = new WifiConfiguration(); - configuration.SSID = "\"" + ssid + "\""; - if (TextUtils.equals(type, "wpa3")) { - configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE); - configuration.preSharedKey = "\"" + getNextArgRequired() + "\""; - } else if (TextUtils.equals(type, "wpa2")) { - configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK); - configuration.preSharedKey = "\"" + getNextArgRequired() + "\""; - } else if (TextUtils.equals(type, "owe")) { - configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OWE); - } else if (TextUtils.equals(type, "open")) { - configuration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_OPEN); - } else { - throw new IllegalArgumentException("Unknown network type " + type); - } - String option = getNextOption(); - while (option != null) { - if (option.equals("-m")) { - configuration.meteredOverride = METERED_OVERRIDE_METERED; - } else if (option.equals("-d")) { - configuration.allowAutojoin = false; - } else if (option.equals("-b")) { - configuration.BSSID = getNextArgRequired(); - } else { - pw.println("Ignoring unknown option " + option); - } - option = getNextOption(); - } - return configuration; - } - - private SoftApConfiguration buildSoftApConfiguration(PrintWriter pw) { - String ssid = getNextArgRequired(); - String type = getNextArgRequired(); - SoftApConfiguration.Builder configBuilder = new SoftApConfiguration.Builder(); - configBuilder.setSsid("\"" + ssid + "\""); - if (TextUtils.equals(type, "wpa2")) { - configBuilder.setPassphrase(getNextArgRequired(), - SoftApConfiguration.SECURITY_TYPE_WPA2_PSK); - } else if (TextUtils.equals(type, "open")) { - configBuilder.setPassphrase(null, SoftApConfiguration.SECURITY_TYPE_OPEN); - } else { - throw new IllegalArgumentException("Unknown network type " + type); - } - String option = getNextOption(); - while (option != null) { - if (option.equals("-b")) { - String preferredBand = getNextArgRequired(); - if (preferredBand.equals("2")) { - configBuilder.setBand(SoftApConfiguration.BAND_2GHZ); - } else if (preferredBand.equals("5")) { - configBuilder.setBand(SoftApConfiguration.BAND_5GHZ); - } else if (preferredBand.equals("6")) { - configBuilder.setBand(SoftApConfiguration.BAND_6GHZ); - } else if (preferredBand.equals("any")) { - configBuilder.setBand(SoftApConfiguration.BAND_ANY); - } else { - throw new IllegalArgumentException("Invalid band option " + preferredBand); - } - } else { - pw.println("Ignoring unknown option " + option); - } - option = getNextOption(); - } - return configBuilder.build(); - } - - private WifiNetworkSuggestion buildSuggestion(PrintWriter pw) { - String ssid = getNextArgRequired(); - String type = getNextArgRequired(); - WifiNetworkSuggestion.Builder suggestionBuilder = - new WifiNetworkSuggestion.Builder(); - suggestionBuilder.setSsid(ssid); - if (TextUtils.equals(type, "wpa3")) { - suggestionBuilder.setWpa3Passphrase(getNextArgRequired()); - } else if (TextUtils.equals(type, "wpa2")) { - suggestionBuilder.setWpa2Passphrase(getNextArgRequired()); - } else if (TextUtils.equals(type, "owe")) { - suggestionBuilder.setIsEnhancedOpen(true); - } else if (TextUtils.equals(type, "open")) { - // nothing to do. - } else { - throw new IllegalArgumentException("Unknown network type " + type); - } - String option = getNextOption(); - while (option != null) { - if (option.equals("-u")) { - suggestionBuilder.setUntrusted(true); - } else if (option.equals("-m")) { - suggestionBuilder.setIsMetered(true); - } else if (option.equals("-s")) { - suggestionBuilder.setCredentialSharedWithUser(true); - } else if (option.equals("-d")) { - suggestionBuilder.setIsInitialAutojoinEnabled(false); - } else if (option.equals("-b")) { - suggestionBuilder.setBssid(MacAddress.fromString(getNextArgRequired())); - } else { - pw.println("Ignoring unknown option " + option); - } - option = getNextOption(); - } - return suggestionBuilder.build(); - } - - private NetworkRequest buildNetworkRequest(PrintWriter pw) { - String ssid = getNextArgRequired(); - String type = getNextArgRequired(); - WifiNetworkSpecifier.Builder specifierBuilder = - new WifiNetworkSpecifier.Builder(); - specifierBuilder.setSsid(ssid); - if (TextUtils.equals(type, "wpa3")) { - specifierBuilder.setWpa3Passphrase(getNextArgRequired()); - } else if (TextUtils.equals(type, "wpa2")) { - specifierBuilder.setWpa2Passphrase(getNextArgRequired()); - } else if (TextUtils.equals(type, "owe")) { - specifierBuilder.setIsEnhancedOpen(true); - } else if (TextUtils.equals(type, "open")) { - // nothing to do. - } else { - throw new IllegalArgumentException("Unknown network type " + type); - } - String bssid = null; - String option = getNextOption(); - while (option != null) { - if (option.equals("-b")) { - bssid = getNextArgRequired(); - } else { - pw.println("Ignoring unknown option " + option); - } - option = getNextOption(); - } - - // Permission approval bypass is only available to requests with both ssid & bssid set. - // So, find scan result with the best rssi level to set in the request. - if (bssid == null) { - ScanResult matchingScanResult = - mWifiService.getScanResults(SHELL_PACKAGE_NAME, null) - .stream() - .filter(s -> s.SSID.equals(ssid)) - .max(Comparator.comparingInt(s -> s.level)) - .orElse(null); - if (matchingScanResult != null) { - bssid = matchingScanResult.BSSID; - } else { - pw.println("No matching bssid found, request will need UI approval"); - } - } - if (bssid != null) specifierBuilder.setBssid(MacAddress.fromString(bssid)); - return new NetworkRequest.Builder() - .addTransportType(TRANSPORT_WIFI) - .removeCapability(NET_CAPABILITY_INTERNET) - .setNetworkSpecifier(specifierBuilder.build()) - .build(); - } - - private void setAutoJoin(PrintWriter pw, String ssid, boolean allowAutojoin) { - // For suggestions, this will work only if the config has already been added - // to WifiConfigManager. - WifiConfiguration retrievedConfig = - mWifiService.getPrivilegedConfiguredNetworks(SHELL_PACKAGE_NAME, null) - .getList() - .stream() - .filter(n -> n.SSID.equals(ssid)) - .findAny() - .orElse(null); - if (retrievedConfig == null) { - pw.println("Cannot retrieve config, autojoin setting skipped."); - return; - } - mWifiService.allowAutojoin(retrievedConfig.networkId, allowAutojoin); - } - - private int sendLinkProbe(PrintWriter pw) throws InterruptedException { - // Note: should match WifiNl80211Manager#SEND_MGMT_FRAME_TIMEOUT_MS - final int sendMgmtFrameTimeoutMs = 1000; - - ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(1); - mClientModeImpl.probeLink(new WifiNl80211Manager.SendMgmtFrameCallback() { - @Override - public void onAck(int elapsedTimeMs) { - queue.offer("Link probe succeeded after " + elapsedTimeMs + " ms"); - } - - @Override - public void onFailure(int reason) { - queue.offer("Link probe failed with reason " + reason); - } - }, -1); - - // block until msg is received, or timed out - String msg = queue.poll(sendMgmtFrameTimeoutMs + 1000, TimeUnit.MILLISECONDS); - if (msg == null) { - pw.println("Link probe timed out"); - } else { - pw.println(msg); - } - return 0; - } - - private boolean isApChannelMHzValid(int apChannelMHz) { - int[] allowed2gFreq = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ); - int[] allowed5gFreq = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ); - int[] allowed5gDfsFreq = - mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY); - int[] allowed6gFreq = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ); - if (allowed2gFreq == null) { - allowed2gFreq = new int[0]; - } - if (allowed5gFreq == null) { - allowed5gFreq = new int[0]; - } - if (allowed5gDfsFreq == null) { - allowed5gDfsFreq = new int[0]; - } - if (allowed6gFreq == null) { - allowed6gFreq = new int[0]; - } - - return (Arrays.binarySearch(allowed2gFreq, apChannelMHz) >= 0 - || Arrays.binarySearch(allowed5gFreq, apChannelMHz) >= 0 - || Arrays.binarySearch(allowed5gDfsFreq, apChannelMHz) >= 0) - || Arrays.binarySearch(allowed6gFreq, apChannelMHz) >= 0; - } - - private void printStatus(PrintWriter pw) { - boolean wifiEnabled = mWifiService.getWifiEnabledState() == WIFI_STATE_ENABLED; - pw.println("Wifi is " + (wifiEnabled ? "enabled" : "disabled")); - pw.println("Wifi scanning is " - + (mWifiService.isScanAlwaysAvailable() - ? "always available" : "only available when wifi is enabled")); - if (!wifiEnabled) { - return; - } - WifiInfo info = mWifiService.getConnectionInfo(SHELL_PACKAGE_NAME, null); - if (info.getSupplicantState() != SupplicantState.COMPLETED) { - pw.println("Wifi is not connected"); - return; - } - pw.println("Wifi is connected to " + info.getSSID()); - pw.println("WifiInfo: " + info); - // additional diagnostics not printed by WifiInfo.toString() - pw.println("successfulTxPackets: " + info.txSuccess); - pw.println("successfulTxPacketsPerSecond: " + info.getSuccessfulTxPacketsPerSecond()); - pw.println("retriedTxPackets: " + info.txRetries); - pw.println("retriedTxPacketsPerSecond: " + info.getRetriedTxPacketsPerSecond()); - pw.println("lostTxPackets: " + info.txBad); - pw.println("lostTxPacketsPerSecond: " + info.getLostTxPacketsPerSecond()); - pw.println("successfulRxPackets: " + info.rxSuccess); - pw.println("successfulRxPacketsPerSecond: " + info.getSuccessfulRxPacketsPerSecond()); - - Network network = mWifiService.getCurrentNetwork(); - try { - NetworkCapabilities capabilities = mConnectivityManager.getNetworkCapabilities(network); - pw.println("NetworkCapabilities: " + capabilities); - } catch (SecurityException e) { - // ignore on unrooted shell. - } - } - - private void onHelpNonPrivileged(PrintWriter pw) { - pw.println(" get-country-code"); - pw.println(" Gets country code as a two-letter string"); - pw.println(" set-wifi-enabled enabled|disabled"); - pw.println(" Enables/disables Wifi on this device."); - pw.println(" set-scan-always-available enabled|disabled"); - pw.println(" Sets whether scanning should be available even when wifi is off."); - pw.println(" list-scan-results"); - pw.println(" Lists the latest scan results"); - pw.println(" start-scan"); - pw.println(" Start a new scan"); - pw.println(" list-networks"); - pw.println(" Lists the saved networks"); - pw.println(" connect-network <ssid> open|owe|wpa2|wpa3 [<passphrase>] [-m] [-d] " - + "[-b <bssid>]"); - pw.println(" Connect to a network with provided params and add to saved networks list"); - pw.println(" <ssid> - SSID of the network"); - pw.println(" open|owe|wpa2|wpa3 - Security type of the network."); - pw.println(" - Use 'open' or 'owe' for networks with no passphrase"); - pw.println(" - 'open' - Open networks (Most prevalent)"); - pw.println(" - 'owe' - Enhanced open networks"); - pw.println(" - Use 'wpa2' or 'wpa3' for networks with passphrase"); - pw.println(" - 'wpa2' - WPA-2 PSK networks (Most prevalent)"); - pw.println(" - 'wpa3' - WPA-3 PSK networks"); - pw.println(" -m - Mark the network metered."); - pw.println(" -d - Mark the network autojoin disabled."); - pw.println(" -b <bssid> - Set specific BSSID."); - pw.println(" add-network <ssid> open|owe|wpa2|wpa3 [<passphrase>] [-m] [-d] " - + "[-b <bssid>]"); - pw.println(" Add/update saved network with provided params"); - pw.println(" <ssid> - SSID of the network"); - pw.println(" open|owe|wpa2|wpa3 - Security type of the network."); - pw.println(" - Use 'open' or 'owe' for networks with no passphrase"); - pw.println(" - 'open' - Open networks (Most prevalent)"); - pw.println(" - 'owe' - Enhanced open networks"); - pw.println(" - Use 'wpa2' or 'wpa3' for networks with passphrase"); - pw.println(" - 'wpa2' - WPA-2 PSK networks (Most prevalent)"); - pw.println(" - 'wpa3' - WPA-3 PSK networks"); - pw.println(" -m - Mark the network metered."); - pw.println(" -d - Mark the network autojoin disabled."); - pw.println(" -b <bssid> - Set specific BSSID."); - pw.println(" forget-network <networkId>"); - pw.println(" Remove the network mentioned by <networkId>"); - pw.println(" - Use list-networks to retrieve <networkId> for the network"); - pw.println(" status"); - pw.println(" Current wifi status"); - pw.println(" set-verbose-logging enabled|disabled "); - pw.println(" Set the verbose logging enabled or disabled"); - pw.println(" add-suggestion <ssid> open|owe|wpa2|wpa3 [<passphrase>] [-u] [-m] [-s] [-d]" - + "[-b <bssid>]"); - pw.println(" Add a network suggestion with provided params"); - pw.println(" Use 'network-suggestions-set-user-approved " + SHELL_PACKAGE_NAME + " yes'" - + " to approve suggestions added via shell (Needs root access)"); - pw.println(" <ssid> - SSID of the network"); - pw.println(" open|owe|wpa2|wpa3 - Security type of the network."); - pw.println(" - Use 'open' or 'owe' for networks with no passphrase"); - pw.println(" - 'open' - Open networks (Most prevalent)"); - pw.println(" - 'owe' - Enhanced open networks"); - pw.println(" - Use 'wpa2' or 'wpa3' for networks with passphrase"); - pw.println(" - 'wpa2' - WPA-2 PSK networks (Most prevalent)"); - pw.println(" - 'wpa3' - WPA-3 PSK networks"); - pw.println(" -u - Mark the suggestion untrusted."); - pw.println(" -m - Mark the suggestion metered."); - pw.println(" -s - Share the suggestion with user."); - pw.println(" -d - Mark the suggestion autojoin disabled."); - pw.println(" -b <bssid> - Set specific BSSID."); - pw.println(" remove-suggestion <ssid>"); - pw.println(" Remove a network suggestion with provided SSID of the network"); - pw.println(" remove-all-suggestions"); - pw.println(" Removes all suggestions added via shell"); - pw.println(" list-suggestions"); - pw.println(" Lists the suggested networks added via shell"); - pw.println(" set-connected-score <score>"); - pw.println(" Set connected wifi network score (to choose between LTE & Wifi for " - + "default route)."); - pw.println(" This turns off the active connected scorer (default or external)."); - pw.println(" Only works while connected to a wifi network. This score will stay in " - + "effect until you call reset-connected-score or the device disconnects from the " - + "current network."); - pw.println(" <score> - Integer score should be in the range of 0 - 60"); - pw.println(" reset-connected-score"); - pw.println(" Turns on the default connected scorer."); - pw.println(" Note: Will clear any external scorer set."); - pw.println(" start-softap <ssid> (open|wpa2) <passphrase> [-b 2|5|6|any]"); - pw.println(" Start softap with provided params"); - pw.println(" Note that the shell command doesn't activate internet tethering. In some " - + "devices, internet sharing is possible when Wi-Fi STA is also enabled and is" - + "associated to another AP with internet access."); - pw.println(" <ssid> - SSID of the network"); - pw.println(" open|wpa2 - Security type of the network."); - pw.println(" - Use 'open' for networks with no passphrase"); - pw.println(" - Use 'wpa2' for networks with passphrase"); - pw.println(" -b 2|5|6|any - select the preferred band."); - pw.println(" - Use '2' to select 2.4GHz band as the preferred band"); - pw.println(" - Use '5' to select 5GHz band as the preferred band"); - pw.println(" - Use '6' to select 6GHz band as the preferred band"); - pw.println(" - Use 'any' to indicate no band preference"); - pw.println(" Note: If the band option is not provided, 2.4GHz is the preferred band."); - pw.println(" The exact channel is auto-selected by FW unless overridden by " - + "force-softap-channel command"); - pw.println(" stop-softap"); - pw.println(" Stop softap (hotspot)"); - } - - private void onHelpPrivileged(PrintWriter pw) { - pw.println(" set-ipreach-disconnect enabled|disabled"); - pw.println(" Sets whether CMD_IP_REACHABILITY_LOST events should trigger disconnects."); - pw.println(" get-ipreach-disconnect"); - pw.println(" Gets setting of CMD_IP_REACHABILITY_LOST events triggering disconnects."); - pw.println(" set-poll-rssi-interval-msecs <int>"); - pw.println(" Sets the interval between RSSI polls to <int> milliseconds."); - pw.println(" get-poll-rssi-interval-msecs"); - pw.println(" Gets current interval between RSSI polls, in milliseconds."); - pw.println(" force-hi-perf-mode enabled|disabled"); - pw.println(" Sets whether hi-perf mode is forced or left for normal operation."); - pw.println(" force-low-latency-mode enabled|disabled"); - pw.println(" Sets whether low latency mode is forced or left for normal operation."); - pw.println(" network-suggestions-set-user-approved <package name> yes|no"); - pw.println(" Sets whether network suggestions from the app is approved or not."); - pw.println(" network-suggestions-has-user-approved <package name>"); - pw.println(" Queries whether network suggestions from the app is approved or not."); - pw.println(" imsi-protection-exemption-set-user-approved-for-carrier <carrier id> yes|no"); - pw.println(" Sets whether Imsi protection exemption for carrier is approved or not"); - pw.println(" imsi-protection-exemption-has-user-approved-for-carrier <carrier id>"); - pw.println(" Queries whether Imsi protection exemption for carrier is approved or not"); - pw.println(" imsi-protection-exemption-clear-user-approved-for-carrier <carrier id>"); - pw.println(" Clear the user choice on Imsi protection exemption for carrier"); - pw.println(" network-requests-remove-user-approved-access-points <package name>"); - pw.println(" Removes all user approved network requests for the app."); - pw.println(" clear-user-disabled-networks"); - pw.println(" Clears the user disabled networks list."); - pw.println(" send-link-probe"); - pw.println(" Manually triggers a link probe."); - pw.println(" force-softap-channel enabled <int> | disabled"); - pw.println(" Sets whether soft AP channel is forced to <int> MHz"); - pw.println(" or left for normal operation."); - pw.println(" force-country-code enabled <two-letter code> | disabled "); - pw.println(" Sets country code to <two-letter code> or left for normal value"); - pw.println(" set-wifi-watchdog enabled|disabled"); - pw.println(" Sets whether wifi watchdog should trigger recovery"); - pw.println(" get-wifi-watchdog"); - pw.println(" Gets setting of wifi watchdog trigger recovery."); - pw.println(" get-softap-supported-features"); - pw.println(" Gets softap supported features. Will print 'wifi_softap_acs_supported'"); - pw.println(" and/or 'wifi_softap_wpa3_sae_supported', each on a separate line."); - pw.println(" settings-reset"); - pw.println(" Initiates wifi settings reset"); - pw.println(" add-request <ssid> open|owe|wpa2|wpa3 [<passphrase>] [-b <bssid>]"); - pw.println(" Add a network request with provided params"); - pw.println(" Use 'network-requests-set-user-approved android yes'" - + " to pre-approve requests added via rooted shell (Not persisted)"); - pw.println(" <ssid> - SSID of the network"); - pw.println(" open|owe|wpa2|wpa3 - Security type of the network."); - pw.println(" - Use 'open' or 'owe' for networks with no passphrase"); - pw.println(" - 'open' - Open networks (Most prevalent)"); - pw.println(" - 'owe' - Enhanced open networks"); - pw.println(" - Use 'wpa2' or 'wpa3' for networks with passphrase"); - pw.println(" - 'wpa2' - WPA-2 PSK networks (Most prevalent)"); - pw.println(" - 'wpa3' - WPA-3 PSK networks"); - pw.println(" -b <bssid> - Set specific BSSID."); - pw.println(" remove-request <ssid>"); - pw.println(" Remove a network request with provided SSID of the network"); - pw.println(" remove-all-requests"); - pw.println(" Removes all active requests added via shell"); - pw.println(" list-requests"); - pw.println(" Lists the requested networks added via shell"); - pw.println(" network-requests-set-user-approved <package name> yes|no"); - pw.println(" Sets whether network requests from the app is approved or not."); - pw.println(" Note: Only 1 such app can be approved from the shell at a time"); - pw.println(" network-requests-has-user-approved <package name>"); - pw.println(" Queries whether network requests from the app is approved or not."); - pw.println(" Note: This only returns whether the app was set via the " - + "'network-requests-set-user-approved' shell command"); - pw.println(" list-all-suggestions"); - pw.println(" Lists all suggested networks on this device"); - pw.println(" list-suggestions-from-app <package name>"); - pw.println(" Lists the suggested networks from the app"); - pw.println(" set-emergency-callback-mode enabled|disabled"); - pw.println(" Sets whether Emergency Callback Mode (ECBM) is enabled."); - pw.println(" Equivalent to receiving the " - + "TelephonyManager.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED broadcast."); - pw.println(" set-emergency-call-state enabled|disabled"); - pw.println(" Sets whether we are in the middle of an emergency call."); - pw.println("Equivalent to receiving the " - + "TelephonyManager.ACTION_EMERGENCY_CALL_STATE_CHANGED broadcast."); - } - - @Override - public void onHelp() { - final PrintWriter pw = getOutPrintWriter(); - pw.println("Wi-Fi (wifi) commands:"); - pw.println(" help or -h"); - pw.println(" Print this help text."); - onHelpNonPrivileged(pw); - if (Binder.getCallingUid() == Process.ROOT_UID) { - onHelpPrivileged(pw); - } - pw.println(); - } - private void printWifiNetworkSuggestions(PrintWriter pw, - Collection<WifiNetworkSuggestion> suggestions) { - if (suggestions == null || suggestions.isEmpty()) { - pw.println("No suggestions on this device"); - } else { - pw.println("SSID Security type"); - for (WifiNetworkSuggestion suggestion : suggestions) { - String securityType = null; - if (suggestion.getPasspointConfig() != null) { - securityType = "passpoint"; - } else if (WifiConfigurationUtil.isConfigForSaeNetwork( - suggestion.getWifiConfiguration())) { - securityType = "wpa3"; - } else if (WifiConfigurationUtil.isConfigForPskNetwork( - suggestion.getWifiConfiguration())) { - securityType = "wpa2"; - } else if (WifiConfigurationUtil.isConfigForEapNetwork( - suggestion.getWifiConfiguration())) { - securityType = "eap"; - } else if (WifiConfigurationUtil.isConfigForOweNetwork( - suggestion.getWifiConfiguration())) { - securityType = "owe"; - } else if (WifiConfigurationUtil.isConfigForOpenNetwork( - suggestion.getWifiConfiguration())) { - securityType = "open"; - } - pw.println(String.format("%-32s %-4s", - WifiInfo.sanitizeSsid(suggestion.getWifiConfiguration().SSID), - securityType)); - } - } - } -} |