Network switch notifications: rate & daily limits

This patch adds a daily limit to the maximum number of notifications
shown when switching networks.

It also adds a rate limit to prevent rapid successive notifications in
flapping scenarios.

Bug: 31132499
Change-Id: Iccb6d0899646ea6df3cfad32a421922263e0eb85
This commit is contained in:
Lorenzo Colitti
2016-08-29 14:03:11 +09:00
committed by Hugo Benichi
parent 01f7228f5c
commit 9bf6fef270
3 changed files with 174 additions and 40 deletions

View File

@@ -24,6 +24,7 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkMisc;
import android.text.format.DateUtils;
import com.android.internal.R;
import com.android.server.ConnectivityService;
import com.android.server.connectivity.NetworkNotificationManager;
@@ -40,11 +41,18 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.reset;
public class LingerMonitorTest extends TestCase {
static final String CELLULAR = "CELLULAR";
static final String WIFI = "WIFI";
static final long LOW_RATE_LIMIT = DateUtils.MINUTE_IN_MILLIS;
static final long HIGH_RATE_LIMIT = 0;
static final int LOW_DAILY_LIMIT = 2;
static final int HIGH_DAILY_LIMIT = 1000;
LingerMonitor mMonitor;
@Mock ConnectivityService mConnService;
@@ -59,7 +67,7 @@ public class LingerMonitorTest extends TestCase {
when(mCtx.getPackageName()).thenReturn("com.android.server.connectivity");
when(mConnService.createNetworkMonitor(any(), any(), any(), any())).thenReturn(null);
mMonitor = new TestableLingerMonitor(mCtx, mNotifier);
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT);
}
public void testTransitions() {
@@ -129,8 +137,78 @@ public class LingerMonitorTest extends TestCase {
mMonitor.noteLingerDefaultNetwork(to, from);
verify(mNotifier, times(1)).clearNotification(100);
reset(mNotifier);
mMonitor.noteLingerDefaultNetwork(from, to);
verifyToast(from, to);
verifyNoNotifications();
}
public void testMultipleNotifications() {
setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
NetworkAgentInfo wifi1 = wifiNai(100);
NetworkAgentInfo wifi2 = wifiNai(101);
NetworkAgentInfo cell = cellNai(102);
mMonitor.noteLingerDefaultNetwork(wifi1, cell);
verifyNotification(wifi1, cell);
mMonitor.noteLingerDefaultNetwork(cell, wifi2);
verify(mNotifier, times(1)).clearNotification(100);
reset(mNotifier);
mMonitor.noteLingerDefaultNetwork(wifi2, cell);
verifyNotification(wifi2, cell);
}
public void testRateLimiting() throws InterruptedException {
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT);
setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
NetworkAgentInfo wifi1 = wifiNai(100);
NetworkAgentInfo wifi2 = wifiNai(101);
NetworkAgentInfo wifi3 = wifiNai(102);
NetworkAgentInfo cell = cellNai(103);
mMonitor.noteLingerDefaultNetwork(wifi1, cell);
verifyNotification(wifi1, cell);
reset(mNotifier);
Thread.sleep(50);
mMonitor.noteLingerDefaultNetwork(cell, wifi2);
mMonitor.noteLingerDefaultNetwork(wifi2, cell);
verifyNoNotifications();
Thread.sleep(50);
mMonitor.noteLingerDefaultNetwork(cell, wifi3);
mMonitor.noteLingerDefaultNetwork(wifi3, cell);
verifyNoNotifications();
}
public void testDailyLimiting() throws InterruptedException {
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT);
setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
NetworkAgentInfo wifi1 = wifiNai(100);
NetworkAgentInfo wifi2 = wifiNai(101);
NetworkAgentInfo wifi3 = wifiNai(102);
NetworkAgentInfo cell = cellNai(103);
mMonitor.noteLingerDefaultNetwork(wifi1, cell);
verifyNotification(wifi1, cell);
reset(mNotifier);
Thread.sleep(50);
mMonitor.noteLingerDefaultNetwork(cell, wifi2);
mMonitor.noteLingerDefaultNetwork(wifi2, cell);
verifyNotification(wifi2, cell);
reset(mNotifier);
Thread.sleep(50);
mMonitor.noteLingerDefaultNetwork(cell, wifi3);
mMonitor.noteLingerDefaultNetwork(wifi3, cell);
verifyNoNotifications();
}
public void testUniqueNotification() {
@@ -149,7 +227,7 @@ public class LingerMonitorTest extends TestCase {
verifyNotification(from, to);
}
public void testIgnoreUnvalidatedNetworks() {
public void testIgnoreNeverValidatedNetworks() {
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
setNotificationSwitch(transition(WIFI, CELLULAR));
NetworkAgentInfo from = wifiNai(100);
@@ -160,6 +238,17 @@ public class LingerMonitorTest extends TestCase {
verifyNoNotifications();
}
public void testIgnoreCurrentlyValidatedNetworks() {
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
setNotificationSwitch(transition(WIFI, CELLULAR));
NetworkAgentInfo from = wifiNai(100);
NetworkAgentInfo to = cellNai(101);
from.lastValidated = true;
mMonitor.noteLingerDefaultNetwork(from, to);
verifyNoNotifications();
}
public void testNoNotificationType() {
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
setNotificationSwitch();
@@ -215,7 +304,6 @@ public class LingerMonitorTest extends TestCase {
void verifyNoNotifications() {
verifyNoToast();
verifyNoNotification();
verify(mNotifier, never()).clearNotification(anyInt());
}
void verifyToast(NetworkAgentInfo from, NetworkAgentInfo to) {
@@ -251,8 +339,8 @@ public class LingerMonitorTest extends TestCase {
}
public static class TestableLingerMonitor extends LingerMonitor {
public TestableLingerMonitor(Context c, NetworkNotificationManager n) {
super(c, n);
public TestableLingerMonitor(Context c, NetworkNotificationManager n, int l, long r) {
super(c, n, l, r);
}
@Override protected PendingIntent createNotificationIntent() {
return null;