summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2019-12-09 17:08:30 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-12-09 17:08:30 +0000
commita669e034decb682f145e089cec6c204b09e0c07c (patch)
treedbfb818ee5a9e10aca4eed077f2f4cf3b52d69c7 /service
parent7563bf5a395006fedea65d4c648a8bda9997148a (diff)
parentc126b1d1e26eed110910e5a9459a1db7b59b7bf6 (diff)
Merge changes from topics "suggestion_no_uid_package", "wifi_key_value_list_parser", "wifi_power_profile", "wifi_service_manager_getService", "wifi_westworld"
* changes: wifi: Use auto-generated statsd code for logging wifi: Copy over KeyValueListParser ActiveModeWarden: Don't cache resource value in constructor WifiNetworkSuggestionManager: Store the uid/package name for suggestion wifi: Use public WifiP2pManager, WifiAwareManager objects LastMileLogger: Alternative for IoUtils.readFileAsByteArray WifiDiagnostics: Use public API for bugreport collection wifi: Create our version of ArrayUtils WifiService: Don't calculate energyUsed for WifiActivityEnergyInfo
Diffstat (limited to 'service')
-rw-r--r--service/Android.bp13
-rw-r--r--service/jarjar-rules-shared.txt3
-rw-r--r--service/java/com/android/server/wifi/ActiveModeWarden.java5
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java10
-rw-r--r--service/java/com/android/server/wifi/LastMileLogger.java6
-rw-r--r--service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java48
-rw-r--r--service/java/com/android/server/wifi/NetworkSuggestionStoreData.java139
-rw-r--r--service/java/com/android/server/wifi/ScoringParams.java2
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaNetworkHal.java2
-rw-r--r--service/java/com/android/server/wifi/WifiDiagnostics.java34
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java5
-rw-r--r--service/java/com/android/server/wifi/WifiKeyStore.java2
-rw-r--r--service/java/com/android/server/wifi/WifiLockManager.java46
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java2
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java94
-rw-r--r--service/java/com/android/server/wifi/WifiServiceImpl.java36
-rw-r--r--service/java/com/android/server/wifi/WifiVendorHal.java2
-rw-r--r--service/java/com/android/server/wifi/hotspot2/PasspointProvider.java2
-rw-r--r--service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java2
-rw-r--r--service/java/com/android/server/wifi/rtt/RttService.java8
-rw-r--r--service/java/com/android/server/wifi/rtt/RttServiceImpl.java50
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java2
-rw-r--r--service/java/com/android/server/wifi/util/ArrayUtils.java187
-rw-r--r--service/java/com/android/server/wifi/util/KeyValueListParser.java410
-rw-r--r--service/java/com/android/server/wifi/util/ScanResultUtil.java1
25 files changed, 856 insertions, 255 deletions
diff --git a/service/Android.bp b/service/Android.bp
index 580a5e69c..40e8aec87 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -76,7 +76,8 @@ filegroup {
"java/**/*.java",
"java/**/I*.aidl",
"java/**/*.logtags",
- ":framework-wifistack-shared-srcs",
+ ":framework-wifi-service-shared-srcs",
+ ":statslog-wifi-java-gen",
],
}
@@ -152,6 +153,16 @@ java_library {
init_rc: ["wifi.rc"],
}
+// Westworld auto-generated code
+// ============================================================
+genrule {
+ name: "statslog-wifi-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module wifi " +
+ " --javaPackage com.android.server.wifi.proto --javaClass WifiStatsLog",
+ out: ["com/android/server/wifi/proto/WifiStatsLog.java"],
+}
+
// APK to hold all the wifi overlayable resources.
// TODO: This should be signed by a wifi specific certificate.
// ============================================================
diff --git a/service/jarjar-rules-shared.txt b/service/jarjar-rules-shared.txt
index 7a270f92b..f17d0c3ac 100644
--- a/service/jarjar-rules-shared.txt
+++ b/service/jarjar-rules-shared.txt
@@ -12,11 +12,8 @@ rule com.android.internal.util.WakeupMessage* com.android.server.x.wifi.util.Wak
rule com.android.internal.util.XmlUtils* com.android.server.x.wifi.util.XmlUtils@1
rule android.util.BackupUtils* com.android.server.x.wifi.util.BackupUtils@1
-rule android.util.KeyValueListParser* com.android.server.x.wifi.util.KeyValueListParser@1
rule android.util.LocalLog* com.android.server.x.wifi.util.LocalLog@1
rule android.util.Rational* com.android.server.x.wifi.util.Rational@1
-rule android.util.proto.ProtoStream* com.android.server.x.wifi.util.proto.ProtoStream@1
-rule android.util.proto.ProtoOutputStream* com.android.server.x.wifi.util.proto.ProtoOutputStream@1
rule android.os.HandlerExecutor* com.android.server.x.wifi.os.HandlerExecutor@1
diff --git a/service/java/com/android/server/wifi/ActiveModeWarden.java b/service/java/com/android/server/wifi/ActiveModeWarden.java
index df27ecd6d..65bfcc82a 100644
--- a/service/java/com/android/server/wifi/ActiveModeWarden.java
+++ b/service/java/com/android/server/wifi/ActiveModeWarden.java
@@ -71,7 +71,6 @@ public class ActiveModeWarden {
private final BatteryStatsManager mBatteryStatsManager;
private final ScanRequestProxy mScanRequestProxy;
private final WifiController mWifiController;
- private final boolean mScanHiddenNetworksScanOnlyMode;
private WifiManager.SoftApCallback mSoftApCallback;
private WifiManager.SoftApCallback mLohsCallback;
@@ -115,8 +114,6 @@ public class ActiveModeWarden {
mBatteryStatsManager = batteryStatsManager;
mScanRequestProxy = wifiInjector.getScanRequestProxy();
mWifiController = new WifiController();
- mScanHiddenNetworksScanOnlyMode = context.getResources().getBoolean(
- R.bool.config_wifiScanHiddenNetworksScanOnlyMode);
wifiNative.registerStatusListener(isReady -> {
if (!isReady) {
@@ -473,7 +470,7 @@ public class ActiveModeWarden {
boolean scanEnabled = hasAnyClientModeManager();
boolean scanningForHiddenNetworksEnabled;
- if (mScanHiddenNetworksScanOnlyMode) {
+ if (mContext.getResources().getBoolean(R.bool.config_wifiScanHiddenNetworksScanOnlyMode)) {
scanningForHiddenNetworksEnabled = hasAnyClientModeManager();
} else {
scanningForHiddenNetworksEnabled = hasAnyClientModeManagerInConnectivityRole();
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index f358e9acd..474b094cf 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -71,7 +71,7 @@ import android.net.wifi.WifiManager.DeviceMobilityState;
import android.net.wifi.WifiNetworkAgentSpecifier;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
-import android.net.wifi.p2p.IWifiP2pManager;
+import android.net.wifi.p2p.WifiP2pManager;
import android.os.BatteryStatsManager;
import android.os.Bundle;
import android.os.ConditionVariable;
@@ -2955,14 +2955,12 @@ public class ClientModeImpl extends StateMachine {
private void getAdditionalWifiServiceInterfaces() {
// First set up Wifi Direct
if (mP2pSupported) {
- IBinder s1 = mFacade.getService(Context.WIFI_P2P_SERVICE);
- WifiP2pServiceImpl wifiP2pServiceImpl =
- (WifiP2pServiceImpl) IWifiP2pManager.Stub.asInterface(s1);
+ WifiP2pManager wifiP2pService = mContext.getSystemService(WifiP2pManager.class);
- if (wifiP2pServiceImpl != null) {
+ if (wifiP2pService != null) {
mWifiP2pChannel = new AsyncChannel();
mWifiP2pChannel.connect(mContext, getHandler(),
- wifiP2pServiceImpl.getP2pStateMachineMessenger());
+ wifiP2pService.getP2pStateMachineMessenger());
}
}
}
diff --git a/service/java/com/android/server/wifi/LastMileLogger.java b/service/java/com/android/server/wifi/LastMileLogger.java
index cc0685a47..6cf921dd6 100644
--- a/service/java/com/android/server/wifi/LastMileLogger.java
+++ b/service/java/com/android/server/wifi/LastMileLogger.java
@@ -20,11 +20,11 @@ package com.android.server.wifi;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.util.FileUtils;
-import libcore.io.IoUtils;
-
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Paths;
/**
* Provides a facility for capturing kernel trace events related to Wifi control and data paths.
@@ -113,7 +113,7 @@ public class LastMileLogger {
private byte[] readTrace() {
try {
- return IoUtils.readFileAsByteArray(mEventBufferPath);
+ return Files.readAllBytes(Paths.get(mEventBufferPath));
} catch (IOException e) {
mLog.warn("Failed to read event trace: %").r(e.getMessage()).flush();
return new byte[0];
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java b/service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java
index 81af4b8b4..c8f370bcc 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionEvaluator.java
@@ -19,10 +19,10 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiNetworkSuggestion;
import android.util.LocalLog;
import android.util.Log;
+import com.android.server.wifi.WifiNetworkSuggestionsManager.ExtendedWifiNetworkSuggestion;
import com.android.server.wifi.util.ScanResultUtil;
import java.util.ArrayList;
@@ -90,22 +90,22 @@ public class NetworkSuggestionEvaluator implements WifiNetworkSelector.NetworkEv
+ WifiNetworkSelector.toScanId(scanResult));
continue;
}
- Set<WifiNetworkSuggestion> matchingNetworkSuggestions =
+ Set<ExtendedWifiNetworkSuggestion> matchingExtNetworkSuggestions =
mWifiNetworkSuggestionsManager.getNetworkSuggestionsForScanDetail(scanDetail);
- if (matchingNetworkSuggestions == null || matchingNetworkSuggestions.isEmpty()) {
+ if (matchingExtNetworkSuggestions == null || matchingExtNetworkSuggestions.isEmpty()) {
continue;
}
// All matching suggestions have the same network credentials type. So, use any one of
// them to lookup/add the credentials to WifiConfigManager.
// Note: Apps could provide different credentials (password, ceritificate) for the same
// network, need to handle that in the future.
- WifiNetworkSuggestion matchingNetworkSuggestion =
- matchingNetworkSuggestions.stream().findAny().get();
+ ExtendedWifiNetworkSuggestion matchingExtNetworkSuggestion =
+ matchingExtNetworkSuggestions.stream().findAny().get();
// Check if we already have a network with the same credentials in WifiConfigManager
// database.
WifiConfiguration wCmConfiguredNetwork =
mWifiConfigManager.getConfiguredNetwork(
- matchingNetworkSuggestion.wifiConfiguration.getKey());
+ matchingExtNetworkSuggestion.wns.wifiConfiguration.getKey());
if (wCmConfiguredNetwork != null) {
// If existing network is not from suggestion, ignore.
if (!wCmConfiguredNetwork.fromWifiNetworkSuggestion) {
@@ -113,9 +113,9 @@ public class NetworkSuggestionEvaluator implements WifiNetworkSelector.NetworkEv
}
// Update the WifiConfigManager with the latest WifiConfig
NetworkUpdateResult result = mWifiConfigManager.addOrUpdateNetwork(
- matchingNetworkSuggestion.wifiConfiguration,
- matchingNetworkSuggestion.suggestorUid,
- matchingNetworkSuggestion.suggestorPackageName);
+ matchingExtNetworkSuggestion.wns.wifiConfiguration,
+ matchingExtNetworkSuggestion.perAppInfo.uid,
+ matchingExtNetworkSuggestion.perAppInfo.packageName);
if (result.isSuccess()) {
wCmConfiguredNetwork = mWifiConfigManager.getConfiguredNetwork(
result.getNetworkId());
@@ -128,7 +128,7 @@ public class NetworkSuggestionEvaluator implements WifiNetworkSelector.NetworkEv
continue;
}
}
- matchMetaInfo.putAll(matchingNetworkSuggestions, wCmConfiguredNetwork, scanDetail);
+ matchMetaInfo.putAll(matchingExtNetworkSuggestions, wCmConfiguredNetwork, scanDetail);
}
// Return early on no match.
if (matchMetaInfo.isEmpty()) {
@@ -181,14 +181,15 @@ public class NetworkSuggestionEvaluator implements WifiNetworkSelector.NetworkEv
// Container classes to handle book-keeping while we're iterating through the scan list.
private class PerNetworkSuggestionMatchMetaInfo {
- public final WifiNetworkSuggestion wifiNetworkSuggestion;
+ public final ExtendedWifiNetworkSuggestion extWifiNetworkSuggestion;
public final ScanDetail matchingScanDetail;
public WifiConfiguration wCmConfiguredNetwork; // Added to WifiConfigManager.
- PerNetworkSuggestionMatchMetaInfo(@NonNull WifiNetworkSuggestion wifiNetworkSuggestion,
- @Nullable WifiConfiguration wCmConfiguredNetwork,
- @NonNull ScanDetail matchingScanDetail) {
- this.wifiNetworkSuggestion = wifiNetworkSuggestion;
+ PerNetworkSuggestionMatchMetaInfo(
+ @NonNull ExtendedWifiNetworkSuggestion extWifiNetworkSuggestion,
+ @Nullable WifiConfiguration wCmConfiguredNetwork,
+ @NonNull ScanDetail matchingScanDetail) {
+ this.extWifiNetworkSuggestion = extWifiNetworkSuggestion;
this.wCmConfiguredNetwork = wCmConfiguredNetwork;
this.matchingScanDetail = matchingScanDetail;
}
@@ -200,7 +201,7 @@ public class NetworkSuggestionEvaluator implements WifiNetworkSelector.NetworkEv
/**
* Add the network suggestion & associated info to this package meta info.
*/
- public void put(WifiNetworkSuggestion wifiNetworkSuggestion,
+ public void put(ExtendedWifiNetworkSuggestion wifiNetworkSuggestion,
WifiConfiguration matchingWifiConfiguration,
ScanDetail matchingScanDetail) {
networkInfos.add(new PerNetworkSuggestionMatchMetaInfo(
@@ -217,7 +218,7 @@ public class NetworkSuggestionEvaluator implements WifiNetworkSelector.NetworkEv
Map<Integer, List<PerNetworkSuggestionMatchMetaInfo>> matchedNetworkInfosPerPriority =
networkInfos.stream()
.collect(Collectors.toMap(
- e -> e.wifiNetworkSuggestion.wifiConfiguration.priority,
+ e -> e.extWifiNetworkSuggestion.wns.wifiConfiguration.priority,
e -> Arrays.asList(e),
(v1, v2) -> { // concatenate networks with the same priority.
List<PerNetworkSuggestionMatchMetaInfo> concatList =
@@ -241,14 +242,15 @@ public class NetworkSuggestionEvaluator implements WifiNetworkSelector.NetworkEv
/**
* Add all the network suggestion & associated info.
*/
- public void putAll(Set<WifiNetworkSuggestion> wifiNetworkSuggestions,
+ public void putAll(Set<ExtendedWifiNetworkSuggestion> wifiNetworkSuggestions,
WifiConfiguration wCmConfiguredNetwork,
ScanDetail matchingScanDetail) {
// Separate the suggestions into buckets for each app to allow sorting based on
// priorities set by app.
- for (WifiNetworkSuggestion wifiNetworkSuggestion : wifiNetworkSuggestions) {
+ for (ExtendedWifiNetworkSuggestion wifiNetworkSuggestion : wifiNetworkSuggestions) {
PerAppMatchMetaInfo appInfo = mAppInfos.computeIfAbsent(
- wifiNetworkSuggestion.suggestorPackageName, k -> new PerAppMatchMetaInfo());
+ wifiNetworkSuggestion.perAppInfo.packageName,
+ k -> new PerAppMatchMetaInfo());
appInfo.put(wifiNetworkSuggestion, wCmConfiguredNetwork, matchingScanDetail);
}
}
@@ -278,9 +280,9 @@ public class NetworkSuggestionEvaluator implements WifiNetworkSelector.NetworkEv
// if the network does not already exist in WifiConfigManager, add now.
if (matchedNetworkInfo.wCmConfiguredNetwork == null) {
matchedNetworkInfo.wCmConfiguredNetwork = addCandidateToWifiConfigManager(
- matchedNetworkInfo.wifiNetworkSuggestion.wifiConfiguration,
- matchedNetworkInfo.wifiNetworkSuggestion.suggestorUid,
- matchedNetworkInfo.wifiNetworkSuggestion.suggestorPackageName);
+ matchedNetworkInfo.extWifiNetworkSuggestion.wns.wifiConfiguration,
+ matchedNetworkInfo.extWifiNetworkSuggestion.perAppInfo.uid,
+ matchedNetworkInfo.extWifiNetworkSuggestion.perAppInfo.packageName);
if (matchedNetworkInfo.wCmConfiguredNetwork == null) continue;
mLocalLog.log(String.format("network suggestion candidate %s (new)",
WifiNetworkSelector.toNetworkString(
diff --git a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
index 9641f5c16..eaa58709a 100644
--- a/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
+++ b/service/java/com/android/server/wifi/NetworkSuggestionStoreData.java
@@ -41,7 +41,6 @@ import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -162,10 +161,11 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
return;
}
for (Entry<String, PerAppInfo> entry : networkSuggestionsMap.entrySet()) {
- String packageName = entry.getKey();
+ String packageName = entry.getValue().packageName;
String featureId = entry.getValue().featureId;
boolean hasUserApproved = entry.getValue().hasUserApproved;
int maxSize = entry.getValue().maxSize;
+ int uid = entry.getValue().uid;
Set<ExtendedWifiNetworkSuggestion> networkSuggestions =
entry.getValue().extNetworkSuggestions;
XmlUtil.writeNextSectionStart(out, XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION_PER_APP);
@@ -173,6 +173,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_FEATURE_ID, featureId);
XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_HAS_USER_APPROVED, hasUserApproved);
XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_MAX_SIZE, maxSize);
+ XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_UID, uid);
serializeExtNetworkSuggestions(out, networkSuggestions, encryptionUtil);
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION_PER_APP);
}
@@ -234,10 +235,6 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
suggestion.isUserInteractionRequired);
XmlUtil.writeNextValue(out, XML_TAG_IS_USER_ALLOWED_TO_MANUALLY_CONNECT,
suggestion.isUserAllowedToManuallyConnect);
- XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_UID, suggestion.suggestorUid);
- XmlUtil.writeNextValue(out, XML_TAG_SUGGESTOR_PACKAGE_NAME,
- suggestion.suggestorPackageName);
-
XmlUtil.writeNextSectionEnd(out, XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION);
}
@@ -257,20 +254,74 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
// Try/catch only runtime exceptions (like illegal args), any XML/IO exceptions are
// fatal and should abort the entire loading process.
try {
- String packageName =
- (String) XmlUtil.readNextValueWithName(in, XML_TAG_SUGGESTOR_PACKAGE_NAME);
- String featureId =
- (String) XmlUtil.readNextValueWithName(in, XML_TAG_SUGGESTOR_FEATURE_ID);
- boolean hasUserApproved = (boolean) XmlUtil.readNextValueWithName(in,
- XML_TAG_SUGGESTOR_HAS_USER_APPROVED);
- int maxSize = (int) XmlUtil.readNextValueWithName(in, XML_TAG_SUGGESTOR_MAX_SIZE);
- PerAppInfo perAppInfo = new PerAppInfo(packageName, featureId);
- Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions =
- parseExtNetworkSuggestions(
- in, outerTagDepth + 1, version, encryptionUtil, perAppInfo);
- perAppInfo.hasUserApproved = hasUserApproved;
- perAppInfo.maxSize = maxSize;
- perAppInfo.extNetworkSuggestions.addAll(extNetworkSuggestions);
+ PerAppInfo perAppInfo = null;
+ String packageName = null;
+ String featureId = null;
+ boolean hasUserApproved = false;
+ int maxSize = -1;
+ int uid = Process.INVALID_UID;
+ // Loop through and parse out all the elements from the stream within this section.
+ while (XmlUtils.nextElementWithin(in, outerTagDepth + 1)) {
+ if (in.getAttributeValue(null, "name") != null) {
+ // Value elements.
+ String[] valueName = new String[1];
+ Object value = XmlUtil.readCurrentValue(in, valueName);
+ switch (valueName[0]) {
+ case XML_TAG_SUGGESTOR_PACKAGE_NAME:
+ packageName = (String) value;
+ break;
+ case XML_TAG_SUGGESTOR_FEATURE_ID:
+ featureId = (String) value;
+ break;
+ case XML_TAG_SUGGESTOR_HAS_USER_APPROVED:
+ hasUserApproved = (boolean) value;
+ break;
+ case XML_TAG_SUGGESTOR_MAX_SIZE:
+ maxSize = (int) value;
+ break;
+ case XML_TAG_SUGGESTOR_UID:
+ uid = (int) value;
+ break;
+ default:
+ Log.w(TAG, "Ignoring unknown value name found: " + valueName[0]);
+ break;
+ }
+ } else {
+ String tagName = in.getName();
+ if (tagName == null) {
+ throw new XmlPullParserException("Unexpected null under "
+ + XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION_PER_APP);
+ }
+ // Create the PerAppInfo struct before parsing individual network
+ // suggestions in the block.
+ if (perAppInfo == null) {
+ if (packageName == null) {
+ throw new XmlPullParserException(
+ "XML parsing of PerAppInfo failed");
+ }
+ perAppInfo = new PerAppInfo(uid, packageName, featureId);
+ perAppInfo.hasUserApproved = hasUserApproved;
+ perAppInfo.maxSize = maxSize;
+ }
+ switch (tagName) {
+ case XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION:
+ WifiNetworkSuggestion networkSuggestion =
+ parseNetworkSuggestion(
+ in, outerTagDepth + 2, version, encryptionUtil,
+ perAppInfo);
+ perAppInfo.extNetworkSuggestions.add(
+ ExtendedWifiNetworkSuggestion.fromWns(
+ networkSuggestion, perAppInfo));
+ break;
+ default:
+ Log.w(TAG, "Ignoring unknown tag under "
+ + XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION_PER_APP + ": "
+ + in.getName());
+ break;
+ }
+ }
+ }
+ // Store this app info in the map.
networkSuggestionsMap.put(packageName, perAppInfo);
} catch (RuntimeException e) {
// Failed to parse this network, skip it.
@@ -281,34 +332,6 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
}
/**
- * Parse a set of network suggestions from an input stream in XML format.
- *
- * @throws XmlPullParserException
- * @throws IOException
- */
- private Set<ExtendedWifiNetworkSuggestion> parseExtNetworkSuggestions(
- XmlPullParser in, int outerTagDepth, @WifiConfigStore.Version int version,
- @Nullable WifiConfigStoreEncryptionUtil encryptionUtil, PerAppInfo perAppInfo)
- throws XmlPullParserException, IOException {
- Set<ExtendedWifiNetworkSuggestion> extNetworkSuggestions = new HashSet<>();
- while (XmlUtil.gotoNextSectionWithNameOrEnd(
- in, XML_TAG_SECTION_HEADER_NETWORK_SUGGESTION, outerTagDepth)) {
- // Try/catch only runtime exceptions (like illegal args), any XML/IO exceptions are
- // fatal and should abort the entire loading process.
- try {
- WifiNetworkSuggestion networkSuggestion =
- parseNetworkSuggestion(in, outerTagDepth + 1, version, encryptionUtil);
- extNetworkSuggestions.add(ExtendedWifiNetworkSuggestion.fromWns(
- networkSuggestion, perAppInfo));
- } catch (RuntimeException e) {
- // Failed to parse this network, skip it.
- Log.e(TAG, "Failed to parse network suggestion. Skipping...", e);
- }
- }
- return extNetworkSuggestions;
- }
-
- /**
* Parse a {@link ExtendedWifiNetworkSuggestion} from an input stream in XML format.
*
* @throws XmlPullParserException
@@ -316,7 +339,7 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
*/
private WifiNetworkSuggestion parseNetworkSuggestion(XmlPullParser in, int outerTagDepth,
@WifiConfigStore.Version int version,
- @Nullable WifiConfigStoreEncryptionUtil encryptionUtil)
+ @Nullable WifiConfigStoreEncryptionUtil encryptionUtil, PerAppInfo perAppInfo)
throws XmlPullParserException, IOException {
Pair<String, WifiConfiguration> parsedConfig = null;
WifiEnterpriseConfig enterpriseConfig = null;
@@ -325,7 +348,6 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
boolean isUserInteractionRequired = false;
boolean isUserAllowedToManuallyConnect = false; // Backward compatibility.
int suggestorUid = Process.INVALID_UID;
- String suggestorPackageName = null;
// Loop through and parse out all the elements from the stream within this section.
while (XmlUtils.nextElementWithin(in, outerTagDepth)) {
@@ -344,11 +366,9 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
isUserAllowedToManuallyConnect = (boolean) value;
break;
case XML_TAG_SUGGESTOR_UID:
+ // Only needed for migration of data from Q to R.
suggestorUid = (int) value;
break;
- case XML_TAG_SUGGESTOR_PACKAGE_NAME:
- suggestorPackageName = (String) value;
- break;
default:
Log.w(TAG, "Ignoring unknown value name found: " + valueName[0]);
break;
@@ -398,20 +418,17 @@ public class NetworkSuggestionStoreData implements WifiConfigStore.StoreData {
if (parsedConfig == null || parsedConfig.second == null) {
throw new XmlPullParserException("XML parsing of wifi configuration failed");
}
- if (suggestorUid == -1) {
- throw new XmlPullParserException("XML parsing of suggestor uid failed");
- }
- if (suggestorPackageName == null) {
- throw new XmlPullParserException("XML parsing of suggestor package name failed");
- }
+ // Note: In R, we migrated the uid/package name storage from individual
+ // ExtWifiNetworkSuggestion to the top level PerAppInfo. This block of code helps
+ // with migration of data for devices upgrading from Q to R.
+ perAppInfo.setUid(suggestorUid);
WifiConfiguration wifiConfiguration = parsedConfig.second;
if (enterpriseConfig != null) {
wifiConfiguration.enterpriseConfig = enterpriseConfig;
}
return new WifiNetworkSuggestion(
wifiConfiguration, passpointConfiguration, isAppInteractionRequired,
- isUserInteractionRequired, isUserAllowedToManuallyConnect,
- suggestorUid, suggestorPackageName);
+ isUserInteractionRequired, isUserAllowedToManuallyConnect);
}
}
diff --git a/service/java/com/android/server/wifi/ScoringParams.java b/service/java/com/android/server/wifi/ScoringParams.java
index fa0d0ddee..b36c3e9fa 100644
--- a/service/java/com/android/server/wifi/ScoringParams.java
+++ b/service/java/com/android/server/wifi/ScoringParams.java
@@ -22,10 +22,10 @@ import android.database.ContentObserver;
import android.net.wifi.WifiInfo;
import android.os.Handler;
import android.provider.Settings;
-import android.util.KeyValueListParser;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.util.KeyValueListParser;
import com.android.wifi.resources.R;
/**
diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
index 824e10e83..3508cf71f 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
@@ -29,7 +29,7 @@ import android.util.Log;
import android.util.MutableBoolean;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
+import com.android.server.wifi.util.ArrayUtils;
import com.android.server.wifi.util.GeneralUtil.Mutable;
import com.android.server.wifi.util.NativeUtil;
import com.android.wifi.resources.R;
diff --git a/service/java/com/android/server/wifi/WifiDiagnostics.java b/service/java/com/android/server/wifi/WifiDiagnostics.java
index 1e6386716..3e22d863f 100644
--- a/service/java/com/android/server/wifi/WifiDiagnostics.java
+++ b/service/java/com/android/server/wifi/WifiDiagnostics.java
@@ -18,9 +18,8 @@ package com.android.server.wifi;
import android.annotation.NonNull;
import android.content.Context;
-import android.content.Intent;
+import android.os.BugreportManager;
import android.os.BugreportParams;
-import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Base64;
import android.util.Log;
@@ -62,14 +61,6 @@ class WifiDiagnostics extends BaseWifiDiagnostics {
private static final String TAG = "WifiDiags";
private static final boolean DBG = false;
- // TODO (b/143494985): Use formal API instead of sending this intent.
- private static final String INTENT_BUGREPORT_REQUESTED =
- "com.android.internal.intent.action.BUGREPORT_REQUESTED";
- private static final String SHELL_APP_PACKAGE = "com.android.shell";
- private static final String EXTRA_TITLE = "android.intent.extra.TITLE";
- private static final String EXTRA_DESCRIPTION = "android.intent.extra.DESCRIPTION";
- private static final String EXTRA_BUGREPORT_TYPE = "android.intent.extra.BUGREPORT_TYPE";
-
/** log level flags; keep these consistent with wifi_logger.h */
/** No logs whatsoever */
@@ -306,26 +297,11 @@ class WifiDiagnostics extends BaseWifiDiagnostics {
R.bool.config_wifi_diagnostics_bugreport_enabled)) {
return;
}
-
- // TODO (b/143494985): Use formal API instead of sending this intent.
- // The below code snippet is copied from ActivityManager.requestBugReportWithDescription()
- // Create intent to trigger Bugreport API via Shell
- Intent triggerShellBugreport = new Intent();
- triggerShellBugreport.setAction(INTENT_BUGREPORT_REQUESTED);
- triggerShellBugreport.setPackage(SHELL_APP_PACKAGE);
- triggerShellBugreport.putExtra(EXTRA_BUGREPORT_TYPE, BugreportParams.BUGREPORT_MODE_WIFI);
- triggerShellBugreport.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- triggerShellBugreport.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- if (bugTitle != null) {
- triggerShellBugreport.putExtra(EXTRA_TITLE, bugTitle);
- }
- if (bugDetail != null) {
- triggerShellBugreport.putExtra(EXTRA_DESCRIPTION, bugDetail);
- }
+ BugreportManager bugreportManager = mContext.getSystemService(BugreportManager.class);
+ BugreportParams params = new BugreportParams(BugreportParams.BUGREPORT_MODE_WIFI);
try {
- // Send broadcast to shell to trigger bugreport using Bugreport API
- mContext.sendBroadcastAsUser(triggerShellBugreport, UserHandle.CURRENT);
- } catch (Exception e) { // diagnostics should never crash system_server
+ bugreportManager.requestBugreport(params, bugTitle, bugDetail);
+ } catch (RuntimeException e) {
mLog.err("error taking bugreport: %").c(e.getClass().getName()).flush();
}
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index e941b99dd..bd2a435d1 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -46,7 +46,6 @@ import android.telephony.TelephonyManager;
import android.util.LocalLog;
import android.util.Log;
-import com.android.internal.os.PowerProfile;
import com.android.server.wifi.aware.WifiAwareMetrics;
import com.android.server.wifi.hotspot2.PasspointManager;
import com.android.server.wifi.hotspot2.PasspointNetworkEvaluator;
@@ -734,10 +733,6 @@ public class WifiInjector {
return mSelfRecovery;
}
- public PowerProfile getPowerProfile() {
- return new PowerProfile(mContext, false);
- }
-
public ScanRequestProxy getScanRequestProxy() {
return mScanRequestProxy;
}
diff --git a/service/java/com/android/server/wifi/WifiKeyStore.java b/service/java/com/android/server/wifi/WifiKeyStore.java
index 87289fa68..5444c4dab 100644
--- a/service/java/com/android/server/wifi/WifiKeyStore.java
+++ b/service/java/com/android/server/wifi/WifiKeyStore.java
@@ -24,8 +24,8 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
+import com.android.server.wifi.util.ArrayUtils;
import java.security.Key;
import java.security.KeyStore;
diff --git a/service/java/com/android/server/wifi/WifiLockManager.java b/service/java/com/android/server/wifi/WifiLockManager.java
index e01ccadfa..4745f6e68 100644
--- a/service/java/com/android/server/wifi/WifiLockManager.java
+++ b/service/java/com/android/server/wifi/WifiLockManager.java
@@ -27,8 +27,10 @@ import android.os.RemoteException;
import android.os.WorkSource;
import android.os.WorkSource.WorkChain;
import android.util.Log;
+import android.util.Pair;
import android.util.SparseArray;
-import android.util.StatsLog;
+
+import com.android.server.wifi.proto.WifiStatsLog;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -706,18 +708,44 @@ public class WifiLockManager {
return uidCount;
}
+ private Pair<List<Integer>, List<String>> getUidsAndTagsForWs(WorkSource ws) {
+ List<Integer> uids = new ArrayList<>();
+ List<String> tags = new ArrayList<>();
+
+ for (int i = 0; i < ws.size(); i++) {
+ uids.add(ws.getUid(i));
+ tags.add(ws.getPackageName(i));
+ }
+
+ final List<WorkChain> workChains = ws.getWorkChains();
+ if (workChains != null) {
+ for (int i = 0; i < workChains.size(); ++i) {
+ final WorkChain workChain = workChains.get(i);
+ uids.add(workChain.getAttributionUid());
+ tags.add(workChain.getAttributionTag());
+ }
+ }
+ return Pair.create(uids, tags);
+ }
+
+
private void setBlameHiPerfWs(WorkSource ws, boolean shouldBlame) {
long ident = Binder.clearCallingIdentity();
+ Pair<List<Integer>, List<String>> uidsAndTags = getUidsAndTagsForWs(ws);
try {
if (shouldBlame) {
mBatteryStats.noteFullWifiLockAcquiredFromSource(ws);
- StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED, ws,
- StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON,
+ WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_STATE_CHANGED,
+ uidsAndTags.first.stream().mapToInt(Integer::intValue).toArray(),
+ uidsAndTags.second.toArray(new String[0]),
+ WifiStatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON,
WifiManager.WIFI_MODE_FULL_HIGH_PERF);
} else {
mBatteryStats.noteFullWifiLockReleasedFromSource(ws);
- StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED, ws,
- StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF,
+ WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_STATE_CHANGED,
+ uidsAndTags.first.stream().mapToInt(Integer::intValue).toArray(),
+ uidsAndTags.second.toArray(new String[0]),
+ WifiStatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF,
WifiManager.WIFI_MODE_FULL_HIGH_PERF);
}
} finally {
@@ -730,13 +758,13 @@ public class WifiLockManager {
try {
if (shouldBlame) {
mBatteryStats.noteFullWifiLockAcquiredFromSource(new WorkSource(uid));
- StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, uid, null,
- StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON,
+ WifiStatsLog.write_non_chained(WifiStatsLog.WIFI_LOCK_STATE_CHANGED, uid, null,
+ WifiStatsLog.WIFI_LOCK_STATE_CHANGED__STATE__ON,
WifiManager.WIFI_MODE_FULL_LOW_LATENCY);
} else {
mBatteryStats.noteFullWifiLockReleasedFromSource(new WorkSource(uid));
- StatsLog.write_non_chained(StatsLog.WIFI_LOCK_STATE_CHANGED, uid, null,
- StatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF,
+ WifiStatsLog.write_non_chained(WifiStatsLog.WIFI_LOCK_STATE_CHANGED, uid, null,
+ WifiStatsLog.WIFI_LOCK_STATE_CHANGED__STATE__OFF,
WifiManager.WIFI_MODE_FULL_LOW_LATENCY);
}
} finally {
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 1105db325..27e0a142a 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -56,8 +56,8 @@ import android.util.Log;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
+import com.android.server.wifi.util.ArrayUtils;
import com.android.server.wifi.util.ExternalCallbackTracker;
import com.android.server.wifi.util.ScanResultUtil;
import com.android.server.wifi.util.WifiPermissionsUtil;
diff --git a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
index 6eb4c5930..70c30dd58 100644
--- a/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
+++ b/service/java/com/android/server/wifi/WifiNetworkSuggestionsManager.java
@@ -42,6 +42,7 @@ import android.net.wifi.WifiNetworkSuggestion;
import android.net.wifi.WifiScanner;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.telephony.TelephonyManager;
@@ -122,6 +123,10 @@ public class WifiNetworkSuggestionsManager {
*/
public static class PerAppInfo {
/**
+ * UID of the app.
+ */
+ public int uid;
+ /**
* Package Name of the app.
*/
public final String packageName;
@@ -141,18 +146,30 @@ public class WifiNetworkSuggestionsManager {
/** Stores the max size of the {@link #extNetworkSuggestions} list ever for this app */
public int maxSize = 0;
- public PerAppInfo(@NonNull String packageName, @Nullable String featureId) {
+ public PerAppInfo(int uid, @NonNull String packageName, @Nullable String featureId) {
+ this.uid = uid;
this.packageName = packageName;
this.featureId = featureId;
}
+ /**
+ * Needed for migration of config store data.
+ */
+ public void setUid(int uid) {
+ if (this.uid == Process.INVALID_UID) {
+ this.uid = uid;
+ }
+ // else ignored.
+ }
+
// This is only needed for comparison in unit tests.
@Override
public boolean equals(Object other) {
if (other == null) return false;
if (!(other instanceof PerAppInfo)) return false;
PerAppInfo otherPerAppInfo = (PerAppInfo) other;
- return TextUtils.equals(packageName, otherPerAppInfo.packageName)
+ return uid == otherPerAppInfo.uid
+ && TextUtils.equals(packageName, otherPerAppInfo.packageName)
&& Objects.equals(extNetworkSuggestions, otherPerAppInfo.extNetworkSuggestions)
&& hasUserApproved == otherPerAppInfo.hasUserApproved;
}
@@ -160,7 +177,18 @@ public class WifiNetworkSuggestionsManager {
// This is only needed for comparison in unit tests.
@Override
public int hashCode() {
- return Objects.hash(packageName, extNetworkSuggestions, hasUserApproved);
+ return Objects.hash(uid, packageName, extNetworkSuggestions, hasUserApproved);
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("PerAppInfo[ ")
+ .append("uid=").append(uid)
+ .append(", packageName=").append(packageName)
+ .append(", hasUserApproved=").append(hasUserApproved)
+ .append(", suggestions=").append(extNetworkSuggestions)
+ .append(" ]")
+ .toString();
}
}
@@ -182,7 +210,7 @@ public class WifiNetworkSuggestionsManager {
@Override
public int hashCode() {
- return Objects.hash(wns); // perAppInfo not used for equals.
+ return Objects.hash(wns, perAppInfo.uid, perAppInfo.packageName);
}
@Override
@@ -194,12 +222,14 @@ public class WifiNetworkSuggestionsManager {
return false;
}
ExtendedWifiNetworkSuggestion other = (ExtendedWifiNetworkSuggestion) obj;
- return wns.equals(other.wns); // perAppInfo not used for equals.
+ return wns.equals(other.wns)
+ && perAppInfo.uid == other.perAppInfo.uid
+ && TextUtils.equals(perAppInfo.packageName, other.perAppInfo.packageName);
}
@Override
public String toString() {
- return "Extended" + wns.toString();
+ return wns.toString();
}
/**
@@ -335,7 +365,7 @@ public class WifiNetworkSuggestionsManager {
if (!extNetworkSuggestions.isEmpty()) {
// Start tracking app-op changes from the app if they have active suggestions.
startTrackingAppOpsChange(packageName,
- extNetworkSuggestions.iterator().next().wns.suggestorUid);
+ extNetworkSuggestions.iterator().next().perAppInfo.uid);
}
for (ExtendedWifiNetworkSuggestion ewns : extNetworkSuggestions) {
if (ewns.wns.wifiConfiguration.FQDN != null) {
@@ -622,7 +652,7 @@ public class WifiNetworkSuggestionsManager {
}
PerAppInfo perAppInfo = mActiveNetworkSuggestionsPerApp.get(packageName);
if (perAppInfo == null) {
- perAppInfo = new PerAppInfo(packageName, featureId);
+ perAppInfo = new PerAppInfo(uid, packageName, featureId);
mActiveNetworkSuggestionsPerApp.put(packageName, perAppInfo);
if (mWifiPermissionsUtil.checkNetworkCarrierProvisioningPermission(uid)) {
Log.i(TAG, "Setting the carrier provisioning app approved");
@@ -733,7 +763,7 @@ public class WifiNetworkSuggestionsManager {
if (ewns.wns.wifiConfiguration.FQDN != null) {
// Clear the Passpoint config.
mWifiInjector.getPasspointManager().removeProvider(
- ewns.wns.suggestorUid,
+ ewns.perAppInfo.uid,
false,
ewns.wns.wifiConfiguration.FQDN);
removeFromPassPointInfoMap(ewns);
@@ -985,7 +1015,7 @@ public class WifiNetworkSuggestionsManager {
/**
* Returns a set of all network suggestions matching the provided scan detail.
*/
- public @Nullable Set<WifiNetworkSuggestion> getNetworkSuggestionsForScanDetail(
+ public @Nullable Set<ExtendedWifiNetworkSuggestion> getNetworkSuggestionsForScanDetail(
@NonNull ScanDetail scanDetail) {
ScanResult scanResult = scanDetail.getScanResult();
if (scanResult == null) {
@@ -1033,7 +1063,7 @@ public class WifiNetworkSuggestionsManager {
for (ExtendedWifiNetworkSuggestion extNetworkSuggestion : extNetworkSuggestions) {
if (sendUserApprovalNotificationIfNotApproved(
extNetworkSuggestion.perAppInfo.packageName,
- extNetworkSuggestion.wns.suggestorUid)) {
+ extNetworkSuggestion.perAppInfo.uid)) {
break;
}
}
@@ -1046,7 +1076,7 @@ public class WifiNetworkSuggestionsManager {
+ approvedExtNetworkSuggestions + " for " + scanResult.SSID
+ "[" + scanResult.capabilities + "]");
}
- return convertToWnsSet(approvedExtNetworkSuggestions);
+ return approvedExtNetworkSuggestions;
}
/**
@@ -1079,7 +1109,7 @@ public class WifiNetworkSuggestionsManager {
return null;
}
if (mVerboseLoggingEnabled) {
- Log.v(TAG, "getNetworkSuggestionsFoWifiConfiguration Found "
+ Log.v(TAG, "getNetworkSuggestionsForWifiConfiguration Found "
+ approvedExtNetworkSuggestions + " for " + wifiConfiguration.SSID
+ wifiConfiguration.FQDN + "[" + wifiConfiguration.allowedKeyManagement + "]");
}
@@ -1112,32 +1142,35 @@ public class WifiNetworkSuggestionsManager {
* Helper method to send the post connection broadcast to specified package.
*/
private void sendPostConnectionBroadcast(
- String packageName, WifiNetworkSuggestion networkSuggestion) {
+ ExtendedWifiNetworkSuggestion extSuggestion) {
Intent intent = new Intent(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);
- intent.putExtra(WifiManager.EXTRA_NETWORK_SUGGESTION, networkSuggestion);
+ intent.putExtra(WifiManager.EXTRA_NETWORK_SUGGESTION, extSuggestion.wns);
// Intended to wakeup the receiving app so set the specific package name.
- intent.setPackage(packageName);
+ intent.setPackage(extSuggestion.perAppInfo.packageName);
mContext.sendBroadcastAsUser(
- intent, UserHandle.getUserHandleForUid(networkSuggestion.suggestorUid));
+ intent, UserHandle.getUserHandleForUid(extSuggestion.perAppInfo.uid));
}
/**
* Helper method to send the post connection broadcast to specified package.
*/
private void sendPostConnectionBroadcastIfAllowed(
- String packageName, String featureId, WifiNetworkSuggestion matchingSuggestion,
- @NonNull String message) {
+ ExtendedWifiNetworkSuggestion matchingExtSuggestion, @NonNull String message) {
try {
mWifiPermissionsUtil.enforceCanAccessScanResults(
- packageName, featureId, matchingSuggestion.suggestorUid, message);
+ matchingExtSuggestion.perAppInfo.packageName,
+ matchingExtSuggestion.perAppInfo.featureId,
+ matchingExtSuggestion.perAppInfo.uid, message);
} catch (SecurityException se) {
- Log.w(TAG, "Permission denied for sending post connection broadcast to " + packageName);
+ Log.w(TAG, "Permission denied for sending post connection broadcast to "
+ + matchingExtSuggestion.perAppInfo.packageName);
return;
}
if (mVerboseLoggingEnabled) {
- Log.v(TAG, "Sending post connection broadcast to " + packageName);
+ Log.v(TAG, "Sending post connection broadcast to "
+ + matchingExtSuggestion.perAppInfo.packageName);
}
- sendPostConnectionBroadcast(packageName, matchingSuggestion);
+ sendPostConnectionBroadcast(matchingExtSuggestion);
}
/**
@@ -1170,7 +1203,7 @@ public class WifiNetworkSuggestionsManager {
// Find subset of network suggestions from app suggested the connected network.
matchingExtNetworkSuggestions =
matchingExtNetworkSuggestions.stream()
- .filter(x -> x.wns.suggestorUid == connectedNetwork.creatorUid)
+ .filter(x -> x.perAppInfo.uid == connectedNetwork.creatorUid)
.collect(Collectors.toSet());
if (matchingExtNetworkSuggestions.isEmpty()) {
Log.wtf(TAG, "Current connected network suggestion is missing!");
@@ -1197,9 +1230,7 @@ public class WifiNetworkSuggestionsManager {
for (ExtendedWifiNetworkSuggestion matchingExtNetworkSuggestion
: matchingExtNetworkSuggestionsWithReqAppInteraction) {
sendPostConnectionBroadcastIfAllowed(
- matchingExtNetworkSuggestion.perAppInfo.packageName,
- matchingExtNetworkSuggestion.perAppInfo.featureId,
- matchingExtNetworkSuggestion.wns,
+ matchingExtNetworkSuggestion,
"Connected to " + matchingExtNetworkSuggestion.wns.wifiConfiguration.SSID
+ ". featureId is first feature of the app using network suggestions");
}
@@ -1233,7 +1264,7 @@ public class WifiNetworkSuggestionsManager {
// Find subset of network suggestions which suggested the connection failure network.
Set<ExtendedWifiNetworkSuggestion> matchingExtNetworkSuggestionsFromTargetApp =
matchingExtNetworkSuggestions.stream()
- .filter(x -> x.wns.suggestorUid == network.creatorUid)
+ .filter(x -> x.perAppInfo.uid == network.creatorUid)
.collect(Collectors.toSet());
if (matchingExtNetworkSuggestionsFromTargetApp.isEmpty()) {
Log.wtf(TAG, "Current connection failure network suggestion is missing!");
@@ -1244,6 +1275,7 @@ public class WifiNetworkSuggestionsManager {
: matchingExtNetworkSuggestionsFromTargetApp) {
sendConnectionFailureIfAllowed(matchingExtNetworkSuggestion.perAppInfo.packageName,
matchingExtNetworkSuggestion.perAppInfo.featureId,
+ matchingExtNetworkSuggestion.perAppInfo.uid,
matchingExtNetworkSuggestion.wns, failureCode);
}
}
@@ -1286,11 +1318,12 @@ public class WifiNetworkSuggestionsManager {
* Send network connection failure event to app when an connection attempt failure.
* @param packageName package name to send event
* @param featureId The feature in the package
+ * @param uid uid of the app.
* @param matchingSuggestion suggestion on this connection failure
* @param connectionEvent connection failure code
*/
private void sendConnectionFailureIfAllowed(String packageName, @Nullable String featureId,
- @NonNull WifiNetworkSuggestion matchingSuggestion, int connectionEvent) {
+ int uid, @NonNull WifiNetworkSuggestion matchingSuggestion, int connectionEvent) {
ExternalCallbackTracker<ISuggestionConnectionStatusListener> listenersTracker =
mSuggestionStatusListenerPerApp.get(packageName);
if (listenersTracker == null || listenersTracker.getNumCallbacks() == 0) {
@@ -1298,8 +1331,7 @@ public class WifiNetworkSuggestionsManager {
}
try {
mWifiPermissionsUtil.enforceCanAccessScanResults(
- packageName, featureId, matchingSuggestion.suggestorUid,
- "Connection failure");
+ packageName, featureId, uid, "Connection failure");
} catch (SecurityException se) {
Log.w(TAG, "Permission denied for sending connection failure event to " + packageName);
return;
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 9529ef0ef..dfa09e809 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -98,7 +98,6 @@ import android.util.MutableBoolean;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.PowerProfile;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
@@ -194,11 +193,6 @@ public class WifiServiceImpl extends BaseWifiService {
private final WifiPermissionsUtil mWifiPermissionsUtil;
- /**
- * Power profile
- */
- private final PowerProfile mPowerProfile;
-
private final TetheredSoftApTracker mTetheredSoftApTracker;
private final LohsSoftApTracker mLohsSoftApTracker;
@@ -300,7 +294,6 @@ public class WifiServiceImpl extends BaseWifiService {
mActiveModeWarden.registerSoftApCallback(mTetheredSoftApTracker);
mLohsSoftApTracker = new LohsSoftApTracker();
mActiveModeWarden.registerLohsCallback(mLohsSoftApTracker);
- mPowerProfile = mWifiInjector.getPowerProfile();
mWifiNetworkSuggestionsManager = mWifiInjector.getWifiNetworkSuggestionsManager();
mDppManager = mWifiInjector.getDppManager();
mWifiThreadRunner = mWifiInjector.getWifiThreadRunner();
@@ -1779,15 +1772,6 @@ public class WifiServiceImpl extends BaseWifiService {
return null;
}
- final double rxIdleCurrentInMilliAmps = mPowerProfile.getAveragePower(
- PowerProfile.POWER_WIFI_CONTROLLER_IDLE);
- final double rxCurrentInMilliAmps = mPowerProfile.getAveragePower(
- PowerProfile.POWER_WIFI_CONTROLLER_RX);
- final double txCurrentInMilliAmps = mPowerProfile.getAveragePower(
- PowerProfile.POWER_WIFI_CONTROLLER_TX);
- // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
- final double voltageInVolts = mPowerProfile.getAveragePower(
- PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
final long rxIdleTimeMillis = stats.on_time - stats.tx_time - stats.rx_time;
final long[] txTimePerLevelMillis;
if (stats.tx_time_per_level == null) {
@@ -1801,28 +1785,15 @@ public class WifiServiceImpl extends BaseWifiService {
// TODO(b/27227497): Need to read the power consumed per level from config
}
}
- // times are all in milliseconds, currents are all in milliAmps, voltage is in volts =>
- // resulting energy is in microjoules.
- final long energyUsedInMicroJoules = (long) (
- (stats.tx_time * txCurrentInMilliAmps
- + stats.rx_time * rxCurrentInMilliAmps
- + rxIdleTimeMillis * rxIdleCurrentInMilliAmps
- ) * voltageInVolts);
-
if (VDBG || rxIdleTimeMillis < 0 || stats.on_time < 0 || stats.tx_time < 0
- || stats.rx_time < 0 || stats.on_time_scan < 0 || energyUsedInMicroJoules < 0) {
+ || stats.rx_time < 0 || stats.on_time_scan < 0) {
Log.d(TAG, " reportActivityInfo: "
- + " rxIdleCurrentInMilliAmps=" + rxIdleCurrentInMilliAmps
- + " rxCurrentInMilliAmps=" + rxCurrentInMilliAmps
- + " txCurrentInMilliAmps=" + txCurrentInMilliAmps
- + " voltageInVolts=" + voltageInVolts
+ " on_time_millis=" + stats.on_time
+ " tx_time_millis=" + stats.tx_time
+ " tx_time_per_level_millis=" + Arrays.toString(txTimePerLevelMillis)
+ " rx_time_millis=" + stats.rx_time
+ " rxIdleTimeMillis=" + rxIdleTimeMillis
- + " scan_time_millis=" + stats.on_time_scan
- + " energyUsedInMicroJoules=" + energyUsedInMicroJoules);
+ + " scan_time_millis=" + stats.on_time_scan);
}
// Convert the LinkLayerStats into WifiActivityEnergyInfo
@@ -1832,8 +1803,7 @@ public class WifiServiceImpl extends BaseWifiService {
stats.tx_time,
stats.rx_time,
stats.on_time_scan,
- rxIdleTimeMillis,
- energyUsedInMicroJoules);
+ rxIdleTimeMillis);
return energyInfo.isValid() ? energyInfo : null;
}
diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java
index dce3a1fd2..97dded62f 100644
--- a/service/java/com/android/server/wifi/WifiVendorHal.java
+++ b/service/java/com/android/server/wifi/WifiVendorHal.java
@@ -61,10 +61,10 @@ import android.util.MutableBoolean;
import android.util.MutableLong;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.HexDump;
import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener;
import com.android.server.wifi.WifiLinkLayerStats.ChannelStats;
+import com.android.server.wifi.util.ArrayUtils;
import com.android.server.wifi.util.BitMask;
import com.android.server.wifi.util.NativeUtil;
diff --git a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
index f9ef69eb8..c305c8354 100644
--- a/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
+++ b/service/java/com/android/server/wifi/hotspot2/PasspointProvider.java
@@ -31,7 +31,6 @@ import android.util.Base64;
import android.util.Log;
import android.util.Pair;
-import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.IMSIParameter;
import com.android.server.wifi.WifiKeyStore;
import com.android.server.wifi.hotspot2.anqp.ANQPElement;
@@ -42,6 +41,7 @@ import com.android.server.wifi.hotspot2.anqp.RoamingConsortiumElement;
import com.android.server.wifi.hotspot2.anqp.ThreeGPPNetworkElement;
import com.android.server.wifi.hotspot2.anqp.eap.AuthParam;
import com.android.server.wifi.hotspot2.anqp.eap.NonEAPInnerAuth;
+import com.android.server.wifi.util.ArrayUtils;
import com.android.server.wifi.util.InformationElementUtil.RoamingConsortium;
import com.android.server.wifi.util.TelephonyUtil;
diff --git a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java
index 891595f8d..3e3962807 100644
--- a/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java
+++ b/service/java/com/android/server/wifi/p2p/SupplicantP2pIfaceHal.java
@@ -41,7 +41,7 @@ import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
-import com.android.internal.util.ArrayUtils;
+import com.android.server.wifi.util.ArrayUtils;
import com.android.server.wifi.util.NativeUtil;
import java.nio.ByteBuffer;
diff --git a/service/java/com/android/server/wifi/rtt/RttService.java b/service/java/com/android/server/wifi/rtt/RttService.java
index ae4cdfe8b..0d3e98943 100644
--- a/service/java/com/android/server/wifi/rtt/RttService.java
+++ b/service/java/com/android/server/wifi/rtt/RttService.java
@@ -17,9 +17,8 @@
package com.android.server.wifi.rtt;
import android.content.Context;
-import android.net.wifi.aware.IWifiAwareManager;
+import android.net.wifi.aware.WifiAwareManager;
import android.os.HandlerThread;
-import android.os.ServiceManager;
import android.util.Log;
import com.android.server.SystemService;
@@ -62,11 +61,10 @@ public class RttService extends SystemService {
WifiPermissionsUtil wifiPermissionsUtil = wifiInjector.getWifiPermissionsUtil();
RttMetrics rttMetrics = wifiInjector.getWifiMetrics().getRttMetrics();
- IWifiAwareManager awareBinder = (IWifiAwareManager) ServiceManager.getService(
- Context.WIFI_AWARE_SERVICE);
+ WifiAwareManager awareManager = getContext().getSystemService(WifiAwareManager.class);
RttNative rttNative = new RttNative(mImpl, halDeviceManager);
- mImpl.start(handlerThread.getLooper(), wifiInjector.getClock(), awareBinder, rttNative,
+ mImpl.start(handlerThread.getLooper(), wifiInjector.getClock(), awareManager, rttNative,
rttMetrics, wifiPermissionsUtil, wifiInjector.getFrameworkFacade());
}
}
diff --git a/service/java/com/android/server/wifi/rtt/RttServiceImpl.java b/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
index 6e48f59f4..6e35eb5ad 100644
--- a/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
+++ b/service/java/com/android/server/wifi/rtt/RttServiceImpl.java
@@ -28,7 +28,7 @@ import android.database.ContentObserver;
import android.location.LocationManager;
import android.net.MacAddress;
import android.net.wifi.aware.IWifiAwareMacAddressProvider;
-import android.net.wifi.aware.IWifiAwareManager;
+import android.net.wifi.aware.WifiAwareManager;
import android.net.wifi.rtt.IRttCallback;
import android.net.wifi.rtt.IWifiRttManager;
import android.net.wifi.rtt.RangingRequest;
@@ -84,7 +84,7 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
private final Context mContext;
private final RttShellCommand mShellCommand;
private Clock mClock;
- private IWifiAwareManager mAwareBinder;
+ private WifiAwareManager mAwareManager;
private RttNative mRttNative;
private RttMetrics mRttMetrics;
private WifiPermissionsUtil mWifiPermissionsUtil;
@@ -235,17 +235,17 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
*
* @param looper The looper on which to synchronize operations.
* @param clock A mockable clock.
- * @param awareBinder The Wi-Fi Aware service (binder) if supported on the system.
+ * @param awareManager The Wi-Fi Aware service (binder) if supported on the system.
* @param rttNative The Native interface to the HAL.
* @param rttMetrics The Wi-Fi RTT metrics object.
* @param wifiPermissionsUtil Utility for permission checks.
* @param frameworkFacade Facade for framework classes, allows mocking.
*/
- public void start(Looper looper, Clock clock, IWifiAwareManager awareBinder,
+ public void start(Looper looper, Clock clock, WifiAwareManager awareManager,
RttNative rttNative, RttMetrics rttMetrics, WifiPermissionsUtil wifiPermissionsUtil,
FrameworkFacade frameworkFacade) {
mClock = clock;
- mAwareBinder = awareBinder;
+ mAwareManager = awareManager;
mRttNative = rttNative;
mRttMetrics = rttMetrics;
mWifiPermissionsUtil = wifiPermissionsUtil;
@@ -429,7 +429,7 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
if (callback == null) {
throw new IllegalArgumentException("Callback must not be null");
}
- request.enforceValidity(mAwareBinder != null);
+ request.enforceValidity(mAwareManager != null);
if (!isAvailable()) {
try {
@@ -1012,33 +1012,17 @@ public class RttServiceImpl extends IWifiRttManager.Stub {
}
request.peerHandlesTranslated = true;
- try {
- mAwareBinder.requestMacAddresses(request.uid, peerIdsNeedingTranslation,
- new IWifiAwareMacAddressProvider.Stub() {
- @Override
- public void macAddress(Map peerIdToMacMap) {
- // ASYNC DOMAIN
- mHandler.post(() -> {
- // BACK TO SYNC DOMAIN
- processReceivedAwarePeerMacAddresses(request, peerIdToMacMap);
- });
- }
- });
- } catch (RemoteException e1) {
- Log.e(TAG,
- "processAwarePeerHandles: exception while calling requestMacAddresses -- "
- + e1 + ", aborting request=" + request);
- try {
- mRttMetrics.recordOverallStatus(
- WifiMetricsProto.WifiRttLog.OVERALL_AWARE_TRANSLATION_FAILURE);
- request.callback.onRangingFailure(RangingResultCallback.STATUS_CODE_FAIL);
- } catch (RemoteException e2) {
- Log.e(TAG, "processAwarePeerHandles: onRangingResults failure -- " + e2);
- }
- executeNextRangingRequestIfPossible(true);
- return true; // an abort because we removed request and are executing next one
- }
-
+ mAwareManager.requestMacAddresses(request.uid, peerIdsNeedingTranslation,
+ new IWifiAwareMacAddressProvider.Stub() {
+ @Override
+ public void macAddress(Map peerIdToMacMap) {
+ // ASYNC DOMAIN
+ mHandler.post(() -> {
+ // BACK TO SYNC DOMAIN
+ processReceivedAwarePeerMacAddresses(request, peerIdToMacMap);
+ });
+ }
+ });
return true; // a deferral
}
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 6dd2021d7..e5f2b332d 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -49,7 +49,6 @@ import android.util.Pair;
import android.util.StatsLog;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
@@ -63,6 +62,7 @@ import com.android.server.wifi.WifiMetrics;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.scanner.ChannelHelper.ChannelCollection;
+import com.android.server.wifi.util.ArrayUtils;
import com.android.server.wifi.util.ScanResultUtil;
import com.android.server.wifi.util.WifiHandler;
import com.android.server.wifi.util.WifiPermissionsUtil;
diff --git a/service/java/com/android/server/wifi/util/ArrayUtils.java b/service/java/com/android/server/wifi/util/ArrayUtils.java
new file mode 100644
index 000000000..330abc025
--- /dev/null
+++ b/service/java/com/android/server/wifi/util/ArrayUtils.java
@@ -0,0 +1,187 @@
+/*
+ * 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.util;
+
+import android.annotation.Nullable;
+
+import java.util.Collection;
+import java.util.Objects;
+
+/**
+ * Copied over from frameworks/base/core/java/com/android/internal/util/ArrayUtils.java
+ */
+public class ArrayUtils {
+ private ArrayUtils() { /* cannot be instantiated */ }
+
+ /**
+ * Checks if the beginnings of two byte arrays are equal.
+ *
+ * @param array1 the first byte array
+ * @param array2 the second byte array
+ * @param length the number of bytes to check
+ * @return true if they're equal, false otherwise
+ */
+ public static boolean equals(byte[] array1, byte[] array2, int length) {
+ if (length < 0) {
+ throw new IllegalArgumentException();
+ }
+
+ if (array1 == array2) {
+ return true;
+ }
+ if (array1 == null || array2 == null || array1.length < length || array2.length < length) {
+ return false;
+ }
+ for (int i = 0; i < length; i++) {
+ if (array1[i] != array2[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Checks if given array is null or has zero elements.
+ */
+ public static boolean isEmpty(@Nullable Collection<?> array) {
+ return array == null || array.isEmpty();
+ }
+
+ /**
+ * Checks if given array is null or has zero elements.
+ */
+ public static <T> boolean isEmpty(@Nullable T[] array) {
+ return array == null || array.length == 0;
+ }
+
+ /**
+ * Checks if given array is null or has zero elements.
+ */
+ public static boolean isEmpty(@Nullable int[] array) {
+ return array == null || array.length == 0;
+ }
+
+ /**
+ * Checks if given array is null or has zero elements.
+ */
+ public static boolean isEmpty(@Nullable long[] array) {
+ return array == null || array.length == 0;
+ }
+
+ /**
+ * Checks if given array is null or has zero elements.
+ */
+ public static boolean isEmpty(@Nullable byte[] array) {
+ return array == null || array.length == 0;
+ }
+
+ /**
+ * Checks if given array is null or has zero elements.
+ */
+ public static boolean isEmpty(@Nullable boolean[] array) {
+ return array == null || array.length == 0;
+ }
+
+ /**
+ * Length of the given array or 0 if it's null.
+ */
+ public static int size(@Nullable Object[] array) {
+ return array == null ? 0 : array.length;
+ }
+
+ /**
+ * Length of the given collection or 0 if it's null.
+ */
+ public static int size(@Nullable Collection<?> collection) {
+ return collection == null ? 0 : collection.size();
+ }
+
+ /**
+ * Checks that value is present as at least one of the elements of the array.
+ *
+ * @param array the array to check in
+ * @param value the value to check for
+ * @return true if the value is present in the array
+ */
+ public static <T> boolean contains(@Nullable T[] array, T value) {
+ return indexOf(array, value) != -1;
+ }
+
+ /**
+ * Checks that value is present as at least one of the elements of the array.
+ *
+ * @param array the array to check in
+ * @param value the value to check for
+ * @return true if the value is present in the array
+ */
+ public static boolean contains(@Nullable int[] array, int value) {
+ if (array == null) return false;
+ for (int element : array) {
+ if (element == value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks that value is present as at least one of the elements of the array.
+ *
+ * @param array the array to check in
+ * @param value the value to check for
+ * @return true if the value is present in the array
+ */
+ public static boolean contains(@Nullable long[] array, long value) {
+ if (array == null) return false;
+ for (long element : array) {
+ if (element == value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks that value is present as at least one of the elements of the array.
+ *
+ * @param array the array to check in
+ * @param value the value to check for
+ * @return true if the value is present in the array
+ */
+ public static boolean contains(@Nullable char[] array, char value) {
+ if (array == null) return false;
+ for (char element : array) {
+ if (element == value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return first index of {@code value} in {@code array}, or {@code -1} if
+ * not found.
+ */
+ public static <T> int indexOf(@Nullable T[] array, T value) {
+ if (array == null) return -1;
+ for (int i = 0; i < array.length; i++) {
+ if (Objects.equals(array[i], value)) return i;
+ }
+ return -1;
+ }
+}
+
diff --git a/service/java/com/android/server/wifi/util/KeyValueListParser.java b/service/java/com/android/server/wifi/util/KeyValueListParser.java
new file mode 100644
index 000000000..ffbad6475
--- /dev/null
+++ b/service/java/com/android/server/wifi/util/KeyValueListParser.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2015 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.util;
+
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.time.format.DateTimeParseException;
+
+/**
+ * Parses a list of key=value pairs, separated by some delimiter, and puts the results in
+ * an internal Map. Values can be then queried by key, or if not found, a default value
+ * can be used.
+ *
+ * Note: @hide class copied from android.util (with ProtoStream dependency stripped out)
+ */
+public class KeyValueListParser {
+ private final ArrayMap<String, String> mValues = new ArrayMap<>();
+ private final TextUtils.StringSplitter mSplitter;
+
+ /**
+ * Constructs a new KeyValueListParser. This can be reused for different strings
+ * by calling {@link #setString(String)}.
+ * @param delim The delimiter that separates key=value pairs.
+ */
+ public KeyValueListParser(char delim) {
+ mSplitter = new TextUtils.SimpleStringSplitter(delim);
+ }
+
+ /**
+ * Resets the parser with a new string to parse. The string is expected to be in the following
+ * format:
+ * <pre>key1=value,key2=value,key3=value</pre>
+ *
+ * where the delimiter is a comma.
+ *
+ * @param str the string to parse.
+ * @throws IllegalArgumentException if the string is malformed.
+ */
+ public void setString(String str) throws IllegalArgumentException {
+ mValues.clear();
+ if (str != null) {
+ mSplitter.setString(str);
+ for (String pair : mSplitter) {
+ int sep = pair.indexOf('=');
+ if (sep < 0) {
+ mValues.clear();
+ throw new IllegalArgumentException(
+ "'" + pair + "' in '" + str + "' is not a valid key-value pair");
+ }
+ mValues.put(pair.substring(0, sep).trim(), pair.substring(sep + 1).trim());
+ }
+ }
+ }
+
+ /**
+ * Get the value for key as an int.
+ * @param key The key to lookup.
+ * @param def The value to return if the key was not found, or the value was not a long.
+ * @return the int value associated with the key.
+ */
+ public int getInt(String key, int def) {
+ String value = mValues.get(key);
+ if (value != null) {
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ // fallthrough
+ }
+ }
+ return def;
+ }
+
+ /**
+ * Get the value for key as a long.
+ * @param key The key to lookup.
+ * @param def The value to return if the key was not found, or the value was not a long.
+ * @return the long value associated with the key.
+ */
+ public long getLong(String key, long def) {
+ String value = mValues.get(key);
+ if (value != null) {
+ try {
+ return Long.parseLong(value);
+ } catch (NumberFormatException e) {
+ // fallthrough
+ }
+ }
+ return def;
+ }
+
+ /**
+ * Get the value for key as a float.
+ * @param key The key to lookup.
+ * @param def The value to return if the key was not found, or the value was not a float.
+ * @return the float value associated with the key.
+ */
+ public float getFloat(String key, float def) {
+ String value = mValues.get(key);
+ if (value != null) {
+ try {
+ return Float.parseFloat(value);
+ } catch (NumberFormatException e) {
+ // fallthrough
+ }
+ }
+ return def;
+ }
+
+ /**
+ * Get the value for key as a string.
+ * @param key The key to lookup.
+ * @param def The value to return if the key was not found.
+ * @return the string value associated with the key.
+ */
+ public String getString(String key, String def) {
+ String value = mValues.get(key);
+ if (value != null) {
+ return value;
+ }
+ return def;
+ }
+
+ /**
+ * Get the value for key as a boolean.
+ * @param key The key to lookup.
+ * @param def The value to return if the key was not found.
+ * @return the string value associated with the key.
+ */
+ public boolean getBoolean(String key, boolean def) {
+ String value = mValues.get(key);
+ if (value != null) {
+ try {
+ return Boolean.parseBoolean(value);
+ } catch (NumberFormatException e) {
+ // fallthrough
+ }
+ }
+ return def;
+ }
+
+ /**
+ * Get the value for key as an integer array.
+ *
+ * The value should be encoded as "0:1:2:3:4"
+ *
+ * @param key The key to lookup.
+ * @param def The value to return if the key was not found.
+ * @return the int[] value associated with the key.
+ */
+ public int[] getIntArray(String key, int[] def) {
+ String value = mValues.get(key);
+ if (value != null) {
+ try {
+ String[] parts = value.split(":");
+ if (parts.length > 0) {
+ int[] ret = new int[parts.length];
+ for (int i = 0; i < parts.length; i++) {
+ ret[i] = Integer.parseInt(parts[i]);
+ }
+ return ret;
+ }
+ } catch (NumberFormatException e) {
+ // fallthrough
+ }
+ }
+ return def;
+ }
+
+ /**
+ * @return the number of keys.
+ */
+ public int size() {
+ return mValues.size();
+ }
+
+ /**
+ * @return the key at {@code index}. Use with {@link #size()} to enumerate all key-value pairs.
+ */
+ public String keyAt(int index) {
+ return mValues.keyAt(index);
+ }
+
+ /**
+ * {@hide}
+ * Parse a duration in millis based on java.time.Duration or just a number (millis)
+ */
+ public long getDurationMillis(String key, long def) {
+ String value = mValues.get(key);
+ if (value != null) {
+ try {
+ if (value.startsWith("P") || value.startsWith("p")) {
+ return Duration.parse(value).toMillis();
+ } else {
+ return Long.parseLong(value);
+ }
+ } catch (NumberFormatException | DateTimeParseException e) {
+ // fallthrough
+ }
+ }
+ return def;
+ }
+
+ /** Represents an integer config value. */
+ public static class IntValue {
+ private final String mKey;
+ private final int mDefaultValue;
+ private int mValue;
+
+ /** Constructor, initialize with a config key and a default value. */
+ public IntValue(String key, int defaultValue) {
+ mKey = key;
+ mDefaultValue = defaultValue;
+ mValue = mDefaultValue;
+ }
+
+ /** Read a value from {@link KeyValueListParser} */
+ public void parse(KeyValueListParser parser) {
+ mValue = parser.getInt(mKey, mDefaultValue);
+ }
+
+ /** Return the config key. */
+ public String getKey() {
+ return mKey;
+ }
+
+ /** Return the default value. */
+ public int getDefaultValue() {
+ return mDefaultValue;
+ }
+
+ /** Return the actual config value. */
+ public int getValue() {
+ return mValue;
+ }
+
+ /** Overwrites with a value. */
+ public void setValue(int value) {
+ mValue = value;
+ }
+
+ /** Used for dumpsys */
+ public void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix);
+ pw.print(mKey);
+ pw.print("=");
+ pw.print(mValue);
+ pw.println();
+ }
+ }
+
+ /** Represents an long config value. */
+ public static class LongValue {
+ private final String mKey;
+ private final long mDefaultValue;
+ private long mValue;
+
+ /** Constructor, initialize with a config key and a default value. */
+ public LongValue(String key, long defaultValue) {
+ mKey = key;
+ mDefaultValue = defaultValue;
+ mValue = mDefaultValue;
+ }
+
+ /** Read a value from {@link KeyValueListParser} */
+ public void parse(KeyValueListParser parser) {
+ mValue = parser.getLong(mKey, mDefaultValue);
+ }
+
+ /** Return the config key. */
+ public String getKey() {
+ return mKey;
+ }
+
+ /** Return the default value. */
+ public long getDefaultValue() {
+ return mDefaultValue;
+ }
+
+ /** Return the actual config value. */
+ public long getValue() {
+ return mValue;
+ }
+
+ /** Overwrites with a value. */
+ public void setValue(long value) {
+ mValue = value;
+ }
+
+ /** Used for dumpsys */
+ public void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix);
+ pw.print(mKey);
+ pw.print("=");
+ pw.print(mValue);
+ pw.println();
+ }
+ }
+
+ /** Represents an string config value. */
+ public static class StringValue {
+ private final String mKey;
+ private final String mDefaultValue;
+ private String mValue;
+
+ /** Constructor, initialize with a config key and a default value. */
+ public StringValue(String key, String defaultValue) {
+ mKey = key;
+ mDefaultValue = defaultValue;
+ mValue = mDefaultValue;
+ }
+
+ /** Read a value from {@link KeyValueListParser} */
+ public void parse(KeyValueListParser parser) {
+ mValue = parser.getString(mKey, mDefaultValue);
+ }
+
+ /** Return the config key. */
+ public String getKey() {
+ return mKey;
+ }
+
+ /** Return the default value. */
+ public String getDefaultValue() {
+ return mDefaultValue;
+ }
+
+ /** Return the actual config value. */
+ public String getValue() {
+ return mValue;
+ }
+
+ /** Overwrites with a value. */
+ public void setValue(String value) {
+ mValue = value;
+ }
+
+ /** Used for dumpsys */
+ public void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix);
+ pw.print(mKey);
+ pw.print("=");
+ pw.print(mValue);
+ pw.println();
+ }
+ }
+
+ /** Represents an float config value. */
+ public static class FloatValue {
+ private final String mKey;
+ private final float mDefaultValue;
+ private float mValue;
+
+ /** Constructor, initialize with a config key and a default value. */
+ public FloatValue(String key, float defaultValue) {
+ mKey = key;
+ mDefaultValue = defaultValue;
+ mValue = mDefaultValue;
+ }
+
+ /** Read a value from {@link KeyValueListParser} */
+ public void parse(KeyValueListParser parser) {
+ mValue = parser.getFloat(mKey, mDefaultValue);
+ }
+
+ /** Return the config key. */
+ public String getKey() {
+ return mKey;
+ }
+
+ /** Return the default value. */
+ public float getDefaultValue() {
+ return mDefaultValue;
+ }
+
+ /** Return the actual config value. */
+ public float getValue() {
+ return mValue;
+ }
+
+ /** Overwrites with a value. */
+ public void setValue(float value) {
+ mValue = value;
+ }
+
+ /** Used for dumpsys */
+ public void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix);
+ pw.print(mKey);
+ pw.print("=");
+ pw.print(mValue);
+ pw.println();
+ }
+ }
+}
diff --git a/service/java/com/android/server/wifi/util/ScanResultUtil.java b/service/java/com/android/server/wifi/util/ScanResultUtil.java
index b92483899..ec5a3a1ec 100644
--- a/service/java/com/android/server/wifi/util/ScanResultUtil.java
+++ b/service/java/com/android/server/wifi/util/ScanResultUtil.java
@@ -20,7 +20,6 @@ import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.ScanDetail;
import com.android.server.wifi.hotspot2.NetworkDetail;