Merge changes Id928678b,Ic55dbbe6 into rvc-dev
* changes: ConnectedNetworkScorerTest: Add test for connected network scorer ConnectedNetworkScorerTest: Add tests for wifi usability stats
This commit is contained in:
committed by
Android (Google) Code Review
commit
415461e1c9
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.cts;
|
||||
|
||||
import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_FAILURE;
|
||||
import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_NO_PROBE;
|
||||
import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_SUCCESS;
|
||||
import static android.net.wifi.WifiUsabilityStatsEntry.PROBE_STATUS_UNKNOWN;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.app.UiAutomation;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.WifiUsabilityStatsEntry;
|
||||
import android.support.test.uiautomator.UiDevice;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
|
||||
import com.android.compatibility.common.util.PollingCheck;
|
||||
import com.android.compatibility.common.util.ShellIdentityUtils;
|
||||
import com.android.compatibility.common.util.SystemUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ConnectedNetworkScorerTest extends AndroidTestCase {
|
||||
private WifiManager mWifiManager;
|
||||
private UiDevice mUiDevice;
|
||||
private boolean mWasVerboseLoggingEnabled;
|
||||
|
||||
private static final int DURATION = 10_000;
|
||||
private static final int DURATION_SCREEN_TOGGLE = 2000;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
if (!WifiFeature.isWifiSupported(getContext())) {
|
||||
// skip the test if WiFi is not supported
|
||||
return;
|
||||
}
|
||||
mWifiManager = getContext().getSystemService(WifiManager.class);
|
||||
assertThat(mWifiManager).isNotNull();
|
||||
|
||||
// turn on verbose logging for tests
|
||||
mWasVerboseLoggingEnabled = ShellIdentityUtils.invokeWithShellPermissions(
|
||||
() -> mWifiManager.isVerboseLoggingEnabled());
|
||||
ShellIdentityUtils.invokeWithShellPermissions(
|
||||
() -> mWifiManager.setVerboseLoggingEnabled(true));
|
||||
|
||||
if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true);
|
||||
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
turnScreenOn();
|
||||
PollingCheck.check("Wifi not enabled", DURATION, () -> mWifiManager.isWifiEnabled());
|
||||
List<WifiConfiguration> savedNetworks = ShellIdentityUtils.invokeWithShellPermissions(
|
||||
() -> mWifiManager.getConfiguredNetworks());
|
||||
assertFalse("Need at least one saved network", savedNetworks.isEmpty());
|
||||
// Wait for wifi is to be connected
|
||||
PollingCheck.check(
|
||||
"Wifi not connected",
|
||||
DURATION,
|
||||
() -> mWifiManager.getConnectionInfo().getNetworkId() != -1);
|
||||
assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isNotEqualTo(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (!WifiFeature.isWifiSupported(getContext())) {
|
||||
// skip the test if WiFi is not supported
|
||||
super.tearDown();
|
||||
return;
|
||||
}
|
||||
if (!mWifiManager.isWifiEnabled()) setWifiEnabled(true);
|
||||
turnScreenOff();
|
||||
ShellIdentityUtils.invokeWithShellPermissions(
|
||||
() -> mWifiManager.setVerboseLoggingEnabled(mWasVerboseLoggingEnabled));
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
private void setWifiEnabled(boolean enable) throws Exception {
|
||||
// now trigger the change using shell commands.
|
||||
SystemUtil.runShellCommand("svc wifi " + (enable ? "enable" : "disable"));
|
||||
}
|
||||
|
||||
private void turnScreenOn() throws Exception {
|
||||
mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
|
||||
mUiDevice.executeShellCommand("wm dismiss-keyguard");
|
||||
// Since the screen on/off intent is ordered, they will not be sent right now.
|
||||
Thread.sleep(DURATION_SCREEN_TOGGLE);
|
||||
}
|
||||
|
||||
private void turnScreenOff() throws Exception {
|
||||
mUiDevice.executeShellCommand("input keyevent KEYCODE_SLEEP");
|
||||
}
|
||||
|
||||
private static class TestUsabilityStatsListener implements
|
||||
WifiManager.OnWifiUsabilityStatsListener {
|
||||
private final CountDownLatch mCountDownLatch;
|
||||
public int seqNum;
|
||||
public boolean isSameBssidAndFre;
|
||||
public WifiUsabilityStatsEntry statsEntry;
|
||||
|
||||
TestUsabilityStatsListener(CountDownLatch countDownLatch) {
|
||||
mCountDownLatch = countDownLatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWifiUsabilityStats(int seqNum, boolean isSameBssidAndFreq,
|
||||
WifiUsabilityStatsEntry statsEntry) {
|
||||
this.seqNum = seqNum;
|
||||
this.isSameBssidAndFre = isSameBssidAndFreq;
|
||||
this.statsEntry = statsEntry;
|
||||
mCountDownLatch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@link android.net.wifi.WifiUsabilityStatsEntry} retrieved from
|
||||
* {@link WifiManager.OnWifiUsabilityStatsListener}.
|
||||
*/
|
||||
public void testWifiUsabilityStatsEntry() throws Exception {
|
||||
if (!WifiFeature.isWifiSupported(getContext())) {
|
||||
// skip the test if WiFi is not supported
|
||||
return;
|
||||
}
|
||||
CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
|
||||
TestUsabilityStatsListener usabilityStatsListener =
|
||||
new TestUsabilityStatsListener(countDownLatch);
|
||||
try {
|
||||
uiAutomation.adoptShellPermissionIdentity();
|
||||
mWifiManager.addOnWifiUsabilityStatsListener(
|
||||
Executors.newSingleThreadExecutor(), usabilityStatsListener);
|
||||
// Wait for new usability stats (while connected & screen on this is triggered
|
||||
// by platform periodically).
|
||||
assertThat(countDownLatch.await(DURATION, TimeUnit.MILLISECONDS)).isTrue();
|
||||
|
||||
assertThat(usabilityStatsListener.statsEntry).isNotNull();
|
||||
WifiUsabilityStatsEntry statsEntry = usabilityStatsListener.statsEntry;
|
||||
|
||||
assertThat(statsEntry.getTimeStampMillis()).isGreaterThan(0L);
|
||||
assertThat(statsEntry.getRssi()).isLessThan(0);
|
||||
assertThat(statsEntry.getLinkSpeedMbps()).isGreaterThan(0);
|
||||
assertThat(statsEntry.getTotalTxSuccess()).isGreaterThan(0L);
|
||||
assertThat(statsEntry.getTotalTxRetries()).isAtLeast(0L);
|
||||
assertThat(statsEntry.getTotalTxBad()).isAtLeast(0L);
|
||||
assertThat(statsEntry.getTotalRxSuccess()).isAtLeast(0L);
|
||||
assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L);
|
||||
assertThat(statsEntry.getTotalRadioTxTimeMillis()).isGreaterThan(0L);
|
||||
assertThat(statsEntry.getTotalRadioRxTimeMillis()).isGreaterThan(0L);
|
||||
assertThat(statsEntry.getTotalScanTimeMillis()).isGreaterThan(0L);
|
||||
assertThat(statsEntry.getTotalNanScanTimeMillis()).isAtLeast(0L);
|
||||
assertThat(statsEntry.getTotalBackgroundScanTimeMillis()).isAtLeast(0L);
|
||||
assertThat(statsEntry.getTotalRoamScanTimeMillis()).isAtLeast(0L);
|
||||
assertThat(statsEntry.getTotalPnoScanTimeMillis()).isAtLeast(0L);
|
||||
assertThat(statsEntry.getTotalHotspot2ScanTimeMillis()).isAtLeast(0L);
|
||||
assertThat(statsEntry.getTotalCcaBusyFreqTimeMillis()).isAtLeast(0L);
|
||||
assertThat(statsEntry.getTotalRadioOnTimeMillis()).isGreaterThan(0L);
|
||||
assertThat(statsEntry.getTotalBeaconRx()).isGreaterThan(0L);
|
||||
assertThat(statsEntry.getProbeStatusSinceLastUpdate())
|
||||
.isAnyOf(PROBE_STATUS_SUCCESS,
|
||||
PROBE_STATUS_FAILURE,
|
||||
PROBE_STATUS_NO_PROBE,
|
||||
PROBE_STATUS_UNKNOWN);
|
||||
// -1 is default value for some of these fields if they're not available.
|
||||
assertThat(statsEntry.getProbeElapsedTimeSinceLastUpdateMillis()).isAtLeast(-1);
|
||||
assertThat(statsEntry.getProbeMcsRateSinceLastUpdate()).isAtLeast(-1);
|
||||
assertThat(statsEntry.getRxLinkSpeedMbps()).isAtLeast(-1);
|
||||
// no longer populated, return default value.
|
||||
assertThat(statsEntry.getCellularDataNetworkType())
|
||||
.isAnyOf(TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
TelephonyManager.NETWORK_TYPE_GPRS,
|
||||
TelephonyManager.NETWORK_TYPE_EDGE,
|
||||
TelephonyManager.NETWORK_TYPE_UMTS,
|
||||
TelephonyManager.NETWORK_TYPE_CDMA,
|
||||
TelephonyManager.NETWORK_TYPE_EVDO_0,
|
||||
TelephonyManager.NETWORK_TYPE_EVDO_A,
|
||||
TelephonyManager.NETWORK_TYPE_1xRTT,
|
||||
TelephonyManager.NETWORK_TYPE_HSDPA,
|
||||
TelephonyManager.NETWORK_TYPE_HSUPA,
|
||||
TelephonyManager.NETWORK_TYPE_HSPA,
|
||||
TelephonyManager.NETWORK_TYPE_IDEN,
|
||||
TelephonyManager.NETWORK_TYPE_EVDO_B,
|
||||
TelephonyManager.NETWORK_TYPE_LTE,
|
||||
TelephonyManager.NETWORK_TYPE_EHRPD,
|
||||
TelephonyManager.NETWORK_TYPE_HSPAP,
|
||||
TelephonyManager.NETWORK_TYPE_GSM,
|
||||
TelephonyManager.NETWORK_TYPE_TD_SCDMA,
|
||||
TelephonyManager.NETWORK_TYPE_IWLAN,
|
||||
TelephonyManager.NETWORK_TYPE_NR);
|
||||
assertThat(statsEntry.getCellularSignalStrengthDbm()).isAtMost(0);
|
||||
assertThat(statsEntry.getCellularSignalStrengthDb()).isAtMost(0);
|
||||
assertThat(statsEntry.isSameRegisteredCell()).isFalse();
|
||||
} finally {
|
||||
mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener);
|
||||
uiAutomation.dropShellPermissionIdentity();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@link android.net.wifi.WifiManager#updateWifiUsabilityScore(int, int, int)}
|
||||
*/
|
||||
public void testUpdateWifiUsabilityScore() throws Exception {
|
||||
if (!WifiFeature.isWifiSupported(getContext())) {
|
||||
// skip the test if WiFi is not supported
|
||||
return;
|
||||
}
|
||||
UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
|
||||
try {
|
||||
uiAutomation.adoptShellPermissionIdentity();
|
||||
// update scoring with dummy values.
|
||||
mWifiManager.updateWifiUsabilityScore(0, 50, 50);
|
||||
} finally {
|
||||
uiAutomation.dropShellPermissionIdentity();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestConnectedNetworkScorer implements
|
||||
WifiManager.WifiConnectedNetworkScorer {
|
||||
private CountDownLatch mCountDownLatch;
|
||||
public int startSessionId;
|
||||
public int stopSessionId;
|
||||
public WifiManager.ScoreUpdateObserver scoreUpdateObserver;
|
||||
|
||||
TestConnectedNetworkScorer(CountDownLatch countDownLatch) {
|
||||
mCountDownLatch = countDownLatch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(int sessionId) {
|
||||
synchronized (mCountDownLatch) {
|
||||
this.startSessionId = sessionId;
|
||||
mCountDownLatch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(int sessionId) {
|
||||
synchronized (mCountDownLatch) {
|
||||
this.stopSessionId = sessionId;
|
||||
mCountDownLatch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetScoreUpdateObserver(WifiManager.ScoreUpdateObserver observerImpl) {
|
||||
this.scoreUpdateObserver = observerImpl;
|
||||
}
|
||||
|
||||
public void resetCountDownLatch(CountDownLatch countDownLatch) {
|
||||
synchronized (mCountDownLatch) {
|
||||
mCountDownLatch = countDownLatch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@link android.net.wifi.WifiConnectedNetworkScorer} interface.
|
||||
*
|
||||
* Note: We could write more interesting test cases (if the device has a mobile connection), but
|
||||
* that would make the test flaky. The default network/route selection on the device is not just
|
||||
* controlled by the wifi scorer input, but also based on params which are controlled by
|
||||
* other parts of the platform (likely in connectivity service) and hence will behave
|
||||
* differently on OEM devices.
|
||||
*/
|
||||
public void testSetWifiConnectedNetworkScorer() throws Exception {
|
||||
if (!WifiFeature.isWifiSupported(getContext())) {
|
||||
// skip the test if WiFi is not supported
|
||||
return;
|
||||
}
|
||||
CountDownLatch countDownLatchScorer = new CountDownLatch(1);
|
||||
CountDownLatch countDownLatchUsabilityStats = new CountDownLatch(1);
|
||||
UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
|
||||
TestConnectedNetworkScorer connectedNetworkScorer =
|
||||
new TestConnectedNetworkScorer(countDownLatchScorer);
|
||||
TestUsabilityStatsListener usabilityStatsListener =
|
||||
new TestUsabilityStatsListener(countDownLatchUsabilityStats);
|
||||
try {
|
||||
uiAutomation.adoptShellPermissionIdentity();
|
||||
mWifiManager.setWifiConnectedNetworkScorer(
|
||||
Executors.newSingleThreadExecutor(), connectedNetworkScorer);
|
||||
// Since we're already connected, wait for onStart to be invoked.
|
||||
assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue();
|
||||
|
||||
assertThat(connectedNetworkScorer.startSessionId).isAtLeast(0);
|
||||
assertThat(connectedNetworkScorer.scoreUpdateObserver).isNotNull();
|
||||
WifiManager.ScoreUpdateObserver scoreUpdateObserver =
|
||||
connectedNetworkScorer.scoreUpdateObserver;
|
||||
|
||||
// Now trigger a dummy score update.
|
||||
scoreUpdateObserver.notifyScoreUpdate(connectedNetworkScorer.startSessionId, 50);
|
||||
|
||||
// Register the usability listener
|
||||
mWifiManager.addOnWifiUsabilityStatsListener(
|
||||
Executors.newSingleThreadExecutor(), usabilityStatsListener);
|
||||
// Trigger a usability stats update.
|
||||
scoreUpdateObserver.triggerUpdateOfWifiUsabilityStats(
|
||||
connectedNetworkScorer.startSessionId);
|
||||
// Ensure that we got the stats update callback.
|
||||
assertThat(countDownLatchUsabilityStats.await(DURATION, TimeUnit.MILLISECONDS))
|
||||
.isTrue();
|
||||
assertThat(usabilityStatsListener.seqNum).isAtLeast(0);
|
||||
|
||||
// Reset the scorer countdown latch for onStop
|
||||
countDownLatchScorer = new CountDownLatch(1);
|
||||
connectedNetworkScorer.resetCountDownLatch(countDownLatchScorer);
|
||||
// Now disconnect from the network.
|
||||
mWifiManager.disconnect();
|
||||
// Wait for it to be disconnected.
|
||||
PollingCheck.check(
|
||||
"Wifi not disconnected",
|
||||
DURATION,
|
||||
() -> mWifiManager.getConnectionInfo().getNetworkId() == -1);
|
||||
assertThat(mWifiManager.getConnectionInfo().getNetworkId()).isEqualTo(-1);
|
||||
|
||||
// Wait for stop to be invoked and ensure that the session id matches.
|
||||
assertThat(countDownLatchScorer.await(DURATION, TimeUnit.MILLISECONDS)).isTrue();
|
||||
assertThat(connectedNetworkScorer.stopSessionId)
|
||||
.isEqualTo(connectedNetworkScorer.startSessionId);
|
||||
} finally {
|
||||
mWifiManager.removeOnWifiUsabilityStatsListener(usabilityStatsListener);
|
||||
mWifiManager.clearWifiConnectedNetworkScorer();
|
||||
uiAutomation.dropShellPermissionIdentity();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user