diff options
| -rw-r--r-- | Android.bp | 1 | ||||
| -rw-r--r-- | api/system-current.txt | 31 | ||||
| -rw-r--r-- | core/res/AndroidManifest.xml | 5 | ||||
| -rw-r--r-- | proto/src/wifi.proto | 11 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/IWifiManager.aidl | 6 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/IWifiUsabilityStatsListener.aidl | 41 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 88 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiUsabilityStatsEntry.aidl | 19 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java | 148 | ||||
| -rw-r--r-- | wifi/java/com/android/server/wifi/BaseWifiService.java | 12 | ||||
| -rw-r--r-- | wifi/tests/src/android/net/wifi/WifiManagerTest.java | 40 | ||||
| -rw-r--r-- | wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java | 104 |
12 files changed, 505 insertions, 1 deletions
diff --git a/Android.bp b/Android.bp index 8a2089f8c8e6..644cf0e7686d 100644 --- a/Android.bp +++ b/Android.bp @@ -637,6 +637,7 @@ java_defaults { "wifi/java/android/net/wifi/ISoftApCallback.aidl", "wifi/java/android/net/wifi/ITrafficStateCallback.aidl", "wifi/java/android/net/wifi/IWifiManager.aidl", + "wifi/java/android/net/wifi/IWifiUsabilityStatsListener.aidl", "wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl", "wifi/java/android/net/wifi/aware/IWifiAwareEventCallback.aidl", "wifi/java/android/net/wifi/aware/IWifiAwareMacAddressProvider.aidl", diff --git a/api/system-current.txt b/api/system-current.txt index 730cac64827e..2e8f69f51d07 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4610,6 +4610,7 @@ package android.net.wifi { } public class WifiManager { + method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void addWifiUsabilityStatsListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.WifiManager.WifiUsabilityStatsListener); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(android.net.wifi.WifiConfiguration, android.net.wifi.WifiManager.ActionListener); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void connect(int, android.net.wifi.WifiManager.ActionListener); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void disable(int, android.net.wifi.WifiManager.ActionListener); @@ -4625,6 +4626,7 @@ package android.net.wifi { method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public boolean isWifiApEnabled(); method public boolean isWifiScannerSupported(); method @RequiresPermission("android.permission.NETWORK_SETTINGS") public void registerNetworkRequestMatchCallback(@NonNull android.net.wifi.WifiManager.NetworkRequestMatchCallback, @Nullable android.os.Handler); + method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void removeWifiUsabilityStatsListener(@NonNull android.net.wifi.WifiManager.WifiUsabilityStatsListener); method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD, "android.permission.NETWORK_STACK"}) public void save(android.net.wifi.WifiConfiguration, android.net.wifi.WifiManager.ActionListener); method @RequiresPermission("android.permission.WIFI_SET_DEVICE_MOBILITY_STATE") public void setDeviceMobilityState(int); method @RequiresPermission(android.Manifest.permission.CHANGE_WIFI_STATE) public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration); @@ -4682,6 +4684,10 @@ package android.net.wifi { method public void select(@NonNull android.net.wifi.WifiConfiguration); } + public static interface WifiManager.WifiUsabilityStatsListener { + method public void onStatsUpdated(int, boolean, android.net.wifi.WifiUsabilityStatsEntry); + } + public class WifiNetworkConnectionStatistics implements android.os.Parcelable { ctor public WifiNetworkConnectionStatistics(int, int); ctor public WifiNetworkConnectionStatistics(); @@ -4811,6 +4817,31 @@ package android.net.wifi { field @Deprecated public int unchangedSampleSize; } + public final class WifiUsabilityStatsEntry implements android.os.Parcelable { + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.net.wifi.WifiUsabilityStatsEntry> CREATOR; + field public final int linkSpeedMbps; + field public final int rssi; + field public final long timeStampMs; + field public final long totalBackgroundScanTimeMs; + field public final long totalBeaconRx; + field public final long totalCcaBusyFreqTimeMs; + field public final long totalHotspot2ScanTimeMs; + field public final long totalNanScanTimeMs; + field public final long totalPnoScanTimeMs; + field public final long totalRadioOnFreqTimeMs; + field public final long totalRadioOnTimeMs; + field public final long totalRadioRxTimeMs; + field public final long totalRadioTxTimeMs; + field public final long totalRoamScanTimeMs; + field public final long totalRxSuccess; + field public final long totalScanTimeMs; + field public final long totalTxBad; + field public final long totalTxRetries; + field public final long totalTxSuccess; + } + } package android.net.wifi.aware { diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index c7cba62a4f69..f92df6a070c6 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1654,6 +1654,11 @@ <permission android:name="android.permission.WIFI_SET_DEVICE_MOBILITY_STATE" android:protectionLevel="signature|privileged" /> + <!-- #SystemApi @hide Allows privileged system APK to update Wifi usability stats and score. + <p>Not for use by third-party applications. --> + <permission android:name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE" + android:protectionLevel="signature|privileged" /> + <!-- ======================================= --> <!-- Permissions for short range, peripheral networks --> <!-- ======================================= --> diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto index 79b63bc55102..665691994f44 100644 --- a/proto/src/wifi.proto +++ b/proto/src/wifi.proto @@ -1800,6 +1800,17 @@ message WifiUsabilityStatsEntry { // Sequence number from external system app to framework optional int32 seq_num_to_framework = 19; + + // The total time CCA is on busy status on the current frequency in ms + // counted from the last radio chip reset + optional int64 total_cca_busy_freq_time_ms = 20; + + // The total radio on time of the current frequency from the last radio + // chip reset + optional int64 total_radio_on_freq_time_ms = 21; + + // The total number of beacons received from the last radio chip reset + optional int64 total_beacon_rx = 22; } message WifiUsabilityStats { diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 46c419130233..a0ce9dde3068 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -28,6 +28,7 @@ import android.net.wifi.IDppCallback; import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; +import android.net.wifi.IWifiUsabilityStatsListener; import android.net.wifi.PasspointManagementObjectDefinition; import android.net.wifi.ScanResult; import android.net.wifi.WifiActivityEnergyInfo; @@ -186,6 +187,10 @@ interface IWifiManager void unregisterSoftApCallback(int callbackIdentifier); + void addWifiUsabilityStatsListener(in IBinder binder, in IWifiUsabilityStatsListener listener, int listenerIdentifier); + + void removeWifiUsabilityStatsListener(int listenerIdentifier); + void registerTrafficStateCallback(in IBinder binder, in ITrafficStateCallback callback, int callbackIdentifier); void unregisterTrafficStateCallback(int callbackIdentifier); @@ -210,4 +215,3 @@ interface IWifiManager void stopDppSession(); } - diff --git a/wifi/java/android/net/wifi/IWifiUsabilityStatsListener.aidl b/wifi/java/android/net/wifi/IWifiUsabilityStatsListener.aidl new file mode 100644 index 000000000000..284ffaa18257 --- /dev/null +++ b/wifi/java/android/net/wifi/IWifiUsabilityStatsListener.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +import android.net.wifi.WifiUsabilityStatsEntry; + +/** + * Interface for Wi-Fi usability stats listener. + * + * @hide + */ +oneway interface IWifiUsabilityStatsListener +{ + /** + * Service to manager callback providing current Wi-Fi usability stats. + * + * @param seqNum The sequence number of stats, used to derive the timing of updated Wi-Fi + * usability statistics, set by framework and shall be incremented by one + * after each update. + * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of + * network stays the same or not relative to the last update of + * Wi-Fi usability stats. + * @param stats The updated Wi-Fi usability statistics. + */ + void onStatsUpdated(int seqNum, boolean isSameBssidAndFreq, + in WifiUsabilityStatsEntry stats); +} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 1fd45e72f1e8..084bd0936725 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -4777,4 +4777,92 @@ public class WifiManager { }); } } + + /** + * Interface for Wi-Fi usability statistics listener. Should be implemented by applications and + * set when calling {@link WifiManager#addWifiUsabilityStatsListener(Executor, + * WifiUsabilityStatsListener)}. + * + * @hide + */ + @SystemApi + public interface WifiUsabilityStatsListener { + /** + * Called when Wi-Fi usability statistics is updated. + * + * @param seqNum The sequence number of statistics, used to derive the timing of updated + * Wi-Fi usability statistics, set by framework and incremented by one after + * each update. + * @param isSameBssidAndFreq The flag to indicate whether the BSSID and the frequency of + * network stays the same or not relative to the last update of + * Wi-Fi usability stats. + * @param stats The updated Wi-Fi usability statistics. + */ + void onStatsUpdated(int seqNum, boolean isSameBssidAndFreq, + WifiUsabilityStatsEntry stats); + } + + /** + * Adds a listener for Wi-Fi usability statistics. See {@link WifiUsabilityStatsListener}. + * Multiple listeners can be added. Callers will be invoked periodically by framework to + * inform clients about the current Wi-Fi usability statistics. Callers can remove a previously + * added listener using {@link removeWifiUsabilityStatsListener}. + * + * @param executor The executor on which callback will be invoked. + * @param listener Listener for Wifi usability statistics. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) + public void addWifiUsabilityStatsListener(@NonNull @CallbackExecutor Executor executor, + @NonNull WifiUsabilityStatsListener listener) { + if (executor == null) throw new IllegalArgumentException("executor cannot be null"); + if (listener == null) throw new IllegalArgumentException("listener cannot be null"); + if (mVerboseLoggingEnabled) { + Log.v(TAG, "addWifiUsabilityStatsListener: listener=" + listener); + } + try { + mService.addWifiUsabilityStatsListener(new Binder(), + new IWifiUsabilityStatsListener.Stub() { + @Override + public void onStatsUpdated(int seqNum, boolean isSameBssidAndFreq, + WifiUsabilityStatsEntry stats) { + if (mVerboseLoggingEnabled) { + Log.v(TAG, "WifiUsabilityStatsListener: onStatsUpdated: seqNum=" + + seqNum); + } + Binder.withCleanCallingIdentity(() -> + executor.execute(() -> listener.onStatsUpdated(seqNum, + isSameBssidAndFreq, stats))); + } + }, + listener.hashCode() + ); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Allow callers to remove a previously registered listener. After calling this method, + * applications will no longer receive Wi-Fi usability statistics. + * + * @param listener Listener to remove the Wi-Fi usability statistics. + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE) + public void removeWifiUsabilityStatsListener(@NonNull WifiUsabilityStatsListener listener) { + if (listener == null) throw new IllegalArgumentException("listener cannot be null"); + if (mVerboseLoggingEnabled) { + Log.v(TAG, "removeWifiUsabilityStatsListener: listener=" + listener); + } + try { + mService.removeWifiUsabilityStatsListener(listener.hashCode()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } } diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.aidl b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.aidl new file mode 100644 index 000000000000..839af54b81ba --- /dev/null +++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +parcelable WifiUsabilityStatsEntry; diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java new file mode 100644 index 000000000000..c796e29e4e1a --- /dev/null +++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * This class makes a subset of + * com.android.server.wifi.nano.WifiMetricsProto.WifiUsabilityStatsEntry parcelable. + * + * @hide + */ +@SystemApi +public final class WifiUsabilityStatsEntry implements Parcelable { + /** Absolute milliseconds from device boot when these stats were sampled */ + public final long timeStampMs; + /** The RSSI (in dBm) at the sample time */ + public final int rssi; + /** Link speed at the sample time in Mbps */ + public final int linkSpeedMbps; + /** The total number of tx success counted from the last radio chip reset */ + public final long totalTxSuccess; + /** The total number of MPDU data packet retries counted from the last radio chip reset */ + public final long totalTxRetries; + /** The total number of tx bad counted from the last radio chip reset */ + public final long totalTxBad; + /** The total number of rx success counted from the last radio chip reset */ + public final long totalRxSuccess; + /** The total time the wifi radio is on in ms counted from the last radio chip reset */ + public final long totalRadioOnTimeMs; + /** The total time the wifi radio is doing tx in ms counted from the last radio chip reset */ + public final long totalRadioTxTimeMs; + /** The total time the wifi radio is doing rx in ms counted from the last radio chip reset */ + public final long totalRadioRxTimeMs; + /** The total time spent on all types of scans in ms counted from the last radio chip reset */ + public final long totalScanTimeMs; + /** The total time spent on nan scans in ms counted from the last radio chip reset */ + public final long totalNanScanTimeMs; + /** The total time spent on background scans in ms counted from the last radio chip reset */ + public final long totalBackgroundScanTimeMs; + /** The total time spent on roam scans in ms counted from the last radio chip reset */ + public final long totalRoamScanTimeMs; + /** The total time spent on pno scans in ms counted from the last radio chip reset */ + public final long totalPnoScanTimeMs; + /** The total time spent on hotspot2.0 scans and GAS exchange in ms counted from the last radio + * chip reset */ + public final long totalHotspot2ScanTimeMs; + /** The total time CCA is on busy status on the current frequency in ms counted from the last + * radio chip reset */ + public final long totalCcaBusyFreqTimeMs; + /** The total radio on time of the current frequency from the last radio chip reset */ + public final long totalRadioOnFreqTimeMs; + /** The total number of beacons received from the last radio chip reset */ + public final long totalBeaconRx; + + /** Constructor function {@hide} */ + public WifiUsabilityStatsEntry(long timeStampMs, int rssi, + int linkSpeedMbps, long totalTxSuccess, long totalTxRetries, + long totalTxBad, long totalRxSuccess, long totalRadioOnTimeMs, + long totalRadioTxTimeMs, long totalRadioRxTimeMs, long totalScanTimeMs, + long totalNanScanTimeMs, long totalBackgroundScanTimeMs, long totalRoamScanTimeMs, + long totalPnoScanTimeMs, long totalHotspot2ScanTimeMs, long totalCcaBusyFreqTimeMs, + long totalRadioOnFreqTimeMs, long totalBeaconRx) { + this.timeStampMs = timeStampMs; + this.rssi = rssi; + this.linkSpeedMbps = linkSpeedMbps; + this.totalTxSuccess = totalTxSuccess; + this.totalTxRetries = totalTxRetries; + this.totalTxBad = totalTxBad; + this.totalRxSuccess = totalRxSuccess; + this.totalRadioOnTimeMs = totalRadioOnTimeMs; + this.totalRadioTxTimeMs = totalRadioTxTimeMs; + this.totalRadioRxTimeMs = totalRadioRxTimeMs; + this.totalScanTimeMs = totalScanTimeMs; + this.totalNanScanTimeMs = totalNanScanTimeMs; + this.totalBackgroundScanTimeMs = totalBackgroundScanTimeMs; + this.totalRoamScanTimeMs = totalRoamScanTimeMs; + this.totalPnoScanTimeMs = totalPnoScanTimeMs; + this.totalHotspot2ScanTimeMs = totalHotspot2ScanTimeMs; + this.totalCcaBusyFreqTimeMs = totalCcaBusyFreqTimeMs; + this.totalRadioOnFreqTimeMs = totalRadioOnFreqTimeMs; + this.totalBeaconRx = totalBeaconRx; + } + + /** Implement the Parcelable interface */ + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(timeStampMs); + dest.writeInt(rssi); + dest.writeInt(linkSpeedMbps); + dest.writeLong(totalTxSuccess); + dest.writeLong(totalTxRetries); + dest.writeLong(totalTxBad); + dest.writeLong(totalRxSuccess); + dest.writeLong(totalRadioOnTimeMs); + dest.writeLong(totalRadioTxTimeMs); + dest.writeLong(totalRadioRxTimeMs); + dest.writeLong(totalScanTimeMs); + dest.writeLong(totalNanScanTimeMs); + dest.writeLong(totalBackgroundScanTimeMs); + dest.writeLong(totalRoamScanTimeMs); + dest.writeLong(totalPnoScanTimeMs); + dest.writeLong(totalHotspot2ScanTimeMs); + dest.writeLong(totalCcaBusyFreqTimeMs); + dest.writeLong(totalRadioOnFreqTimeMs); + dest.writeLong(totalBeaconRx); + } + + /** Implement the Parcelable interface */ + public static final Creator<WifiUsabilityStatsEntry> CREATOR = + new Creator<WifiUsabilityStatsEntry>() { + public WifiUsabilityStatsEntry createFromParcel(Parcel in) { + return new WifiUsabilityStatsEntry( + in.readLong(), in.readInt(), + in.readInt(), in.readLong(), in.readLong(), + in.readLong(), in.readLong(), in.readLong(), + in.readLong(), in.readLong(), in.readLong(), + in.readLong(), in.readLong(), in.readLong(), + in.readLong(), in.readLong(), in.readLong(), + in.readLong(), in.readLong() + ); + } + + public WifiUsabilityStatsEntry[] newArray(int size) { + return new WifiUsabilityStatsEntry[size]; + } + }; +} diff --git a/wifi/java/com/android/server/wifi/BaseWifiService.java b/wifi/java/com/android/server/wifi/BaseWifiService.java index b3ac9f15eb9a..226c7c48a3b3 100644 --- a/wifi/java/com/android/server/wifi/BaseWifiService.java +++ b/wifi/java/com/android/server/wifi/BaseWifiService.java @@ -26,6 +26,7 @@ import android.net.wifi.INetworkRequestMatchCallback; import android.net.wifi.ISoftApCallback; import android.net.wifi.ITrafficStateCallback; import android.net.wifi.IWifiManager; +import android.net.wifi.IWifiUsabilityStatsListener; import android.net.wifi.ScanResult; import android.net.wifi.WifiActivityEnergyInfo; import android.net.wifi.WifiConfiguration; @@ -464,4 +465,15 @@ public class BaseWifiService extends IWifiManager.Stub { public void stopDppSession() throws RemoteException { throw new UnsupportedOperationException(); } + + @Override + public void addWifiUsabilityStatsListener( + IBinder binder, IWifiUsabilityStatsListener listener, int listenerIdentifier) { + throw new UnsupportedOperationException(); + } + + @Override + public void removeWifiUsabilityStatsListener(int listenerIdentifier) { + throw new UnsupportedOperationException(); + } } diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java index 4fbef5a8493d..5c2f626a24cc 100644 --- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java +++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java @@ -61,6 +61,7 @@ import android.net.wifi.WifiManager.NetworkRequestMatchCallback; import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.net.wifi.WifiManager.SoftApCallback; import android.net.wifi.WifiManager.TrafficStateCallback; +import android.net.wifi.WifiManager.WifiUsabilityStatsListener; import android.os.Handler; import android.os.IBinder; import android.os.Message; @@ -80,6 +81,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Executor; /** * Unit tests for {@link android.net.wifi.WifiManager}. @@ -103,7 +105,9 @@ public class WifiManagerTest { @Mock SoftApCallback mSoftApCallback; @Mock TrafficStateCallback mTrafficStateCallback; @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback; + @Mock WifiUsabilityStatsListener mWifiUsabilityStatsListener; + private Executor mExecutor; private Handler mHandler; private TestLooper mLooper; private WifiManager mWifiManager; @@ -1342,4 +1346,40 @@ i * Verify that a call to cancel WPS immediately returns a failure. assertArrayEquals(TEST_MAC_ADDRESSES, mWifiManager.getFactoryMacAddresses()); verify(mWifiService).getFactoryMacAddresses(); } + + /** + * Verify the call to addWifiUsabilityStatsListener goes to WifiServiceImpl. + */ + @Test + public void addWifiUsabilityStatsListeneroesToWifiServiceImpl() throws Exception { + mExecutor = new SynchronousExecutor(); + mWifiManager.addWifiUsabilityStatsListener(mExecutor, mWifiUsabilityStatsListener); + verify(mWifiService).addWifiUsabilityStatsListener(any(IBinder.class), + any(IWifiUsabilityStatsListener.Stub.class), anyInt()); + } + + /** + * Verify the call to removeWifiUsabilityStatsListener goes to WifiServiceImpl. + */ + @Test + public void removeWifiUsabilityListenerGoesToWifiServiceImpl() throws Exception { + ArgumentCaptor<Integer> listenerIdentifier = ArgumentCaptor.forClass(Integer.class); + mExecutor = new SynchronousExecutor(); + mWifiManager.addWifiUsabilityStatsListener(mExecutor, mWifiUsabilityStatsListener); + verify(mWifiService).addWifiUsabilityStatsListener(any(IBinder.class), + any(IWifiUsabilityStatsListener.Stub.class), listenerIdentifier.capture()); + + mWifiManager.removeWifiUsabilityStatsListener(mWifiUsabilityStatsListener); + verify(mWifiService).removeWifiUsabilityStatsListener( + eq((int) listenerIdentifier.getValue())); + } + + /** + * Defined for testing purpose. + */ + class SynchronousExecutor implements Executor { + public void execute(Runnable r) { + r.run(); + } + } } diff --git a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java new file mode 100644 index 000000000000..a947b5568a16 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.validateMockitoUsage; + +import android.os.Parcel; + +import androidx.test.filters.SmallTest; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.MockitoAnnotations; + + +/** + * Unit tests for {@link android.net.wifi.WifiUsabilityStatsEntry}. + */ +@SmallTest +public class WifiUsabilityStatsEntryTest { + + /** + * Setup before tests. + */ + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + /** + * Clean up after tests. + */ + @After + public void cleanup() { + validateMockitoUsage(); + } + + /** + * Verify parcel read/write for Wifi usability stats result. + */ + @Test + public void verifyStatsResultWriteAndThenRead() throws Exception { + WifiUsabilityStatsEntry writeResult = createResult(); + WifiUsabilityStatsEntry readResult = parcelWriteRead(writeResult); + assertWifiUsabilityStatsEntryEquals(writeResult, readResult); + } + + /** + * Write the provided {@link WifiUsabilityStatsEntry} to a parcel and deserialize it. + */ + private static WifiUsabilityStatsEntry parcelWriteRead( + WifiUsabilityStatsEntry writeResult) throws Exception { + Parcel parcel = Parcel.obtain(); + writeResult.writeToParcel(parcel, 0); + parcel.setDataPosition(0); // Rewind data position back to the beginning for read. + return WifiUsabilityStatsEntry.CREATOR.createFromParcel(parcel); + } + + private static WifiUsabilityStatsEntry createResult() { + return new WifiUsabilityStatsEntry( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 + ); + } + + private static void assertWifiUsabilityStatsEntryEquals( + WifiUsabilityStatsEntry expected, + WifiUsabilityStatsEntry actual) { + assertEquals(expected.timeStampMs, actual.timeStampMs); + assertEquals(expected.rssi, actual.rssi); + assertEquals(expected.linkSpeedMbps, actual.linkSpeedMbps); + assertEquals(expected.totalTxSuccess, actual.totalTxSuccess); + assertEquals(expected.totalTxRetries, actual.totalTxRetries); + assertEquals(expected.totalTxBad, actual.totalTxBad); + assertEquals(expected.totalRxSuccess, actual.totalRxSuccess); + assertEquals(expected.totalRadioOnTimeMs, actual.totalRadioOnTimeMs); + assertEquals(expected.totalRadioTxTimeMs, actual.totalRadioTxTimeMs); + assertEquals(expected.totalRadioRxTimeMs, actual.totalRadioRxTimeMs); + assertEquals(expected.totalScanTimeMs, actual.totalScanTimeMs); + assertEquals(expected.totalNanScanTimeMs, actual.totalNanScanTimeMs); + assertEquals(expected.totalBackgroundScanTimeMs, actual.totalBackgroundScanTimeMs); + assertEquals(expected.totalRoamScanTimeMs, actual.totalRoamScanTimeMs); + assertEquals(expected.totalPnoScanTimeMs, actual.totalPnoScanTimeMs); + assertEquals(expected.totalHotspot2ScanTimeMs, actual.totalHotspot2ScanTimeMs); + assertEquals(expected.totalCcaBusyFreqTimeMs, actual.totalCcaBusyFreqTimeMs); + assertEquals(expected.totalRadioOnFreqTimeMs, actual.totalRadioOnFreqTimeMs); + assertEquals(expected.totalBeaconRx, actual.totalBeaconRx); + } +} |