diff options
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)); } /** |