summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/WifiScoreReport.java170
-rw-r--r--tests/wifitests/Android.bp6
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java74
3 files changed, 161 insertions, 89 deletions
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index ad3c1ca27..5561a9104 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -56,11 +56,10 @@ public class WifiScoreReport {
// Cache of the last score
private int mScore = ConnectedScore.WIFI_MAX_SCORE;
- private int mSessionId = INVALID_SESSION_ID;
private final ScoringParams mScoringParams;
private final Clock mClock;
- private int mSessionNumber = 0;
+ private int mSessionNumber = 0; // not to be confused with sessionid, this just counts resets
private String mInterfaceName;
private final BssidBlocklistMonitor mBssidBlocklistMonitor;
private long mLastScoreBreachLowTimeMillis = -1;
@@ -75,16 +74,19 @@ public class WifiScoreReport {
WifiThreadRunner mWifiThreadRunner;
/**
- * Callback proxy. See {@link WifiManager#ScoreUpdateObserver}.
+ * Callback proxy. See {@link android.net.wifi.WifiManager.ScoreUpdateObserver}.
*/
private class ScoreUpdateObserverProxy extends IScoreUpdateObserver.Stub {
@Override
public void notifyScoreUpdate(int sessionId, int score) {
mWifiThreadRunner.post(() -> {
- if (mWifiConnectedNetworkScorerHolder == null) {
- return;
- }
- if (!validateSessionId(sessionId)) {
+ if (mWifiConnectedNetworkScorerHolder == null
+ || sessionId == INVALID_SESSION_ID
+ || sessionId != getCurrentSessionId()) {
+ Log.w(TAG, "Ignoring stale/invalid external score"
+ + " sessionId=" + sessionId
+ + " currentSessionId=" + getCurrentSessionId()
+ + " score=" + score);
return;
}
if (mNetworkAgent != null) {
@@ -108,21 +110,20 @@ public class WifiScoreReport {
@Override
public void triggerUpdateOfWifiUsabilityStats(int sessionId) {
mWifiThreadRunner.post(() -> {
- if (mWifiConnectedNetworkScorerHolder == null) {
- return;
- }
- if (!validateSessionId(sessionId)) {
+ if (mWifiConnectedNetworkScorerHolder == null
+ || sessionId == INVALID_SESSION_ID
+ || sessionId != getCurrentSessionId()
+ || mInterfaceName == null) {
+ Log.w(TAG, "Ignoring triggerUpdateOfWifiUsabilityStats"
+ + " sessionId=" + sessionId
+ + " currentSessionId=" + getCurrentSessionId()
+ + " interfaceName=" + mInterfaceName);
return;
}
- if (mInterfaceName == null) {
- Log.e(TAG, "getWifiLinkLayerStats called without an interface");
- return;
- }
-
WifiLinkLayerStats stats = mWifiNative.getWifiLinkLayerStats(mInterfaceName);
// update mWifiInfo
- // TODO: b/149583741 Better coordinate this class and ClientModeImpl to remove
+ // TODO(b/153075963): Better coordinate this class and ClientModeImpl to remove
// redundant codes below and in ClientModeImpl#fetchRssiLinkSpeedAndFrequencyNative.
WifiNl80211Manager.SignalPollResult pollResult =
mWifiNative.signalPoll(mInterfaceName);
@@ -159,34 +160,19 @@ public class WifiScoreReport {
}
}
+ // TODO(b/153075963): This should not be plumbed through WifiMetrics
mWifiMetrics.updateWifiUsabilityStatsEntries(mWifiInfo, stats);
});
}
-
- private boolean validateSessionId(int sessionId) {
- if (sessionId == INVALID_SESSION_ID) {
- Log.e(TAG, "Called with invalid ID");
- return false;
- }
- if (mSessionId == INVALID_SESSION_ID) {
- if (mVerboseLoggingEnabled) Log.d(TAG, "Called with score after session reset");
- return false;
- }
- if (sessionId != mSessionId) {
- // This indicates a more serious timing issue
- Log.w(TAG, "Called with old session ID");
- return false;
- }
- return true;
- }
}
/**
- * Container for storing info about external scorer and tracks its death.
+ * Container for storing info about external scorer and tracking its death.
*/
private final class WifiConnectedNetworkScorerHolder implements IBinder.DeathRecipient {
private final IBinder mBinder;
private final IWifiConnectedNetworkScorer mScorer;
+ private int mSessionId = INVALID_SESSION_ID;
WifiConnectedNetworkScorerHolder(IBinder binder, IWifiConnectedNetworkScorer scorer) {
mBinder = binder;
@@ -209,10 +195,9 @@ public class WifiScoreReport {
/**
* App hosting the binder has died.
*/
+ @Override
public void binderDied() {
- mWifiThreadRunner.post(() -> {
- revertAospConnectedScorer();
- });
+ mWifiThreadRunner.post(() -> revertToDefaultConnectedScorer());
}
/**
@@ -223,10 +208,39 @@ public class WifiScoreReport {
}
/**
- * Get Wi-Fi connected network scorer
+ * Starts a new scoring session.
*/
- public IWifiConnectedNetworkScorer getScorer() {
- return mScorer;
+ public void startSession(int sessionId) {
+ if (sessionId == INVALID_SESSION_ID) {
+ throw new IllegalArgumentException();
+ }
+ if (mSessionId != INVALID_SESSION_ID) {
+ // This is not expected to happen, log if it does
+ Log.e(TAG, "Stopping session " + mSessionId + " before starting " + sessionId);
+ stopSession();
+ }
+ // Bail now if the scorer has gone away
+ if (this != mWifiConnectedNetworkScorerHolder) {
+ return;
+ }
+ mSessionId = sessionId;
+ try {
+ mScorer.onStart(sessionId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to start Wifi connected network scorer " + this, e);
+ revertToDefaultConnectedScorer();
+ }
+ }
+ public void stopSession() {
+ final int sessionId = mSessionId;
+ if (sessionId == INVALID_SESSION_ID) return;
+ mSessionId = INVALID_SESSION_ID;
+ try {
+ mScorer.onStop(sessionId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to stop Wifi connected network scorer " + this, e);
+ revertToDefaultConnectedScorer();
+ }
}
}
@@ -353,7 +367,7 @@ public class WifiScoreReport {
mScore = score;
}
- private void updateWifiMetrics(long now, int s2, int score) {
+ private int getCurrentNetId() {
int netId = 0;
if (mNetworkAgent != null) {
final Network network = mNetworkAgent.getNetwork();
@@ -361,6 +375,28 @@ public class WifiScoreReport {
netId = network.getNetId();
}
}
+ return netId;
+ }
+
+ private int getCurrentSessionId() {
+ return sessionIdFromNetId(getCurrentNetId());
+ }
+
+ /**
+ * Encodes a network id into a scoring session id.
+ *
+ * We use a different numeric value for session id and the network id
+ * to make it clear that these are not the same thing. However, for
+ * easier debugging, the network id can be recovered by dropping the
+ * last decimal digit (at least until they get very, very, large).
+ */
+ public static int sessionIdFromNetId(final int netId) {
+ if (netId <= 0) return INVALID_SESSION_ID;
+ return (int) (((long) netId * 10 + (8 - (netId % 9))) % Integer.MAX_VALUE + 1);
+ }
+
+ private void updateWifiMetrics(long now, int s2, int score) {
+ int netId = getCurrentNetId();
mAggressiveConnectedScore.updateUsingWifiInfo(mWifiInfo, now);
int s1 = mAggressiveConnectedScore.generateScore();
@@ -516,6 +552,7 @@ public class WifiScoreReport {
*/
public boolean setWifiConnectedNetworkScorer(IBinder binder,
IWifiConnectedNetworkScorer scorer) {
+ if (binder == null || scorer == null) return false;
// Enforce that only a single scorer can be set successfully.
if (mWifiConnectedNetworkScorerHolder != null) {
Log.e(TAG, "Failed to set current scorer because one scorer is already set");
@@ -532,15 +569,17 @@ public class WifiScoreReport {
scorer.onSetScoreUpdateObserver(mScoreUpdateObserver);
} catch (RemoteException e) {
Log.e(TAG, "Unable to set score update observer " + scorer, e);
- revertAospConnectedScorer();
+ revertToDefaultConnectedScorer();
return false;
}
- if (mSessionId != INVALID_SESSION_ID) {
- startConnectedNetworkScorer(mSessionId);
- }
// Disable AOSP scorer
mVelocityBasedConnectedScore = null;
mWifiMetrics.setIsExternalWifiScorerOn(true);
+ // If there is already a connection, start a new session
+ final int netId = getCurrentNetId();
+ if (netId > 0) {
+ startConnectedNetworkScorer(netId);
+ }
return true;
}
@@ -552,26 +591,25 @@ public class WifiScoreReport {
return;
}
mWifiConnectedNetworkScorerHolder.reset();
- revertAospConnectedScorer();
+ revertToDefaultConnectedScorer();
}
/**
* Start the registered Wi-Fi connected network scorer.
- * @param sessionId
+ * @param netId identifies the current android.net.Network
*/
- public void startConnectedNetworkScorer(int sessionId) {
- mSessionId = sessionId;
- if (mWifiConnectedNetworkScorerHolder == null) {
+ public void startConnectedNetworkScorer(int netId) {
+ final int sessionId = getCurrentSessionId();
+ if (mWifiConnectedNetworkScorerHolder == null
+ || netId != getCurrentNetId()
+ || sessionId == INVALID_SESSION_ID) {
+ Log.w(TAG, "Cannot start external scoring"
+ + " netId=" + netId
+ + " currentNetId=" + getCurrentNetId()
+ + " sessionId=" + sessionId);
return;
}
- try {
- IWifiConnectedNetworkScorer scorer = mWifiConnectedNetworkScorerHolder.getScorer();
- scorer.onStart(sessionId);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to start Wifi connected network scorer "
- + mWifiConnectedNetworkScorerHolder, e);
- revertAospConnectedScorer();
- }
+ mWifiConnectedNetworkScorerHolder.startSession(sessionId);
mLastScoreBreachLowTimeMillis = INVALID_WALL_CLOCK_MILLIS;
}
@@ -582,15 +620,8 @@ public class WifiScoreReport {
if (mWifiConnectedNetworkScorerHolder == null) {
return;
}
- try {
- IWifiConnectedNetworkScorer scorer = mWifiConnectedNetworkScorerHolder.getScorer();
- scorer.onStop(mSessionId);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to stop Wifi connected network scorer "
- + mWifiConnectedNetworkScorerHolder, e);
- }
+ mWifiConnectedNetworkScorerHolder.stopSession();
- mSessionId = INVALID_SESSION_ID;
long millis = mClock.getWallClockMillis();
// Blocklist the current BSS
if ((mLastScoreBreachLowTimeMillis != INVALID_WALL_CLOCK_MILLIS)
@@ -605,7 +636,6 @@ public class WifiScoreReport {
/**
* Set NetworkAgent
- * @param agent
*/
public void setNetworkAgent(NetworkAgent agent) {
mNetworkAgent = agent;
@@ -626,8 +656,8 @@ public class WifiScoreReport {
mInterfaceName = ifaceName;
}
- private void revertAospConnectedScorer() {
- // Create AOSP scorer and null external Wifi connected network scorer
+ private void revertToDefaultConnectedScorer() {
+ Log.d(TAG, "Using VelocityBasedConnectedScore");
mVelocityBasedConnectedScore = new VelocityBasedConnectedScore(mScoringParams, mClock);
mWifiConnectedNetworkScorerHolder = null;
mWifiMetrics.setIsExternalWifiScorerOn(false);
diff --git a/tests/wifitests/Android.bp b/tests/wifitests/Android.bp
index 7fd2a5f75..2f3cbad1b 100644
--- a/tests/wifitests/Android.bp
+++ b/tests/wifitests/Android.bp
@@ -900,6 +900,9 @@ android_test {
"com.android.server.wifi.util.KeyValueListParser",
"com.android.server.wifi.util.KeyValueListParser$*",
"com.android.server.wifi.util.KeyValueListParser.**",
+ "com.android.server.wifi.util.LruConnectionTracker",
+ "com.android.server.wifi.util.LruConnectionTracker$*",
+ "com.android.server.wifi.util.LruConnectionTracker.**",
"com.android.server.wifi.util.LruList",
"com.android.server.wifi.util.LruList$*",
"com.android.server.wifi.util.LruList.**",
@@ -927,6 +930,9 @@ android_test {
"com.android.server.wifi.util.ScanResultUtil",
"com.android.server.wifi.util.ScanResultUtil$*",
"com.android.server.wifi.util.ScanResultUtil.**",
+ "com.android.server.wifi.util.SettingsMigrationDataHolder",
+ "com.android.server.wifi.util.SettingsMigrationDataHolder$*",
+ "com.android.server.wifi.util.SettingsMigrationDataHolder.**",
"com.android.server.wifi.util.StringUtil",
"com.android.server.wifi.util.StringUtil$*",
"com.android.server.wifi.util.StringUtil.**",
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
index 41775ec25..5fe8eaac7 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
@@ -60,7 +60,6 @@ import com.android.wifi.resources.R;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -82,7 +81,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
}
}
- private static final int TEST_SESSION_ID = 8603706;
+ private static final int TEST_NETWORK_ID = 860370;
+ private static final int TEST_SESSION_ID = 8603703; // last digit is a check digit
FakeClock mClock;
WifiConfiguration mWifiConfiguration;
@@ -100,6 +100,7 @@ public class WifiScoreReportTest extends WifiBaseTest {
@Mock IWifiConnectedNetworkScorer mWifiConnectedNetworkScorer;
@Mock WifiNative mWifiNative;
@Mock BssidBlocklistMonitor mBssidBlocklistMonitor;
+ @Mock Network mNetwork;
private TestLooper mLooper;
public class WifiConnectedNetworkScorerImpl extends IWifiConnectedNetworkScorer.Stub {
@@ -189,10 +190,11 @@ public class WifiScoreReportTest extends WifiBaseTest {
final ConnectivityManager cm = mock(ConnectivityManager.class);
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(cm);
when(cm.registerNetworkAgent(any(), any(), any(), any(), anyInt(), any(), anyInt()))
- .thenReturn(mock(Network.class));
+ .thenReturn(mNetwork);
+ when(mNetwork.getNetId()).thenReturn(0);
mNetworkAgent = spy(new TestNetworkAgent(mContext));
mClock = new FakeClock();
- mScoringParams = new ScoringParams(mContext);
+ mScoringParams = new ScoringParams();
mWifiThreadRunner = new WifiThreadRunner(new Handler(mLooper.getLooper()));
mWifiScoreReport = new WifiScoreReport(mScoringParams, mClock, mWifiMetrics, mWifiInfo,
mWifiNative, mBssidBlocklistMonitor, mWifiThreadRunner);
@@ -412,7 +414,7 @@ public class WifiScoreReportTest extends WifiBaseTest {
asks++;
}
}
- assertTrue(oops + " asks:" + asks, asks > 5 && asks < 12);
+ assertTrue(oops + " asks:" + asks, asks > 5 && asks < 15);
}
@@ -609,16 +611,45 @@ public class WifiScoreReportTest extends WifiBaseTest {
}
/**
+ * Verify netId to sessionId conversion.
+ */
+ @Test
+ public void testSessionId() throws Exception {
+ assertEquals(-1, WifiScoreReport.sessionIdFromNetId(Integer.MIN_VALUE));
+ assertEquals(-1, WifiScoreReport.sessionIdFromNetId(-42));
+ assertEquals(-1, WifiScoreReport.sessionIdFromNetId(-1));
+ assertEquals(-1, WifiScoreReport.sessionIdFromNetId(0));
+ assertEquals(18, WifiScoreReport.sessionIdFromNetId(1));
+ assertEquals(3339, WifiScoreReport.sessionIdFromNetId(333));
+ assertEquals(TEST_SESSION_ID, WifiScoreReport.sessionIdFromNetId(TEST_NETWORK_ID));
+ int dangerOfOverflow = Integer.MAX_VALUE / 10;
+ assertEquals(214748364, dangerOfOverflow);
+ assertEquals(2147483646, WifiScoreReport.sessionIdFromNetId(dangerOfOverflow));
+ assertEquals(8, WifiScoreReport.sessionIdFromNetId(dangerOfOverflow + 1));
+ assertEquals(8, WifiScoreReport.sessionIdFromNetId(Integer.MAX_VALUE));
+ }
+
+ /**
* Verify that client gets session ID when onStart() method is called.
*/
@Test
public void testClientGetSessionIdOnStart() throws Exception {
- ArgumentCaptor<Integer> startId = ArgumentCaptor.forClass(Integer.class);
// Register Client for verification.
mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, mWifiConnectedNetworkScorer);
- mWifiScoreReport.startConnectedNetworkScorer(TEST_SESSION_ID);
- verify(mWifiConnectedNetworkScorer).onStart(startId.capture());
- assertEquals((int) startId.getValue(), TEST_SESSION_ID);
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
+ verify(mWifiConnectedNetworkScorer).onStart(TEST_SESSION_ID);
+ }
+
+ /**
+ * Verify that onStart is called if there is already an active network when registered.
+ */
+ @Test
+ public void testClientStartOnRegWhileActive() throws Exception {
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
+ mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, mWifiConnectedNetworkScorer);
+ verify(mWifiConnectedNetworkScorer).onStart(TEST_SESSION_ID);
}
/**
@@ -626,13 +657,12 @@ public class WifiScoreReportTest extends WifiBaseTest {
*/
@Test
public void testClientGetSessionIdOnStop() throws Exception {
- ArgumentCaptor<Integer> stopId = ArgumentCaptor.forClass(Integer.class);
// Register Client for verification.
mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, mWifiConnectedNetworkScorer);
- mWifiScoreReport.startConnectedNetworkScorer(TEST_SESSION_ID);
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
mWifiScoreReport.stopConnectedNetworkScorer();
- verify(mWifiConnectedNetworkScorer).onStop(stopId.capture());
- assertEquals((int) stopId.getValue(), TEST_SESSION_ID);
+ verify(mWifiConnectedNetworkScorer).onStop(TEST_SESSION_ID);
}
/**
@@ -655,7 +685,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
// Register Client for verification.
mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl);
- mWifiScoreReport.startConnectedNetworkScorer(TEST_SESSION_ID);
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
assertEquals(TEST_SESSION_ID, scorerImpl.mSessionId);
@@ -687,7 +718,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
// Register Client for verification.
mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl);
mWifiScoreReport.setInterfaceName("wlan0");
- mWifiScoreReport.startConnectedNetworkScorer(TEST_SESSION_ID);
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
scorerImpl.mScoreUpdateObserver.triggerUpdateOfWifiUsabilityStats(scorerImpl.mSessionId);
mLooper.dispatchAll();
@@ -703,7 +735,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
// Register Client for verification.
mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl);
- mWifiScoreReport.startConnectedNetworkScorer(TEST_SESSION_ID);
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
mClock.mStepMillis = 0;
mClock.mWallClockMillis = 5001;
@@ -732,7 +765,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
// Register Client for verification.
mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl);
- mWifiScoreReport.startConnectedNetworkScorer(TEST_SESSION_ID);
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
mClock.mStepMillis = 0;
mClock.mWallClockMillis = 10;
@@ -755,7 +789,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
// Register Client for verification.
mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl);
- mWifiScoreReport.startConnectedNetworkScorer(TEST_SESSION_ID);
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
mClock.mStepMillis = 0;
mClock.mWallClockMillis = 10;
@@ -777,7 +812,8 @@ public class WifiScoreReportTest extends WifiBaseTest {
WifiConnectedNetworkScorerImpl scorerImpl = new WifiConnectedNetworkScorerImpl();
// Register Client for verification.
mWifiScoreReport.setWifiConnectedNetworkScorer(mAppBinder, scorerImpl);
- mWifiScoreReport.startConnectedNetworkScorer(TEST_SESSION_ID);
+ when(mNetwork.getNetId()).thenReturn(TEST_NETWORK_ID);
+ mWifiScoreReport.startConnectedNetworkScorer(TEST_NETWORK_ID);
mClock.mStepMillis = 0;
mClock.mWallClockMillis = 10;