summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--framework/java/android/net/wifi/IWifiScannerListener.aidl10
-rw-r--r--framework/java/android/net/wifi/WifiScanner.java15
l---------service/ServiceWifiResources/res/values-mcc310-mnc9501
-rw-r--r--service/ServiceWifiResources/res/values-mcc310-mnc950/config.xml28
l---------service/ServiceWifiResources/res/values-mcc311-mnc1802
-rw-r--r--service/ServiceWifiResources/res/values-mcc312-mnc670/config.xml27
l---------service/ServiceWifiResources/res/values-mcc313-mnc1401
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java2
-rw-r--r--service/java/com/android/server/wifi/LastMileLogger.java29
-rw-r--r--service/java/com/android/server/wifi/SarManager.java22
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java3
-rw-r--r--service/java/com/android/server/wifi/WifiLockManager.java4
-rw-r--r--service/java/com/android/server/wifi/WifiMetrics.java28
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java8
-rw-r--r--service/java/com/android/server/wifi/aware/WifiAwareStateManager.java2
-rw-r--r--service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicant.java356
-rw-r--r--service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicantStaIfaceCallback.java210
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScannerInternal.java7
-rw-r--r--service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java27
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java43
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java41
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java15
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java18
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java1
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java4
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java3
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/mainline_supplicant/MainlineSupplicantTest.java38
-rw-r--r--service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java19
28 files changed, 857 insertions, 107 deletions
diff --git a/framework/java/android/net/wifi/IWifiScannerListener.aidl b/framework/java/android/net/wifi/IWifiScannerListener.aidl
index bd19ac2d0f..74b22a1bbf 100644
--- a/framework/java/android/net/wifi/IWifiScannerListener.aidl
+++ b/framework/java/android/net/wifi/IWifiScannerListener.aidl
@@ -15,14 +15,14 @@
package android.net.wifi;
-import android.net.wifi.WifiScanner;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiScanner;
+import com.android.modules.utils.ParceledListSlice;
/**
* @hide
*/
-oneway interface IWifiScannerListener
-{
+oneway interface IWifiScannerListener {
void onSuccess();
void onFailure(int reason, String description);
@@ -46,5 +46,5 @@ oneway interface IWifiScannerListener
/**
* reports full scan result for all access points found in scan
*/
- void onFullResults(in List<ScanResult> scanResult);
-} \ No newline at end of file
+ void onFullResults(in ParceledListSlice<ScanResult> scanResult);
+}
diff --git a/framework/java/android/net/wifi/WifiScanner.java b/framework/java/android/net/wifi/WifiScanner.java
index fd9676e0e4..b5cc3b0976 100644
--- a/framework/java/android/net/wifi/WifiScanner.java
+++ b/framework/java/android/net/wifi/WifiScanner.java
@@ -45,6 +45,7 @@ import android.util.Log;
import androidx.annotation.RequiresApi;
import com.android.internal.util.Protocol;
+import com.android.modules.utils.ParceledListSlice;
import com.android.modules.utils.build.SdkLevel;
import com.android.wifi.flags.Flags;
@@ -387,14 +388,14 @@ public class WifiScanner {
* reports full scan result for all access points found in scan
*/
@Override
- public void onFullResults(List<ScanResult> fullScanResult) {
+ public void onFullResults(ParceledListSlice<ScanResult> fullScanResult) {
Log.i(TAG, "onFullResults");
if (mActionListener == null) return;
if (!(mActionListener instanceof ScanListener)) return;
ScanListener scanListener = (ScanListener) mActionListener;
Binder.clearCallingIdentity();
mExecutor.execute(
- () -> fullScanResult.forEach(scanListener::onFullResult));
+ () -> fullScanResult.getList().forEach(scanListener::onFullResult));
}
@Override
@@ -1021,7 +1022,8 @@ public class WifiScanner {
dest.writeInt(mFlags);
dest.writeInt(mBucketsScanned);
dest.writeInt(mScannedBands);
- dest.writeParcelableList(mResults, 0);
+ ParceledListSlice<ScanResult> parceledListSlice = new ParceledListSlice<>(mResults);
+ parceledListSlice.writeToParcel(dest, flags);
}
/** Implement the Parcelable interface {@hide} */
@@ -1032,9 +1034,10 @@ public class WifiScanner {
int flags = in.readInt();
int bucketsScanned = in.readInt();
int bandsScanned = in.readInt();
- List<ScanResult> results = new ArrayList<>();
- in.readParcelableList(results, ScanResult.class.getClassLoader());
- return new ScanData(id, flags, bucketsScanned, bandsScanned, results);
+ ParceledListSlice<ScanResult> parceledListSlice =
+ ParceledListSlice.CREATOR.createFromParcel(in);
+ return new ScanData(id, flags, bucketsScanned, bandsScanned,
+ parceledListSlice.getList());
}
public ScanData[] newArray(int size) {
diff --git a/service/ServiceWifiResources/res/values-mcc310-mnc950 b/service/ServiceWifiResources/res/values-mcc310-mnc950
deleted file mode 120000
index 179ce02a94..0000000000
--- a/service/ServiceWifiResources/res/values-mcc310-mnc950
+++ /dev/null
@@ -1 +0,0 @@
-values-mcc310-mnc030 \ No newline at end of file
diff --git a/service/ServiceWifiResources/res/values-mcc310-mnc950/config.xml b/service/ServiceWifiResources/res/values-mcc310-mnc950/config.xml
new file mode 100644
index 0000000000..c6fdb89325
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-mcc310-mnc950/config.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <integer name="config_wifiFrameworkSecureNetworkBonus">540</integer>
+
+ <string-array translatable="false" name="config_wifiOobPseudonymEnabled_carrier_overrides">
+ <item><xliff:g id="carrier_id_prefix">:::1187:::</xliff:g>true</item>
+ </string-array>
+
+ <!-- Carrier specific override for the URL of entitlement server retrieving OOB pseudonym. -->
+ <string-array translatable="false" name="config_wifiOobPseudonymEntitlementServerUrl_carrier_overrides">
+ <item><xliff:g id="carrier_id_prefix">:::1187:::</xliff:g>https://sentitlement2.npc.mobilephone.net/WFC</item>
+ </string-array>
+</resources>
diff --git a/service/ServiceWifiResources/res/values-mcc311-mnc180 b/service/ServiceWifiResources/res/values-mcc311-mnc180
index 179ce02a94..c885455563 120000
--- a/service/ServiceWifiResources/res/values-mcc311-mnc180
+++ b/service/ServiceWifiResources/res/values-mcc311-mnc180
@@ -1 +1 @@
-values-mcc310-mnc030 \ No newline at end of file
+values-mcc310-mnc950 \ No newline at end of file
diff --git a/service/ServiceWifiResources/res/values-mcc312-mnc670/config.xml b/service/ServiceWifiResources/res/values-mcc312-mnc670/config.xml
new file mode 100644
index 0000000000..a605db28c3
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-mcc312-mnc670/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2025 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.
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array translatable="false" name="config_wifiOobPseudonymEnabled_carrier_overrides">
+ <item><xliff:g id="carrier_id_prefix">:::2119:::</xliff:g>true</item>
+ </string-array>
+
+ <!-- Carrier specific override for the URL of entitlement server retrieving OOB pseudonym. -->
+ <string-array translatable="false" name="config_wifiOobPseudonymEntitlementServerUrl_carrier_overrides">
+ <item><xliff:g id="carrier_id_prefix">:::2119:::</xliff:g>https://sentitlement2.npc.mobilephone.net/WFC</item>
+ </string-array>
+</resources>
diff --git a/service/ServiceWifiResources/res/values-mcc313-mnc140 b/service/ServiceWifiResources/res/values-mcc313-mnc140
new file mode 120000
index 0000000000..2d21ee5bae
--- /dev/null
+++ b/service/ServiceWifiResources/res/values-mcc313-mnc140
@@ -0,0 +1 @@
+values-mcc313-mnc100 \ No newline at end of file
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index 99a6880b30..9bcf627f9a 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -219,7 +219,7 @@ public class ClientModeImpl extends StateMachine implements ClientMode {
private static final int IPCLIENT_SHUTDOWN_TIMEOUT_MS = 60_000; // 60 seconds
private static final int NETWORK_AGENT_TEARDOWN_DELAY_MS = 5_000; // Max teardown delay.
private static final int DISASSOC_AP_BUSY_DISABLE_DURATION_MS = 5 * 60 * 1000; // 5 minutes
- @VisibleForTesting public static final long CONNECTING_WATCHDOG_TIMEOUT_MS = 30_000; // 30 secs.
+ @VisibleForTesting public static final long CONNECTING_WATCHDOG_TIMEOUT_MS = 8_000; // 8 secs.
public static final int PROVISIONING_TIMEOUT_FILS_CONNECTION_MS = 36_000; // 36 secs.
@VisibleForTesting
public static final String ARP_TABLE_PATH = "/proc/net/arp";
diff --git a/service/java/com/android/server/wifi/LastMileLogger.java b/service/java/com/android/server/wifi/LastMileLogger.java
index 0c9c0addcf..49c506ed62 100644
--- a/service/java/com/android/server/wifi/LastMileLogger.java
+++ b/service/java/com/android/server/wifi/LastMileLogger.java
@@ -17,6 +17,7 @@
package com.android.server.wifi;
+import android.os.Handler;
import android.util.ArrayMap;
import com.android.internal.annotations.VisibleForTesting;
@@ -34,7 +35,9 @@ import java.util.Map;
* Provides a facility for capturing kernel trace events related to Wifi control and data paths.
*/
public class LastMileLogger {
- public LastMileLogger(WifiInjector injector) {
+ private final Handler mBackgroundHandler;
+ public LastMileLogger(WifiInjector injector, Handler handler) {
+ mBackgroundHandler = handler;
File tracefsEnablePath = new File(WIFI_EVENT_ENABLE_PATH);
if (tracefsEnablePath.exists()) {
initLastMileLogger(injector, WIFI_EVENT_BUFFER_PATH, WIFI_EVENT_ENABLE_PATH,
@@ -47,7 +50,8 @@ public class LastMileLogger {
@VisibleForTesting
public LastMileLogger(WifiInjector injector, String bufferPath, String enablePath,
- String releasePath) {
+ String releasePath, Handler handler) {
+ mBackgroundHandler = handler;
initLastMileLogger(injector, bufferPath, enablePath, releasePath);
}
@@ -62,16 +66,17 @@ public class LastMileLogger {
boolean shouldTracingBeEnabled = anyConnectionInProgress();
- if (!wasTracingEnabled && shouldTracingBeEnabled) {
- enableTracing();
- } else if (wasTracingEnabled && !shouldTracingBeEnabled) {
- disableTracing();
- }
-
- if (event == WifiDiagnostics.CONNECTION_EVENT_FAILED
- || event == WifiDiagnostics.CONNECTION_EVENT_TIMEOUT) {
- mLastMileLogForLastFailure = readTrace();
- }
+ mBackgroundHandler.post(() -> {
+ if (!wasTracingEnabled && shouldTracingBeEnabled) {
+ enableTracing();
+ } else if (wasTracingEnabled && !shouldTracingBeEnabled) {
+ disableTracing();
+ }
+ if (event == WifiDiagnostics.CONNECTION_EVENT_FAILED
+ || event == WifiDiagnostics.CONNECTION_EVENT_TIMEOUT) {
+ mLastMileLogForLastFailure = readTrace();
+ }
+ });
}
private boolean anyConnectionInProgress() {
diff --git a/service/java/com/android/server/wifi/SarManager.java b/service/java/com/android/server/wifi/SarManager.java
index a454dfe96c..9d6a992f57 100644
--- a/service/java/com/android/server/wifi/SarManager.java
+++ b/service/java/com/android/server/wifi/SarManager.java
@@ -72,7 +72,7 @@ public class SarManager {
private static final String TAG = "WifiSarManager";
private boolean mVerboseLoggingEnabled = true;
- private SarInfo mSarInfo;
+ private final SarInfo mSarInfo;
/* Configuration for SAR support */
private boolean mSupportSarTxPowerLimit;
@@ -106,6 +106,7 @@ public class SarManager {
mAudioManager = mContext.getSystemService(AudioManager.class);
mHandler = new Handler(looper);
mPhoneStateListener = new WifiPhoneStateListener(looper);
+ mSarInfo = new SarInfo();
wifiDeviceStateChangeManager.registerStateChangeCallback(
new WifiDeviceStateChangeManager.StateChangeCallback() {
@Override
@@ -121,9 +122,9 @@ public class SarManager {
public void handleBootCompleted() {
readSarConfigs();
if (mSupportSarTxPowerLimit) {
- mSarInfo = new SarInfo();
setSarConfigsInInfo();
registerListeners();
+ updateSarScenario();
}
}
@@ -302,11 +303,6 @@ public class SarManager {
*/
public void setClientWifiState(int state) {
boolean newIsEnabled;
- /* No action is taken if SAR is not supported */
- if (!mSupportSarTxPowerLimit) {
- return;
- }
-
if (state == WifiManager.WIFI_STATE_DISABLED) {
newIsEnabled = false;
} else if (state == WifiManager.WIFI_STATE_ENABLED) {
@@ -328,10 +324,6 @@ public class SarManager {
*/
public void setSapWifiState(int state) {
boolean newIsEnabled;
- /* No action is taken if SAR is not supported */
- if (!mSupportSarTxPowerLimit) {
- return;
- }
if (state == WifiManager.WIFI_AP_STATE_DISABLED) {
newIsEnabled = false;
@@ -354,10 +346,6 @@ public class SarManager {
*/
public void setScanOnlyWifiState(int state) {
boolean newIsEnabled;
- /* No action is taken if SAR is not supported */
- if (!mSupportSarTxPowerLimit) {
- return;
- }
if (state == WifiManager.WIFI_STATE_DISABLED) {
newIsEnabled = false;
@@ -459,6 +447,10 @@ public class SarManager {
* Update HAL with the new SAR scenario if needed.
*/
private void updateSarScenario() {
+ /* No action is taken if SAR is not supported */
+ if (!mSupportSarTxPowerLimit) {
+ return;
+ }
if (!mSarInfo.shouldReport()) {
return;
}
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 300f850d51..dcf4388095 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -418,7 +418,8 @@ public class WifiInjector {
: maxLinesHighRam);
mWifiDiagnostics = new WifiDiagnostics(
mContext, this, mWifiNative, mBuildProperties,
- new LastMileLogger(this), mClock, mWifiDiagnosticsHandlerThread.getLooper());
+ new LastMileLogger(this, BackgroundThread.getHandler()), mClock,
+ mWifiDiagnosticsHandlerThread.getLooper());
mWifiLastResortWatchdog = new WifiLastResortWatchdog(this, mContext, mClock,
mWifiMetrics, mWifiDiagnostics, wifiLooper,
mDeviceConfigFacade, mWifiThreadRunner, mWifiMonitor);
diff --git a/service/java/com/android/server/wifi/WifiLockManager.java b/service/java/com/android/server/wifi/WifiLockManager.java
index d6f6742998..33833f4b9a 100644
--- a/service/java/com/android/server/wifi/WifiLockManager.java
+++ b/service/java/com/android/server/wifi/WifiLockManager.java
@@ -678,7 +678,7 @@ public class WifiLockManager {
switch(wifiLock.mMode) {
case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
uidsAndTags.first,
uidsAndTags.second,
mWifiPermissionsUtil.getWifiCallerType(wifiLock.getUid(),
@@ -696,7 +696,7 @@ public class WifiLockManager {
}
break;
case WifiManager.WIFI_MODE_FULL_LOW_LATENCY:
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
uidsAndTags.first,
uidsAndTags.second,
mWifiPermissionsUtil.getWifiCallerType(wifiLock.getUid(),
diff --git a/service/java/com/android/server/wifi/WifiMetrics.java b/service/java/com/android/server/wifi/WifiMetrics.java
index 58b13fc2ea..68ac00f1ef 100644
--- a/service/java/com/android/server/wifi/WifiMetrics.java
+++ b/service/java/com/android/server/wifi/WifiMetrics.java
@@ -8914,8 +8914,11 @@ public class WifiMetrics {
}
}
- /** Add a WifiLock acquisition session */
- public void addWifiLockAcqSession(int lockType, int[] attrUids, String[] attrTags,
+ /**
+ * Add a WifiLockManager acquisition session. This represents the session during which
+ * a single lock was held.
+ */
+ public void addWifiLockManagerAcqSession(int lockType, int[] attrUids, String[] attrTags,
int callerType, long duration, boolean isPowersaveDisableAllowed,
boolean isAppExemptedFromScreenOn, boolean isAppExemptedFromForeground) {
int lockMode;
@@ -8933,6 +8936,27 @@ public class WifiMetrics {
Log.e(TAG, "addWifiLockAcqSession: Invalid lock type: " + lockType);
return;
}
+ writeWifiLockAcqSession(lockMode, attrUids, attrTags, callerType, duration,
+ isPowersaveDisableAllowed, isAppExemptedFromScreenOn, isAppExemptedFromForeground);
+ }
+
+ /**
+ * Add a MulticastLockManager acquisition session. This represents the session during which
+ * a single lock was held.
+ */
+ public void addMulticastLockManagerAcqSession(
+ int uid, String attributionTag, int callerType, long duration) {
+ // Use a default value for the boolean parameters, since these fields
+ // don't apply to multicast locks.
+ writeWifiLockAcqSession(
+ WifiStatsLog.WIFI_LOCK_RELEASED__MODE__WIFI_MODE_MULTICAST_FILTERING_DISABLED,
+ new int[]{uid}, new String[]{attributionTag}, callerType, duration,
+ false, false, false);
+ }
+
+ private void writeWifiLockAcqSession(int lockMode, int[] attrUids, String[] attrTags,
+ int callerType, long duration, boolean isPowersaveDisableAllowed,
+ boolean isAppExemptedFromScreenOn, boolean isAppExemptedFromForeground) {
WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_RELEASED,
attrUids,
attrTags,
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index f29eb75cf6..ec4a5ca353 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -1347,6 +1347,14 @@ public class WifiNetworkFactory extends NetworkFactory {
// If there is no active request or if the user has already selected a network,
// ignore screen state changes.
if (mActiveSpecificNetworkRequest == null || !mIsPeriodicScanEnabled) return;
+ if (mSkipUserDialogue) {
+ // Allow App which bypass the user approval to fulfill the request during screen off.
+ return;
+ }
+ if (screenOn != mIsPeriodicScanPaused) {
+ // already at the expected state
+ return;
+ }
// Pause periodic scans when the screen is off & resume when the screen is on.
if (screenOn) {
diff --git a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
index 19047477dc..3f4460ed8b 100644
--- a/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
+++ b/service/java/com/android/server/wifi/aware/WifiAwareStateManager.java
@@ -2661,8 +2661,8 @@ public class WifiAwareStateManager implements WifiAwareShellCommand.DelegatedShe
onAwareDownLocal();
if (reason != NanStatusCode.SUCCESS) {
sendAwareStateChangedBroadcast(false);
+ releaseAwareInterface();
}
- releaseAwareInterface();
break;
}
case NOTIFICATION_TYPE_ON_MESSAGE_SEND_SUCCESS: {
diff --git a/service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicant.java b/service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicant.java
index 6310577077..1ac2ad8f64 100644
--- a/service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicant.java
+++ b/service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicant.java
@@ -18,6 +18,10 @@ package com.android.server.wifi.mainline_supplicant;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.net.wifi.usd.Config;
+import android.net.wifi.usd.PublishConfig;
+import android.net.wifi.usd.SubscribeConfig;
import android.net.wifi.util.Environment;
import android.os.IBinder;
import android.os.RemoteException;
@@ -25,13 +29,18 @@ import android.os.ServiceSpecificException;
import android.system.wifi.mainline_supplicant.IMainlineSupplicant;
import android.system.wifi.mainline_supplicant.IStaInterface;
import android.system.wifi.mainline_supplicant.IStaInterfaceCallback;
+import android.system.wifi.mainline_supplicant.UsdMessageInfo;
+import android.system.wifi.mainline_supplicant.UsdServiceProtoType;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wifi.SupplicantStaIfaceHal;
import com.android.server.wifi.WifiNative;
import com.android.server.wifi.WifiThreadRunner;
+import com.android.server.wifi.usd.UsdNativeManager;
import com.android.wifi.flags.Flags;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
@@ -47,6 +56,7 @@ public class MainlineSupplicant {
private static final String TAG = "MainlineSupplicant";
private static final String MAINLINE_SUPPLICANT_SERVICE_NAME = "wifi_mainline_supplicant";
private static final long WAIT_FOR_DEATH_TIMEOUT_MS = 50L;
+ protected static final int DEFAULT_USD_FREQ_MHZ = 2437;
private IMainlineSupplicant mIMainlineSupplicant;
private final Object mLock = new Object();
@@ -57,6 +67,7 @@ public class MainlineSupplicant {
private final boolean mIsServiceAvailable;
private Map<String, IStaInterface> mActiveStaIfaces = new HashMap<>();
private Map<String, IStaInterfaceCallback> mStaIfaceCallbacks = new HashMap<>();
+ private UsdNativeManager.UsdEventsCallback mUsdEventsCallback = null;
public MainlineSupplicant(@NonNull WifiThreadRunner wifiThreadRunner) {
mWifiThreadRunner = wifiThreadRunner;
@@ -281,6 +292,22 @@ public class MainlineSupplicant {
}
/**
+ * Register a framework callback to receive USD events.
+ */
+ public void registerUsdEventsCallback(
+ @NonNull UsdNativeManager.UsdEventsCallback usdEventsCallback) {
+ mUsdEventsCallback = usdEventsCallback;
+ }
+
+ /**
+ * Get the registered USD events callback. Method should only be used
+ * by {@link MainlineSupplicantStaIfaceCallback}.
+ */
+ protected @Nullable UsdNativeManager.UsdEventsCallback getUsdEventsCallback() {
+ return mUsdEventsCallback;
+ }
+
+ /**
* Stop the mainline supplicant process.
*/
public void stopService() {
@@ -342,6 +369,324 @@ public class MainlineSupplicant {
}
}
+ private static byte frameworkToHalUsdTransmissionType(
+ @Config.TransmissionType int transmissionType) {
+ switch (transmissionType) {
+ case Config.TRANSMISSION_TYPE_MULTICAST:
+ return IStaInterface.UsdPublishTransmissionType.MULTICAST;
+ case Config.TRANSMISSION_TYPE_UNICAST:
+ default:
+ return IStaInterface.UsdPublishTransmissionType.UNICAST;
+ }
+ }
+
+ private static byte frameworkToHalUsdProtoType(
+ @Config.ServiceProtoType int protoType) {
+ switch (protoType) {
+ case Config.SERVICE_PROTO_TYPE_GENERIC:
+ return UsdServiceProtoType.GENERIC;
+ case Config.SERVICE_PROTO_TYPE_CSA_MATTER:
+ return UsdServiceProtoType.CSA_MATTER;
+ default:
+ return UsdServiceProtoType.UNKNOWN;
+ }
+ }
+
+ @VisibleForTesting
+ protected static IStaInterface.UsdPublishConfig frameworkToHalUsdPublishConfig(
+ PublishConfig frameworkConfig) {
+ IStaInterface.UsdPublishConfig aidlConfig = new IStaInterface.UsdPublishConfig();
+ // USD publisher is always solicited and unsolicited
+ aidlConfig.publishType = IStaInterface.UsdPublishType.SOLICITED_AND_UNSOLICITED;
+ // FSD is always enabled for USD
+ aidlConfig.isFsd = true;
+ aidlConfig.transmissionType = frameworkToHalUsdTransmissionType(
+ frameworkConfig.getSolicitedTransmissionType());
+ aidlConfig.announcementPeriodMillis = frameworkConfig.getAnnouncementPeriodMillis();
+ aidlConfig.baseConfig = new IStaInterface.UsdBaseConfig();
+ aidlConfig.baseConfig.ttlSec = frameworkConfig.getTtlSeconds();
+ int[] freqs = frameworkConfig.getOperatingFrequenciesMhz();
+ aidlConfig.baseConfig.defaultFreqMhz = (freqs == null || freqs.length == 0)
+ ? DEFAULT_USD_FREQ_MHZ : freqs[0];
+ aidlConfig.baseConfig.freqsMhz = (freqs == null || freqs.length <= 1)
+ ? new int[0] : Arrays.copyOfRange(freqs, 1, freqs.length);
+ aidlConfig.baseConfig.serviceName = Arrays.toString(frameworkConfig.getServiceName());
+ aidlConfig.baseConfig.serviceSpecificInfo =
+ frameworkConfig.getServiceSpecificInfo() != null
+ ? frameworkConfig.getServiceSpecificInfo() : new byte[0];
+ aidlConfig.baseConfig.rxMatchFilter = frameworkConfig.getRxMatchFilterTlv() != null
+ ? frameworkConfig.getRxMatchFilterTlv() : new byte[0];
+ aidlConfig.baseConfig.txMatchFilter = frameworkConfig.getTxMatchFilterTlv() != null
+ ? frameworkConfig.getTxMatchFilterTlv() : new byte[0];
+ aidlConfig.baseConfig.serviceProtoType = frameworkToHalUsdProtoType(
+ frameworkConfig.getServiceProtoType());
+ return aidlConfig;
+ }
+
+ /**
+ * Start a USD publish operation.
+ *
+ * @param ifaceName Name of the interface
+ * @param cmdId An id for this command
+ * @param publishConfig Publish configuration
+ * @return true if successful, false otherwise
+ */
+ public boolean startUsdPublish(@NonNull String ifaceName, int cmdId,
+ @NonNull PublishConfig publishConfig) {
+ synchronized (mLock) {
+ final String methodName = "startUsdPublish";
+ if (ifaceName == null || publishConfig == null) {
+ return false;
+ }
+ IStaInterface iface = getStaIfaceOrLogError(ifaceName, methodName);
+ if (iface == null) {
+ return false;
+ }
+ try {
+ iface.startUsdPublish(cmdId, frameworkToHalUsdPublishConfig(publishConfig));
+ return true;
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodName);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodName);
+ }
+ return false;
+ }
+ }
+
+ private static byte frameworkToHalUsdSubscribeType(
+ @Config.SubscribeType int subscribeType) {
+ switch (subscribeType) {
+ case Config.SUBSCRIBE_TYPE_ACTIVE:
+ return IStaInterface.UsdSubscribeType.ACTIVE_MODE;
+ case Config.SUBSCRIBE_TYPE_PASSIVE:
+ default:
+ return IStaInterface.UsdSubscribeType.PASSIVE_MODE;
+ }
+ }
+
+ @VisibleForTesting
+ protected static IStaInterface.UsdSubscribeConfig frameworkToHalUsdSubscribeConfig(
+ SubscribeConfig frameworkConfig) {
+ IStaInterface.UsdSubscribeConfig aidlConfig = new IStaInterface.UsdSubscribeConfig();
+ aidlConfig.subscribeType =
+ frameworkToHalUsdSubscribeType(frameworkConfig.getSubscribeType());
+ aidlConfig.queryPeriodMillis = frameworkConfig.getQueryPeriodMillis();
+ aidlConfig.baseConfig = new IStaInterface.UsdBaseConfig();
+ aidlConfig.baseConfig.ttlSec = frameworkConfig.getTtlSeconds();
+ int[] freqs = frameworkConfig.getOperatingFrequenciesMhz();
+ aidlConfig.baseConfig.defaultFreqMhz = (freqs == null || freqs.length == 0)
+ ? DEFAULT_USD_FREQ_MHZ : freqs[0];
+ aidlConfig.baseConfig.freqsMhz = (freqs == null || freqs.length <= 1)
+ ? new int[0] : Arrays.copyOfRange(freqs, 1, freqs.length);
+ aidlConfig.baseConfig.serviceName = Arrays.toString(frameworkConfig.getServiceName());
+ aidlConfig.baseConfig.serviceSpecificInfo =
+ frameworkConfig.getServiceSpecificInfo() != null
+ ? frameworkConfig.getServiceSpecificInfo() : new byte[0];
+ aidlConfig.baseConfig.rxMatchFilter = frameworkConfig.getRxMatchFilterTlv() != null
+ ? frameworkConfig.getRxMatchFilterTlv() : new byte[0];
+ aidlConfig.baseConfig.txMatchFilter = frameworkConfig.getTxMatchFilterTlv() != null
+ ? frameworkConfig.getTxMatchFilterTlv() : new byte[0];
+ aidlConfig.baseConfig.serviceProtoType = frameworkToHalUsdProtoType(
+ frameworkConfig.getServiceProtoType());
+ return aidlConfig;
+ }
+
+ /**
+ * Start a USD subscribe operation.
+ *
+ * @param ifaceName Name of the interface
+ * @param cmdId An id for this command
+ * @param subscribeConfig Subscribe configuration
+ * @return true if successful, false otherwise
+ */
+ public boolean startUsdSubscribe(@NonNull String ifaceName, int cmdId,
+ @NonNull SubscribeConfig subscribeConfig) {
+ synchronized (mLock) {
+ final String methodName = "startUsdSubscribe";
+ if (ifaceName == null || subscribeConfig == null) {
+ return false;
+ }
+ IStaInterface iface = getStaIfaceOrLogError(ifaceName, methodName);
+ if (iface == null) {
+ return false;
+ }
+ try {
+ iface.startUsdSubscribe(cmdId, frameworkToHalUsdSubscribeConfig(subscribeConfig));
+ return true;
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodName);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodName);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Get the USD capabilities for the interface.
+ *
+ * @param ifaceName Name of the interface
+ * @return UsdCapabilities if available, otherwise null
+ */
+ public @Nullable SupplicantStaIfaceHal.UsdCapabilitiesInternal getUsdCapabilities(
+ @NonNull String ifaceName) {
+ synchronized (mLock) {
+ final String methodName = "getUsdCapabilities";
+ if (ifaceName == null) {
+ return null;
+ }
+ IStaInterface iface = getStaIfaceOrLogError(ifaceName, methodName);
+ if (iface == null) {
+ return null;
+ }
+ try {
+ IStaInterface.UsdCapabilities aidlCaps = iface.getUsdCapabilities();
+ if (aidlCaps == null) {
+ Log.e(TAG, "Received null USD capabilities from the HAL");
+ return null;
+ }
+ return new SupplicantStaIfaceHal.UsdCapabilitiesInternal(
+ aidlCaps.isUsdPublisherSupported,
+ aidlCaps.isUsdSubscriberSupported,
+ aidlCaps.maxLocalSsiLengthBytes,
+ aidlCaps.maxServiceNameLengthBytes,
+ aidlCaps.maxMatchFilterLengthBytes,
+ aidlCaps.maxNumPublishSessions,
+ aidlCaps.maxNumSubscribeSessions);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodName);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodName);
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Update an ongoing USD publish operation.
+ *
+ * @param ifaceName Name of the interface
+ * @param publishId Publish id for this session
+ * @param ssi Service specific info
+ */
+ public void updateUsdPublish(@NonNull String ifaceName, int publishId,
+ @NonNull byte[] ssi) {
+ synchronized (mLock) {
+ final String methodName = "updateUsdPublish";
+ if (ifaceName == null || ssi == null) {
+ return;
+ }
+ IStaInterface iface = getStaIfaceOrLogError(ifaceName, methodName);
+ if (iface == null) {
+ return;
+ }
+ try {
+ iface.updateUsdPublish(publishId, ssi);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodName);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodName);
+ }
+ }
+ }
+
+ /**
+ * Cancel an ongoing USD publish session.
+ *
+ * @param ifaceName Name of the interface
+ * @param publishId Publish id for the session
+ */
+ public void cancelUsdPublish(@NonNull String ifaceName, int publishId) {
+ synchronized (mLock) {
+ final String methodName = "cancelUsdPublish";
+ if (ifaceName == null) {
+ return;
+ }
+ IStaInterface iface = getStaIfaceOrLogError(ifaceName, methodName);
+ if (iface == null) {
+ return;
+ }
+ try {
+ iface.cancelUsdPublish(publishId);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodName);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodName);
+ }
+ }
+ }
+
+ /**
+ * Cancel an ongoing USD subscribe session.
+ *
+ * @param ifaceName Name of the interface
+ * @param subscribeId Subscribe id for the session
+ */
+ public void cancelUsdSubscribe(@NonNull String ifaceName, int subscribeId) {
+ synchronized (mLock) {
+ final String methodName = "cancelUsdSubscribe";
+ if (ifaceName == null) {
+ return;
+ }
+ IStaInterface iface = getStaIfaceOrLogError(ifaceName, methodName);
+ if (iface == null) {
+ return;
+ }
+ try {
+ iface.cancelUsdSubscribe(subscribeId);
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodName);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodName);
+ }
+ }
+ }
+
+ private static UsdMessageInfo createUsdMessageInfo(int ownId, int peerId,
+ MacAddress peerMacAddress, byte[] message) {
+ UsdMessageInfo messageInfo = new UsdMessageInfo();
+ messageInfo.ownId = ownId;
+ messageInfo.peerId = peerId;
+ messageInfo.message = message;
+ messageInfo.peerMacAddress = peerMacAddress.toByteArray();
+ return messageInfo;
+ }
+
+ /**
+ * Send a message to an ongoing USD publish or subscribe session.
+ *
+ * @param ifaceName Name of the interface
+ * @param ownId Id for the session
+ * @param peerId Id for the peer session
+ * @param peerMacAddress Mac address of the peer session
+ * @param message Data to send
+ * @return true if successful, false otherwise
+ */
+ public boolean sendUsdMessage(@NonNull String ifaceName, int ownId, int peerId,
+ @NonNull MacAddress peerMacAddress, @NonNull byte[] message) {
+ synchronized (mLock) {
+ final String methodName = "sendUsdMessage";
+ if (ifaceName == null || peerMacAddress == null || message == null) {
+ return false;
+ }
+ IStaInterface iface = getStaIfaceOrLogError(ifaceName, methodName);
+ if (iface == null) {
+ return false;
+ }
+ try {
+ iface.sendUsdMessage(
+ createUsdMessageInfo(ownId, peerId, peerMacAddress, message));
+ return true;
+ } catch (ServiceSpecificException e) {
+ handleServiceSpecificException(e, methodName);
+ } catch (RemoteException e) {
+ handleRemoteException(e, methodName);
+ }
+ return false;
+ }
+ }
+
private void handleServiceSpecificException(ServiceSpecificException e, String methodName) {
Log.e(TAG, methodName + " encountered ServiceSpecificException " + e);
}
@@ -354,6 +699,17 @@ public class MainlineSupplicant {
return true;
}
+ private @Nullable IStaInterface getStaIfaceOrLogError(String ifaceName, String methodName) {
+ synchronized (mLock) {
+ if (!mActiveStaIfaces.containsKey(ifaceName)) {
+ Log.e(TAG, "Unable to call " + methodName + " since iface "
+ + ifaceName + " does not exist");
+ return null;
+ }
+ return mActiveStaIfaces.get(ifaceName);
+ }
+ }
+
private void handleRemoteException(RemoteException e, String methodName) {
synchronized (mLock) {
Log.e(TAG, methodName + " encountered RemoteException " + e);
diff --git a/service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicantStaIfaceCallback.java b/service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicantStaIfaceCallback.java
index 20cda62861..4d6207357e 100644
--- a/service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicantStaIfaceCallback.java
+++ b/service/java/com/android/server/wifi/mainline_supplicant/MainlineSupplicantStaIfaceCallback.java
@@ -17,15 +17,26 @@
package com.android.server.wifi.mainline_supplicant;
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.net.MacAddress;
+import android.net.wifi.usd.Config;
+import android.net.wifi.usd.SessionCallback;
import android.system.wifi.mainline_supplicant.IStaInterfaceCallback;
import android.system.wifi.mainline_supplicant.UsdMessageInfo;
+import android.system.wifi.mainline_supplicant.UsdServiceProtoType;
+import android.util.Log;
import com.android.server.wifi.WifiThreadRunner;
+import com.android.server.wifi.usd.UsdNativeManager;
+import com.android.server.wifi.usd.UsdRequestManager;
/**
* Implementation of the mainline supplicant {@link IStaInterfaceCallback}.
*/
public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.Stub {
+ private static final String TAG = "MainlineSupplicantStaIfaceCallback";
+
private final MainlineSupplicant mMainlineSupplicant;
private final String mIfaceName;
private final WifiThreadRunner mWifiThreadRunner;
@@ -45,7 +56,17 @@ public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.St
* @param publishId Identifier for the publish session.
*/
@Override
- public void onUsdPublishStarted(int cmdId, int publishId) { }
+ public void onUsdPublishStarted(int cmdId, int publishId) {
+ mWifiThreadRunner.post(() -> {
+ UsdNativeManager.UsdEventsCallback usdCallback =
+ mMainlineSupplicant.getUsdEventsCallback();
+ if (usdCallback == null) {
+ Log.e(TAG, "UsdEventsCallback callback is null");
+ return;
+ }
+ usdCallback.onUsdPublishStarted(cmdId, publishId);
+ });
+ }
/**
* Called in response to startUsdSubscribe to indicate that the subscribe session
@@ -55,7 +76,30 @@ public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.St
* @param subscribeId Identifier for the subscribe session.
*/
@Override
- public void onUsdSubscribeStarted(int cmdId, int subscribeId) { }
+ public void onUsdSubscribeStarted(int cmdId, int subscribeId) {
+ mWifiThreadRunner.post(() -> {
+ UsdNativeManager.UsdEventsCallback usdCallback =
+ mMainlineSupplicant.getUsdEventsCallback();
+ if (usdCallback == null) {
+ Log.e(TAG, "UsdEventsCallback callback is null");
+ return;
+ }
+ usdCallback.onUsdSubscribeStarted(cmdId, subscribeId);
+ });
+ }
+
+ @SuppressLint("NewApi")
+ private static @SessionCallback.FailureCode int
+ convertHalToFrameworkUsdConfigErrorCode(int errorCode) {
+ switch (errorCode) {
+ case UsdConfigErrorCode.FAILURE_TIMEOUT:
+ return SessionCallback.FAILURE_TIMEOUT;
+ case UsdConfigErrorCode.FAILURE_NOT_AVAILABLE:
+ return SessionCallback.FAILURE_NOT_AVAILABLE;
+ default:
+ return SessionCallback.FAILURE_UNKNOWN;
+ }
+ }
/**
* Called in response to startUsdPublish to indicate that the publish session
@@ -64,7 +108,18 @@ public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.St
* @param cmdId Identifier for the original request.
* @param errorCode Code indicating the failure reason.
*/
- @Override public void onUsdPublishConfigFailed(int cmdId, int errorCode) { }
+ @Override public void onUsdPublishConfigFailed(int cmdId, int errorCode) {
+ mWifiThreadRunner.post(() -> {
+ UsdNativeManager.UsdEventsCallback usdCallback =
+ mMainlineSupplicant.getUsdEventsCallback();
+ if (usdCallback == null) {
+ Log.e(TAG, "UsdEventsCallback callback is null");
+ return;
+ }
+ usdCallback.onUsdPublishConfigFailed(cmdId,
+ convertHalToFrameworkUsdConfigErrorCode(errorCode));
+ });
+ }
/**
* Called in response to startUsdSubscribe to indicate that the subscribe session
@@ -74,7 +129,29 @@ public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.St
* @param errorCode Code indicating the failure reason.
*/
@Override
- public void onUsdSubscribeConfigFailed(int cmdId, int errorCode) { }
+ public void onUsdSubscribeConfigFailed(int cmdId, int errorCode) {
+ mWifiThreadRunner.post(() -> {
+ UsdNativeManager.UsdEventsCallback usdCallback =
+ mMainlineSupplicant.getUsdEventsCallback();
+ if (usdCallback == null) {
+ Log.e(TAG, "UsdEventsCallback callback is null");
+ return;
+ }
+ usdCallback.onUsdSubscribeConfigFailed(cmdId,
+ convertHalToFrameworkUsdConfigErrorCode(errorCode));
+ });
+ }
+
+ @SuppressLint("NewApi")
+ private static @SessionCallback.TerminationReasonCode int
+ convertHalToFrameworkUsdTerminateReasonCode(int reasonCode) {
+ switch (reasonCode) {
+ case UsdTerminateReasonCode.USER_REQUESTED:
+ return SessionCallback.TERMINATION_REASON_USER_INITIATED;
+ default:
+ return SessionCallback.TERMINATION_REASON_UNKNOWN;
+ }
+ }
/**
* Called in response to cancelUsdPublish to indicate that the session was cancelled
@@ -84,7 +161,18 @@ public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.St
* @param reasonCode Code indicating the reason for the session cancellation.
*/
@Override
- public void onUsdPublishTerminated(int publishId, int reasonCode) { }
+ public void onUsdPublishTerminated(int publishId, int reasonCode) {
+ mWifiThreadRunner.post(() -> {
+ UsdNativeManager.UsdEventsCallback usdCallback =
+ mMainlineSupplicant.getUsdEventsCallback();
+ if (usdCallback == null) {
+ Log.e(TAG, "UsdEventsCallback callback is null");
+ return;
+ }
+ usdCallback.onUsdPublishTerminated(publishId,
+ convertHalToFrameworkUsdTerminateReasonCode(reasonCode));
+ });
+ }
/**
* Called in response to cancelUsdSubscribe to indicate that the session was cancelled
@@ -94,7 +182,59 @@ public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.St
* @param reasonCode Code indicating the reason for the session cancellation.
*/
@Override
- public void onUsdSubscribeTerminated(int subscribeId, int reasonCode) { }
+ public void onUsdSubscribeTerminated(int subscribeId, int reasonCode) {
+ mWifiThreadRunner.post(() -> {
+ UsdNativeManager.UsdEventsCallback usdCallback =
+ mMainlineSupplicant.getUsdEventsCallback();
+ if (usdCallback == null) {
+ Log.e(TAG, "UsdEventsCallback callback is null");
+ return;
+ }
+ usdCallback.onUsdSubscribeTerminated(subscribeId,
+ convertHalToFrameworkUsdTerminateReasonCode(reasonCode));
+ });
+ }
+
+ private static @Config.ServiceProtoType int
+ convertHalToFrameworkUsdProtocolType(int protocolType) {
+ switch (protocolType) {
+ case UsdServiceProtoType.CSA_MATTER:
+ return Config.SERVICE_PROTO_TYPE_CSA_MATTER;
+ default:
+ return Config.SERVICE_PROTO_TYPE_GENERIC;
+ }
+ }
+
+ private static @Nullable MacAddress safeConvertMacAddress(byte[] macAddrBytes) {
+ if (macAddrBytes == null) return null;
+ try {
+ return MacAddress.fromBytes(macAddrBytes);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ private static UsdRequestManager.UsdHalDiscoveryInfo
+ convertHalToFrameworkUsdDiscoveryInfo(UsdServiceDiscoveryInfo discoveryInfo) {
+ if (discoveryInfo.peerMacAddress == null
+ || discoveryInfo.serviceSpecificInfo == null
+ || discoveryInfo.matchFilter == null) {
+ Log.e(TAG, "USD discovery info contains a null parameter");
+ return null;
+ }
+ MacAddress peerAddress = safeConvertMacAddress(discoveryInfo.peerMacAddress);
+ if (peerAddress == null) {
+ Log.e(TAG, "USD discovery info contains an invalid peer address");
+ return null;
+ }
+ return new UsdRequestManager.UsdHalDiscoveryInfo(discoveryInfo.ownId,
+ discoveryInfo.peerId,
+ peerAddress,
+ discoveryInfo.serviceSpecificInfo,
+ convertHalToFrameworkUsdProtocolType(discoveryInfo.serviceProtoType),
+ discoveryInfo.isFsd,
+ discoveryInfo.matchFilter);
+ }
/**
* Indicates that the publisher sent a solicited publish message to the subscriber.
@@ -102,7 +242,22 @@ public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.St
* @param info Instance of |UsdServiceDiscoveryInfo| containing information about the reply.
*/
@Override
- public void onUsdPublishReplied(UsdServiceDiscoveryInfo info) { }
+ public void onUsdPublishReplied(UsdServiceDiscoveryInfo info) {
+ mWifiThreadRunner.post(() -> {
+ UsdNativeManager.UsdEventsCallback usdCallback =
+ mMainlineSupplicant.getUsdEventsCallback();
+ if (usdCallback == null) {
+ Log.e(TAG, "UsdEventsCallback callback is null");
+ return;
+ }
+ UsdRequestManager.UsdHalDiscoveryInfo convertedInfo =
+ convertHalToFrameworkUsdDiscoveryInfo(info);
+ if (convertedInfo == null) {
+ return;
+ }
+ usdCallback.onUsdPublishReplied(convertedInfo);
+ });
+ }
/**
* Indicates that a publisher was discovered. Only called if this device is acting as a
@@ -111,7 +266,22 @@ public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.St
* @param info Instance of |UsdServiceDiscoveryInfo| containing information about the service.
*/
@Override
- public void onUsdServiceDiscovered(UsdServiceDiscoveryInfo info) { }
+ public void onUsdServiceDiscovered(UsdServiceDiscoveryInfo info) {
+ mWifiThreadRunner.post(() -> {
+ UsdNativeManager.UsdEventsCallback usdCallback =
+ mMainlineSupplicant.getUsdEventsCallback();
+ if (usdCallback == null) {
+ Log.e(TAG, "UsdEventsCallback callback is null");
+ return;
+ }
+ UsdRequestManager.UsdHalDiscoveryInfo convertedInfo =
+ convertHalToFrameworkUsdDiscoveryInfo(info);
+ if (convertedInfo == null) {
+ return;
+ }
+ usdCallback.onUsdServiceDiscovered(convertedInfo);
+ });
+ }
/**
* Indicates that a message was received on an active USD link.
@@ -119,5 +289,27 @@ public class MainlineSupplicantStaIfaceCallback extends IStaInterfaceCallback.St
* @param messageInfo Information about the message that was received.
*/
@Override
- public void onUsdMessageReceived(UsdMessageInfo messageInfo) { }
+ public void onUsdMessageReceived(UsdMessageInfo messageInfo) {
+ mWifiThreadRunner.post(() -> {
+ UsdNativeManager.UsdEventsCallback usdCallback =
+ mMainlineSupplicant.getUsdEventsCallback();
+ if (usdCallback == null) {
+ Log.e(TAG, "UsdEventsCallback callback is null");
+ return;
+ }
+ MacAddress peerAddress = safeConvertMacAddress(messageInfo.peerMacAddress);
+ if (peerAddress == null) {
+ Log.e(TAG, "USD message info contains an invalid peer address");
+ return;
+ }
+ if (messageInfo.message == null) {
+ Log.e(TAG, "USD message info contains a null message");
+ return;
+ }
+ usdCallback.onUsdMessageReceived(messageInfo.ownId,
+ messageInfo.peerId,
+ peerAddress,
+ messageInfo.message);
+ });
+ }
}
diff --git a/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java b/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java
index 713edd792e..7dac6f1264 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScannerInternal.java
@@ -26,6 +26,7 @@ import android.os.WorkSource;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.ParceledListSlice;
import com.android.server.wifi.WifiThreadRunner;
import java.util.Collections;
@@ -93,9 +94,9 @@ public abstract class WifiScannerInternal {
}
@Override
- public void onFullResults(List<ScanResult> fullScanResult) {
- mWifiThreadRunner.post(() -> fullScanResult.forEach(mScanListener::onFullResult),
- TAG + "#onFullResults");
+ public void onFullResults(ParceledListSlice<ScanResult> fullScanResult) {
+ mWifiThreadRunner.post(() -> fullScanResult.getList()
+ .forEach(mScanListener::onFullResult), TAG + "#onFullResults");
}
@Override
diff --git a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
index 5392d1a0fa..e8c37cf1b3 100644
--- a/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
+++ b/service/java/com/android/server/wifi/scanner/WifiScanningServiceImpl.java
@@ -61,6 +61,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
+import com.android.modules.utils.ParceledListSlice;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.wifi.ClientModeImpl;
import com.android.server.wifi.Clock;
@@ -1740,9 +1741,10 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
entry.clientInfo.reportEvent((listener) -> {
try {
- listener.onFullResults(new ArrayList<>(matchedScanResults));
+ listener.onFullResults(
+ new ParceledListSlice<>(new ArrayList<>(matchedScanResults)));
} catch (RemoteException e) {
- loge("Failed to call onFullResult: " + entry.clientInfo);
+ loge("Failed to call onFullResults: " + entry.clientInfo);
}
});
matchedScanResults.clear();
@@ -1751,9 +1753,9 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
for (RequestInfo<Void> entry : mSingleScanListeners) {
entry.clientInfo.reportEvent((listener) -> {
try {
- listener.onFullResults(results);
+ listener.onFullResults(new ParceledListSlice<>(results));
} catch (RemoteException e) {
- loge("Failed to call onFullResult: " + entry.clientInfo);
+ loge("Failed to call onFullResults: " + entry.clientInfo);
}
});
}
@@ -1779,7 +1781,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
// make sure the handler is removed
listener.onSingleScanCompleted();
} catch (RemoteException e) {
- loge("Failed to call onResult: " + entry.clientInfo);
+ loge("Failed to call onResults: " + entry.clientInfo);
}
});
}
@@ -1791,7 +1793,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
try {
listener.onResults(allResults);
} catch (RemoteException e) {
- loge("Failed to call onResult: " + entry.clientInfo);
+ loge("Failed to call onResults: " + entry.clientInfo);
}
});
}
@@ -2314,9 +2316,10 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
}
entry.clientInfo.reportEvent((listener) -> {
try {
- listener.onFullResults(new ArrayList<>(matchedResults));
+ listener.onFullResults(
+ new ParceledListSlice<>(new ArrayList<>(matchedResults)));
} catch (RemoteException e) {
- loge("Failed to call onFullResult: " + ci);
+ loge("Failed to call onFullResults: " + ci);
}
});
}
@@ -2350,7 +2353,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
try {
listener.onResults(resultsToDeliver);
} catch (RemoteException e) {
- loge("Failed to call onFullResult: " + ci);
+ loge("Failed to call onResults: " + ci);
}
});
}
@@ -2364,7 +2367,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
try {
listener.onFailure(reason, description);
} catch (RemoteException e) {
- loge("Failed to call onFullResult: " + ci);
+ loge("Failed to call onFailure: " + ci);
}
});
}
@@ -3229,7 +3232,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
try {
listener.onPnoNetworkFound(results);
} catch (RemoteException e) {
- loge("Failed to call onFullResult: " + ci);
+ loge("Failed to call onPnoNetworkFound: " + ci);
}
});
}
@@ -3242,7 +3245,7 @@ public class WifiScanningServiceImpl extends IWifiScanner.Stub {
try {
listener.onFailure(reason, description);
} catch (RemoteException e) {
- loge("Failed to call onFullResult: " + ci);
+ loge("Failed to call onFailure: " + ci);
}
});
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java b/service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java
index 158e35bb9c..ab181f693a 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/LastMileLoggerTest.java
@@ -24,6 +24,9 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import android.os.Handler;
+import android.os.test.TestLooper;
+
import androidx.test.filters.SmallTest;
import com.android.server.wifi.util.FileUtils;
@@ -52,6 +55,8 @@ public class LastMileLoggerTest extends WifiBaseTest {
@Mock WifiInjector mWifiInjector;
@Spy FakeWifiLog mLog;
+ private TestLooper mLooper;
+
@Before
public void setUp() throws Exception {
@@ -64,8 +69,10 @@ public class LastMileLoggerTest extends WifiBaseTest {
mTraceEnableFile.deleteOnExit();
mTraceReleaseFile.deleteOnExit();
FileUtils.stringToFile(mTraceEnableFile.getPath(), "0");
+ mLooper = new TestLooper();
+ Handler backgroundHandler = new Handler(mLooper.getLooper());
mLastMileLogger = new LastMileLogger(mWifiInjector, mTraceDataFile.getPath(),
- mTraceEnableFile.getPath(), mTraceReleaseFile.getPath());
+ mTraceEnableFile.getPath(), mTraceReleaseFile.getPath(), backgroundHandler);
}
private static String readFileAsString(File file) throws IOException {
@@ -75,13 +82,15 @@ public class LastMileLoggerTest extends WifiBaseTest {
@Test
public void ctorDoesNotCrash() throws Exception {
new LastMileLogger(mWifiInjector, mTraceDataFile.getPath(), mTraceEnableFile.getPath(),
- mTraceReleaseFile.getPath());
+ mTraceReleaseFile.getPath(), new Handler(mLooper.getLooper()));
+ mLooper.dispatchAll();
verifyNoMoreInteractions(mLog);
}
@Test
public void connectionEventStartedEnablesTracing() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
assertEquals("1", readFileAsString(mTraceEnableFile));
}
@@ -89,6 +98,7 @@ public class LastMileLoggerTest extends WifiBaseTest {
public void connectionEventStartedDoesNotCrashIfReleaseFileIsMissing() throws Exception {
mTraceReleaseFile.delete();
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
verify(mLog).warn(contains("Failed to open free_buffer"));
}
@@ -97,13 +107,14 @@ public class LastMileLoggerTest extends WifiBaseTest {
throws Exception {
mTraceReleaseFile.delete();
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
assertEquals("0", readFileAsString(mTraceEnableFile));
}
@Test
public void connectionEventStartedDoesNotAttemptToReopenReleaseFile() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
-
+ mLooper.dispatchAll();
// This is a rather round-about way of verifying that we don't attempt to re-open
// the file. Namely: if we delete the |release| file, and CONNECTION_EVENT_STARTED
// _did_ re-open the file, then we'd log an error message. Since the test is deleting the
@@ -114,6 +125,7 @@ public class LastMileLoggerTest extends WifiBaseTest {
// FileInputStream.
mTraceReleaseFile.delete();
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
verifyNoMoreInteractions(mLog);
}
@@ -121,36 +133,42 @@ public class LastMileLoggerTest extends WifiBaseTest {
public void connectionEventStartedDoesNotCrashIfEnableFileIsMissing() throws Exception {
mTraceEnableFile.delete();
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
}
@Test
public void connectionEventStartedDoesNotCrashOnRepeatedCalls() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
}
@Test
public void connectionEventSucceededDisablesTracing() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED);
assertEquals("0", readFileAsString(mTraceEnableFile));
+ mLooper.dispatchAll();
}
@Test
public void connectionEventSucceededDoesNotCrashIfEnableFileIsMissing() throws Exception {
mTraceEnableFile.delete();
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED);
+ mLooper.dispatchAll();
}
@Test
public void connectionEventSucceededDoesNotCrashOnRepeatedCalls() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED);
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED);
+ mLooper.dispatchAll();
}
@Test
public void connectionEventFailedDisablesTracingWhenPendingFails() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_FAILED);
+ mLooper.dispatchAll();
assertEquals("0", readFileAsString(mTraceEnableFile));
}
@@ -158,25 +176,30 @@ public class LastMileLoggerTest extends WifiBaseTest {
public void connectionEventTimeoutDisablesTracing() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_TIMEOUT);
+ mLooper.dispatchAll();
assertEquals("0", readFileAsString(mTraceEnableFile));
}
@Test
public void multipleIfaces() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
assertEquals("1", readFileAsString(mTraceEnableFile));
mLastMileLogger.reportConnectionEvent(WLAN1, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
assertEquals("1", readFileAsString(mTraceEnableFile));
FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect");
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_TIMEOUT);
+ mLooper.dispatchAll();
assertEquals("1", readFileAsString(mTraceEnableFile));
String dumpString = getDumpString();
assertTrue(dumpString.contains("--- Last failed"));
assertTrue(dumpString.contains("rdev_connect"));
mLastMileLogger.reportConnectionEvent(WLAN1, WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED);
+ mLooper.dispatchAll();
assertEquals("0", readFileAsString(mTraceEnableFile));
}
@@ -184,25 +207,30 @@ public class LastMileLoggerTest extends WifiBaseTest {
public void connectionEventFailedDoesNotCrashIfEnableFileIsMissing() throws Exception {
mTraceEnableFile.delete();
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_FAILED);
+ mLooper.dispatchAll();
}
@Test
public void connectionEventFailedDoesNotCrashIfDataFileIsMissing() throws Exception {
mTraceDataFile.delete();
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_FAILED);
+ mLooper.dispatchAll();
}
@Test
public void connectionEventFailedDoesNotCrashOnRepeatedCalls() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_FAILED);
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_FAILED);
+ mLooper.dispatchAll();
}
@Test
public void dumpShowsFailureTrace() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect");
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_FAILED);
+ mLooper.dispatchAll();
assertTrue(getDumpString().contains("--- Last failed"));
assertTrue(getDumpString().contains("rdev_connect"));
}
@@ -211,6 +239,7 @@ public class LastMileLoggerTest extends WifiBaseTest {
@Test
public void dumpShowsPendingConnectionTrace() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect");
assertTrue(getDumpString().contains("No last mile log for \"Last failed"));
assertTrue(getDumpString().contains("--- Latest"));
@@ -220,9 +249,11 @@ public class LastMileLoggerTest extends WifiBaseTest {
@Test
public void dumpShowsLastFailureTraceAndPendingConnectionTrace() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect try #1");
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_FAILED);
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect try #2");
String dumpString = getDumpString();
@@ -233,11 +264,14 @@ public class LastMileLoggerTest extends WifiBaseTest {
@Test
public void dumpShowsLastFailureTraceAndCurrentConnectionTrace() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect try #1");
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_FAILED);
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect try #2");
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED);
+ mLooper.dispatchAll();
String dumpString = getDumpString();
assertTrue(dumpString.contains("rdev_connect try #1"));
@@ -247,8 +281,10 @@ public class LastMileLoggerTest extends WifiBaseTest {
@Test
public void dumpDoesNotClearLastFailureData() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect");
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_FAILED);
+ mLooper.dispatchAll();
getDumpString();
String dumpString = getDumpString();
@@ -258,6 +294,7 @@ public class LastMileLoggerTest extends WifiBaseTest {
@Test
public void dumpDoesNotClearPendingConnectionTrace() throws Exception {
mLastMileLogger.reportConnectionEvent(WLAN0, WifiDiagnostics.CONNECTION_EVENT_STARTED);
+ mLooper.dispatchAll();
FileUtils.stringToFile(mTraceDataFile.getPath(), "rdev_connect");
getDumpString();
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java
index 867396da1d..fe582e3521 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SarManagerTest.java
@@ -133,7 +133,6 @@ public class SarManagerTest extends WifiBaseTest {
mWifiDeviceStateChangeManager);
mSarMgr.handleBootCompleted();
-
if (isSarEnabled) {
/* Capture the PhoneStateListener */
ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
@@ -573,4 +572,44 @@ public class SarManagerTest extends WifiBaseTest {
assertTrue(mSarInfo.isWifiScanOnlyEnabled);
assertFalse(mSarInfo.isWifiClientEnabled);
}
+
+ /**
+ * Test that for devices that support setting/resetting Tx Power limits, device sets wifi enable
+ * first then finish the boot up. Verify device will change the power scenario.
+ */
+ @Test
+ public void testSarMgr_enabledTxPowerScenario_wifiOn_before_boot_completed_offHook() {
+ mResources.setBoolean(
+ R.bool.config_wifi_framework_enable_sar_tx_power_limit, true);
+ mResources.setBoolean(
+ R.bool.config_wifi_framework_enable_soft_ap_sar_tx_power_limit,
+ false);
+
+ mSarMgr = new SarManager(mContext, mTelephonyManager, mLooper.getLooper(), mWifiNative,
+ mWifiDeviceStateChangeManager);
+ /* Enable logs from SarManager */
+ enableDebugLogs();
+
+ InOrder inOrder = inOrder(mWifiNative);
+ // Enable wifi first, should be no change to the WifiNative
+ mSarMgr.setClientWifiState(WifiManager.WIFI_STATE_ENABLED);
+ inOrder.verify(mWifiNative, never()).selectTxPowerScenario(any());
+
+ mSarMgr.handleBootCompleted();
+ ArgumentCaptor<PhoneStateListener> phoneStateListenerCaptor =
+ ArgumentCaptor.forClass(PhoneStateListener.class);
+ verify(mTelephonyManager).listen(phoneStateListenerCaptor.capture(),
+ eq(PhoneStateListener.LISTEN_CALL_STATE));
+ mPhoneStateListener = phoneStateListenerCaptor.getValue();
+ assertNotNull(mPhoneStateListener);
+ captureSarInfo(mWifiNative);
+ assertFalse(mSarInfo.isVoiceCall);
+ inOrder.verify(mWifiNative).selectTxPowerScenario(eq(mSarInfo));
+
+ /* Set phone state to OFFHOOK */
+ mPhoneStateListener.onCallStateChanged(CALL_STATE_OFFHOOK, "");
+
+ inOrder.verify(mWifiNative).selectTxPowerScenario(eq(mSarInfo));
+ assertTrue(mSarInfo.isVoiceCall);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java
index 4e5250d387..64831e172d 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiLockManagerTest.java
@@ -303,7 +303,7 @@ public class WifiLockManagerTest extends WifiBaseTest {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "", mBinder, mWorkSource);
releaseWifiLockSuccessful(mBinder);
- verify(mWifiMetrics).addWifiLockAcqSession(
+ verify(mWifiMetrics).addWifiLockManagerAcqSession(
eq(mDeviceConfigFacade.isHighPerfLockDeprecated() && SdkLevel.isAtLeastU()
? WifiManager.WIFI_MODE_FULL_LOW_LATENCY
: WifiManager.WIFI_MODE_FULL_HIGH_PERF), eq(new int[]{DEFAULT_TEST_UID_1}),
@@ -632,7 +632,7 @@ public class WifiLockManagerTest extends WifiBaseTest {
// Release the first lock
releaseWifiLockSuccessful(mBinder);
- verify(mWifiMetrics).addWifiLockAcqSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
+ verify(mWifiMetrics).addWifiLockManagerAcqSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
eq(new int[]{DEFAULT_TEST_UID_1}), eq(new String[]{null}), anyInt(), anyLong(),
anyBoolean(), anyBoolean(),
anyBoolean());
@@ -782,7 +782,7 @@ public class WifiLockManagerTest extends WifiBaseTest {
false);
releaseWifiLockSuccessful(mBinder);
- verify(mWifiMetrics).addWifiLockAcqSession(eq(expectedMode),
+ verify(mWifiMetrics).addWifiLockManagerAcqSession(eq(expectedMode),
eq(new int[]{DEFAULT_TEST_UID_1}), eq(new String[]{null}), anyInt(), anyLong(),
anyBoolean(), anyBoolean(), anyBoolean());
assertEquals(WifiManager.WIFI_MODE_NO_LOCKS_HELD,
@@ -863,7 +863,7 @@ public class WifiLockManagerTest extends WifiBaseTest {
eq(ClientMode.POWER_SAVE_CLIENT_WIFI_LOCK), anyBoolean());
releaseWifiLockSuccessful(mBinder);
- verify(mWifiMetrics).addWifiLockAcqSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
+ verify(mWifiMetrics).addWifiLockManagerAcqSession(eq(WifiManager.WIFI_MODE_FULL_HIGH_PERF),
eq(new int[]{DEFAULT_TEST_UID_1}), eq(new String[]{null}), anyInt(), anyLong(),
anyBoolean(), anyBoolean(), anyBoolean());
assertEquals(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
@@ -1757,7 +1757,7 @@ public class WifiLockManagerTest extends WifiBaseTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(releaseTime);
releaseWifiLockSuccessful_noBatteryStats(mBinder);
- verify(mWifiMetrics).addWifiLockAcqSession(eq(expectedMode),
+ verify(mWifiMetrics).addWifiLockManagerAcqSession(eq(expectedMode),
eq(new int[]{DEFAULT_TEST_UID_1}), eq(new String[]{null}), anyInt(),
eq(releaseTime - acquireTime), eq(true), eq(false), eq(false));
}
@@ -1808,7 +1808,8 @@ public class WifiLockManagerTest extends WifiBaseTest {
when(mClock.getElapsedSinceBootMillis()).thenReturn(releaseTime);
releaseWifiLockSuccessful_noBatteryStats(mBinder);
- verify(mWifiMetrics).addWifiLockAcqSession(eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
+ verify(mWifiMetrics).addWifiLockManagerAcqSession(
+ eq(WifiManager.WIFI_MODE_FULL_LOW_LATENCY),
eq(new int[]{DEFAULT_TEST_UID_1}), eq(new String[]{null}), anyInt(),
eq(releaseTime - acquireTime), eq(true), eq(false), eq(false));
@@ -1851,7 +1852,7 @@ public class WifiLockManagerTest extends WifiBaseTest {
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, TEST_WIFI_LOCK_TAG,
mBinder, mWorkSource);
releaseWifiLockSuccessful(mBinder);
- verify(mWifiMetrics).addWifiLockAcqSession(eq(expectedMode),
+ verify(mWifiMetrics).addWifiLockManagerAcqSession(eq(expectedMode),
eq(new int[]{DEFAULT_TEST_UID_1}), eq(new String[]{null}), anyInt(), anyLong(),
anyBoolean(), anyBoolean(), anyBoolean());
acquireWifiLockSuccessful(WifiManager.WIFI_MODE_FULL_HIGH_PERF, TEST_WIFI_LOCK_TAG,
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
index 3d3a2e6924..e16c2b1272 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiMetricsTest.java
@@ -5624,8 +5624,8 @@ public class WifiMetricsTest extends WifiBaseTest {
* Test the WifiLock acquisition session statistics
*/
@Test
- public void testWifiLockAcqSession() throws Exception {
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
+ public void testWifiLockManagerAcqSession() throws Exception {
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
new int[]{TEST_UID}, new String[]{TEST_TAG}, 0, 100000, false, false, false);
ExtendedMockito.verify(
() -> WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_RELEASED, new int[]{TEST_UID},
@@ -5633,7 +5633,7 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiStatsLog.WIFI_LOCK_RELEASED__MODE__WIFI_MODE_FULL_HIGH_PERF, 100000,
false, false, false));
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
new int[]{TEST_UID}, new String[]{TEST_TAG}, 0, 10000, true, false, false);
ExtendedMockito.verify(
() -> WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_RELEASED, new int[]{TEST_UID},
@@ -5641,7 +5641,7 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiStatsLog.WIFI_LOCK_RELEASED__MODE__WIFI_MODE_FULL_HIGH_PERF, 10000,
true, false, false));
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
new int[]{TEST_UID}, new String[]{TEST_TAG}, 0, 10000000, true, true, false);
ExtendedMockito.verify(
() -> WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_RELEASED, new int[]{TEST_UID},
@@ -5649,7 +5649,7 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiStatsLog.WIFI_LOCK_RELEASED__MODE__WIFI_MODE_FULL_HIGH_PERF, 10000000,
true, true, false));
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_HIGH_PERF,
new int[]{TEST_UID}, new String[]{TEST_TAG}, 0, 1000, true, true, true);
ExtendedMockito.verify(
() -> WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_RELEASED, new int[]{TEST_UID},
@@ -5658,7 +5658,7 @@ public class WifiMetricsTest extends WifiBaseTest {
true, true, true));
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
new int[]{TEST_UID}, new String[]{TEST_TAG}, 0, 90000, false, false, false);
ExtendedMockito.verify(
() -> WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_RELEASED, new int[]{TEST_UID},
@@ -5666,7 +5666,7 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiStatsLog.WIFI_LOCK_RELEASED__MODE__WIFI_MODE_FULL_LOW_LATENCY, 90000,
false, false, false));
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
new int[]{TEST_UID}, new String[]{TEST_TAG}, 0, 900000, true, false, false);
ExtendedMockito.verify(
() -> WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_RELEASED, new int[]{TEST_UID},
@@ -5674,7 +5674,7 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiStatsLog.WIFI_LOCK_RELEASED__MODE__WIFI_MODE_FULL_LOW_LATENCY, 900000,
true, false, false));
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
new int[]{TEST_UID}, new String[]{TEST_TAG}, 0, 9000, true, true, false);
ExtendedMockito.verify(
() -> WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_RELEASED, new int[]{TEST_UID},
@@ -5682,7 +5682,7 @@ public class WifiMetricsTest extends WifiBaseTest {
WifiStatsLog.WIFI_LOCK_RELEASED__MODE__WIFI_MODE_FULL_LOW_LATENCY, 9000,
true, true, false));
- mWifiMetrics.addWifiLockAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
+ mWifiMetrics.addWifiLockManagerAcqSession(WifiManager.WIFI_MODE_FULL_LOW_LATENCY,
new int[]{TEST_UID}, new String[]{TEST_TAG}, 0, 20000000, true, true, true);
ExtendedMockito.verify(
() -> WifiStatsLog.write(WifiStatsLog.WIFI_LOCK_RELEASED, new int[]{TEST_UID},
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index 21aba31784..329a7a8ef0 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -3342,6 +3342,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1,
new int[0]);
mWifiNetworkFactory.needNetworkFor(mNetworkRequest);
+ setScreenState(false);
// Verify we did not trigger the UI for the second request.
verify(mContext, never()).startActivityAsUser(any(), any());
diff --git a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
index 97d11c99a5..0b6181aa89 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/WifiServiceImplTest.java
@@ -1842,7 +1842,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testSetWifiApConfigurationNullConfigNotSaved() throws Exception {
when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
assertFalse(mWifiServiceImpl.setWifiApConfiguration(null, TEST_PACKAGE_NAME));
- verify(mWifiApConfigStore, never()).setApConfiguration(isNull(SoftApConfiguration.class));
+ verify(mWifiApConfigStore, never()).setApConfiguration(isNull());
}
/**
@@ -1903,7 +1903,7 @@ public class WifiServiceImplTest extends WifiBaseTest {
public void testSetSoftApConfigurationNullConfigNotSaved() throws Exception {
when(mWifiPermissionsUtil.checkConfigOverridePermission(anyInt())).thenReturn(true);
assertFalse(mWifiServiceImpl.setSoftApConfiguration(null, TEST_PACKAGE_NAME));
- verify(mWifiApConfigStore, never()).setApConfiguration(isNull(SoftApConfiguration.class));
+ verify(mWifiApConfigStore, never()).setApConfiguration(isNull());
verify(mActiveModeWarden, never()).updateSoftApConfiguration(any());
verify(mWifiPermissionsUtil).checkConfigOverridePermission(anyInt());
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
index 55f63e1513..a4ebf7b185 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/aware/WifiAwareStateManagerTest.java
@@ -2971,7 +2971,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
null, messageId, 0);
mMockLooper.dispatchAll();
inOrder.verify(mMockNative).sendMessage(transactionId.capture(), eq(subscribeId),
- eq(requestorId), eq(peerMac), isNull(byte[].class), eq(messageId));
+ eq(requestorId), eq(peerMac), isNull(), eq(messageId));
short tid = transactionId.getValue();
mDut.onMessageSendQueuedSuccessResponse(tid);
mMockLooper.dispatchAll();
@@ -3873,6 +3873,7 @@ public class WifiAwareStateManagerTest extends WifiBaseTest {
validateCorrectAwareStatusChangeBroadcast(inOrder);
inOrder.verify(mMockNative).disable(transactionId.capture());
mDut.onDisableResponse(transactionId.getValue(), NanStatusCode.SUCCESS);
+ mDut.onAwareDownNotification(NanStatusCode.SUCCESS);
mMockLooper.dispatchAll();
assertFalse(mDut.isDeviceAttached());
collector.checkThat("usage disabled", mDut.isUsageEnabled(), equalTo(false));
diff --git a/service/tests/wifitests/src/com/android/server/wifi/mainline_supplicant/MainlineSupplicantTest.java b/service/tests/wifitests/src/com/android/server/wifi/mainline_supplicant/MainlineSupplicantTest.java
index d1c25a5078..2312fc6c33 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/mainline_supplicant/MainlineSupplicantTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/mainline_supplicant/MainlineSupplicantTest.java
@@ -16,7 +16,9 @@
package com.android.server.wifi.mainline_supplicant;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -27,6 +29,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.net.wifi.usd.PublishConfig;
+import android.net.wifi.usd.SubscribeConfig;
import android.net.wifi.util.Environment;
import android.os.Handler;
import android.os.IBinder;
@@ -48,6 +52,7 @@ import org.mockito.MockitoAnnotations;
*/
public class MainlineSupplicantTest {
private static final String IFACE_NAME = "wlan0";
+ private static final String USD_SERVICE_NAME = "usd_service";
private @Mock IMainlineSupplicant mIMainlineSupplicantMock;
private @Mock IBinder mIBinderMock;
@@ -176,4 +181,37 @@ public class MainlineSupplicantTest {
// Only the valid remove request should reach have reached the service
verify(mIMainlineSupplicantMock, times(1)).removeStaInterface(anyString());
}
+
+ private void verifyUsdBaseConfigDefaultValues(IStaInterface.UsdBaseConfig baseConfig) {
+ assertNotNull(baseConfig.serviceName);
+ assertNotNull(baseConfig.freqsMhz);
+ assertNotNull(baseConfig.serviceSpecificInfo);
+ assertNotNull(baseConfig.rxMatchFilter);
+ assertNotNull(baseConfig.txMatchFilter);
+ assertEquals(MainlineSupplicant.DEFAULT_USD_FREQ_MHZ, baseConfig.defaultFreqMhz);
+ }
+
+ /**
+ * Verify that the proper default values are assigned during the
+ * USD Publish Config conversion.
+ */
+ @Test
+ public void testUsdPublishConfigConversionDefaultValues() {
+ PublishConfig frameworkConfig = new PublishConfig.Builder(USD_SERVICE_NAME).build();
+ IStaInterface.UsdPublishConfig aidlConfig =
+ MainlineSupplicant.frameworkToHalUsdPublishConfig(frameworkConfig);
+ verifyUsdBaseConfigDefaultValues(aidlConfig.baseConfig);
+ }
+
+ /**
+ * Verify that the proper default values are assigned during the
+ * USD Subscribe Config conversion.
+ */
+ @Test
+ public void testUsdSubscribeConfigConversionDefaultValues() {
+ SubscribeConfig frameworkConfig = new SubscribeConfig.Builder(USD_SERVICE_NAME).build();
+ IStaInterface.UsdSubscribeConfig aidlConfig =
+ MainlineSupplicant.frameworkToHalUsdSubscribeConfig(frameworkConfig);
+ verifyUsdBaseConfigDefaultValues(aidlConfig.baseConfig);
+ }
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java b/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java
index b037b168ee..18eb867784 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/scanner/WificondScannerTest.java
@@ -141,12 +141,9 @@ public class WificondScannerTest extends BaseWifiScannerImplTest {
public void externalScanResultsDoNotCauseSpuriousTimerCancellationOrCrash() {
mWifiMonitor.sendMessage(IFACE_NAME, WifiMonitor.SCAN_RESULTS_EVENT);
mLooper.dispatchAll();
- verify(mAlarmManager.getAlarmManager(), never()).cancel(any(PendingIntent.class));
+ verify(mAlarmManager.getAlarmManager(), never()).cancel(nullable(PendingIntent.class));
verify(mAlarmManager.getAlarmManager(), never())
- .cancel(any(AlarmManager.OnAlarmListener.class));
- verify(mAlarmManager.getAlarmManager(), never()).cancel(isNull(PendingIntent.class));
- verify(mAlarmManager.getAlarmManager(), never())
- .cancel(isNull(AlarmManager.OnAlarmListener.class));
+ .cancel(nullable(AlarmManager.OnAlarmListener.class));
}
@Test
@@ -166,12 +163,11 @@ public class WificondScannerTest extends BaseWifiScannerImplTest {
mWifiMonitor.sendMessage(IFACE_NAME, WifiMonitor.SCAN_RESULTS_EVENT);
mLooper.dispatchAll();
- verify(mAlarmManager.getAlarmManager(), never()).cancel(any(PendingIntent.class));
+ verify(mAlarmManager.getAlarmManager(), never()).cancel(nullable(PendingIntent.class));
verify(mAlarmManager.getAlarmManager(), times(1))
.cancel(any(AlarmManager.OnAlarmListener.class));
- verify(mAlarmManager.getAlarmManager(), never()).cancel(isNull(PendingIntent.class));
verify(mAlarmManager.getAlarmManager(), never())
- .cancel(isNull(AlarmManager.OnAlarmListener.class));
+ .cancel((AlarmManager.OnAlarmListener)isNull());
}
@Test
@@ -198,12 +194,9 @@ public class WificondScannerTest extends BaseWifiScannerImplTest {
mWifiMonitor.sendMessage(IFACE_NAME, WifiMonitor.SCAN_RESULTS_EVENT);
mLooper.dispatchAll();
- verify(mAlarmManager.getAlarmManager(), never()).cancel(any(PendingIntent.class));
- verify(mAlarmManager.getAlarmManager(), never())
- .cancel(any(AlarmManager.OnAlarmListener.class));
- verify(mAlarmManager.getAlarmManager(), never()).cancel(isNull(PendingIntent.class));
+ verify(mAlarmManager.getAlarmManager(), never()).cancel(nullable(PendingIntent.class));
verify(mAlarmManager.getAlarmManager(), never())
- .cancel(isNull(AlarmManager.OnAlarmListener.class));
+ .cancel(nullable(AlarmManager.OnAlarmListener.class));
}
/**