Allow firing the LOST_INTERNET intent immediately in config

When config_notifyNoInternetAsDialogWhenHighPriority is on, the
LOST_INTERNET notification intent should be fired immediately
rather than as a pending intent.

Bug: 281970908
Test: Improve test for this in NetworkNotificationManagerTest
(cherry picked from https://android-review.googlesource.com/q/commit:e13b833b21342d80ef940783acba4b3eecfce968)
Merged-In: I88565839a12a1ab4b096f763250944ebaf6c5349
Change-Id: I88565839a12a1ab4b096f763250944ebaf6c5349
This commit is contained in:
Chalard Jean
2023-06-05 18:47:42 +09:00
parent a0e8ab4933
commit 3bf3a59f35
3 changed files with 108 additions and 22 deletions

View File

@@ -135,10 +135,17 @@
<!-- Whether to cancel network notifications automatically when tapped -->
<bool name="config_autoCancelNetworkNotifications">true</bool>
<!-- When no internet or partial connectivity is detected on a network, and a high priority
(heads up) notification would be shown due to the network being explicitly selected,
directly show the dialog that would normally be shown when tapping the notification
instead of showing the notification. -->
<!-- Configuration to let OEMs customize what to do when :
• Partial connectivity is detected on the network
• No internet is detected on the network, and
- the network was explicitly selected
- the system is configured to actively prefer bad wifi (see config_activelyPreferBadWifi)
The default behavior (false) is to post a notification with a PendingIntent so
the user is informed and can act if they wish.
Making this true instead will have the system fire the intent immediately instead
of showing a notification. OEMs who do this should have some intent receiver
listening to the intent and take the action they prefer (e.g. show a dialog,
show a customized notification etc). -->
<bool name="config_notifyNoInternetAsDialogWhenHighPriority">false</bool>
<!-- When showing notifications indicating partial connectivity, display the same notifications

View File

@@ -322,7 +322,11 @@ public class NetworkNotificationManager {
private boolean maybeNotifyViaDialog(Resources res, NotificationType notifyType,
PendingIntent intent) {
if (notifyType != NotificationType.NO_INTERNET
final boolean activelyPreferBadWifi = SdkLevel.isAtLeastU()
|| (SdkLevel.isAtLeastT()
&& res.getInteger(R.integer.config_activelyPreferBadWifi) == 1);
if ((notifyType != NotificationType.LOST_INTERNET || !activelyPreferBadWifi)
&& notifyType != NotificationType.NO_INTERNET
&& notifyType != NotificationType.PARTIAL_CONNECTIVITY) {
return false;
}
@@ -432,7 +436,8 @@ public class NetworkNotificationManager {
* A notification with a higher number will take priority over a notification with a lower
* number.
*/
private static int priority(NotificationType t) {
@VisibleForTesting
public static int priority(NotificationType t) {
if (t == null) {
return 0;
}

View File

@@ -62,6 +62,7 @@ import android.testing.PollingCheck;
import android.util.DisplayMetrics;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.test.filters.SmallTest;
@@ -73,6 +74,7 @@ import androidx.test.uiautomator.UiSelector;
import androidx.test.uiautomator.Until;
import com.android.connectivity.resources.R;
import com.android.modules.utils.build.SdkLevel;
import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
@@ -385,15 +387,75 @@ public class NetworkNotificationManagerTest {
verify(mNotificationManager, never()).cancel(eq(tag), eq(PARTIAL_CONNECTIVITY.eventId));
}
private static final int EXPECT_DIALOG = 0;
private static final int EXPECT_NOTIFICATION = 1;
@Test
public void testNotifyNoInternetAsDialogWhenHighPriority() throws Exception {
doReturn(true).when(mResources).getBoolean(
public void testNotifyNoInternet_asNotification_ActivelyPrefer() throws Exception {
doTestNotifyNotificationAsDialogWhenHighPriority(false /* notifyAsDialog */,
true /* activelyPreferBadWifi */, NO_INTERNET, EXPECT_NOTIFICATION);
}
@Test
public void testNotifyNoInternet_asNotification_NotActivelyPrefer() throws Exception {
doTestNotifyNotificationAsDialogWhenHighPriority(false /* notifyAsDialog */,
false /* activelyPreferBadWifi */, NO_INTERNET, EXPECT_NOTIFICATION);
}
@Test
public void testNotifyNoInternet_asDialog_ActivelyPrefer() throws Exception {
doTestNotifyNotificationAsDialogWhenHighPriority(true /* notifyAsDialog */,
true /* activelyPreferBadWifi */, NO_INTERNET, EXPECT_DIALOG);
}
@Test
public void testNotifyNoInternet_asDialog_NotActivelyPrefer() throws Exception {
doTestNotifyNotificationAsDialogWhenHighPriority(true /* notifyAsDialog */,
false /* activelyPreferBadWifi */, NO_INTERNET, EXPECT_DIALOG);
}
@Test
public void testNotifyLostInternet_asNotification_ActivelyPrefer() throws Exception {
doTestNotifyNotificationAsDialogWhenHighPriority(false /* notifyAsDialog */,
true /* activelyPreferBadWifi */, LOST_INTERNET, EXPECT_NOTIFICATION);
}
@Test
public void testNotifyLostInternet_asNotification_NotActivelyPrefer() throws Exception {
doTestNotifyNotificationAsDialogWhenHighPriority(false /* notifyAsDialog */,
false /* activelyPreferBadWifi */, LOST_INTERNET, EXPECT_NOTIFICATION);
}
@Test
public void testNotifyLostInternet_asDialog_ActivelyPrefer() throws Exception {
doTestNotifyNotificationAsDialogWhenHighPriority(true /* notifyAsDialog */,
true /* activelyPreferBadWifi */, LOST_INTERNET,
SdkLevel.isAtLeastT() ? EXPECT_DIALOG : EXPECT_NOTIFICATION);
}
@Test
public void testNotifyLostInternet_asDialog_NotActivelyPrefer() throws Exception {
doTestNotifyNotificationAsDialogWhenHighPriority(true /* notifyAsDialog */,
false /* activelyPreferBadWifi */, LOST_INTERNET,
SdkLevel.isAtLeastU() ? EXPECT_DIALOG : EXPECT_NOTIFICATION);
}
// Pass EXPECT_DIALOG or EXPECT_NOTIFICATION to |expectBehavior|
public void doTestNotifyNotificationAsDialogWhenHighPriority(
final boolean notifyAsDialog, final boolean activelyPreferBadWifi,
@NonNull final NotificationType notifType, final int expectBehavior) throws Exception {
doReturn(notifyAsDialog).when(mResources).getBoolean(
R.bool.config_notifyNoInternetAsDialogWhenHighPriority);
doReturn(activelyPreferBadWifi ? 1 : 0).when(mResources).getInteger(
R.integer.config_activelyPreferBadWifi);
final Instrumentation instr = InstrumentationRegistry.getInstrumentation();
final UiDevice uiDevice = UiDevice.getInstance(instr);
final Context ctx = instr.getContext();
final PowerManager pm = ctx.getSystemService(PowerManager.class);
// If the prio of this notif is < that of NETWORK_SWITCH, it's the lowest prio and
// therefore it can't be tested whether it cancels other lower-prio notifs.
final boolean isLowestPrioNotif = NetworkNotificationManager.priority(notifType)
< NetworkNotificationManager.priority(NETWORK_SWITCH);
// Wake up the device (it has no effect if the device is already awake).
uiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
@@ -409,9 +471,13 @@ public class NetworkNotificationManagerTest {
uiDevice.wait(Until.hasObject(By.pkg(launcherPackageName)),
UI_AUTOMATOR_WAIT_TIME_MILLIS));
mManager.showNotification(TEST_NOTIF_ID, NETWORK_SWITCH, mWifiNai, mCellNai, null, false);
// Non-"no internet" notifications are not affected
verify(mNotificationManager).notify(eq(TEST_NOTIF_TAG), eq(NETWORK_SWITCH.eventId), any());
if (!isLowestPrioNotif) {
mManager.showNotification(TEST_NOTIF_ID, NETWORK_SWITCH, mWifiNai, mCellNai,
null, false);
// Non-"no internet" notifications are not affected
verify(mNotificationManager).notify(eq(TEST_NOTIF_TAG), eq(NETWORK_SWITCH.eventId),
any());
}
final String testAction = "com.android.connectivity.coverage.TEST_DIALOG";
final Intent intent = new Intent(testAction)
@@ -420,22 +486,30 @@ public class NetworkNotificationManagerTest {
final PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 0 /* requestCode */,
intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
mManager.showNotification(TEST_NOTIF_ID, NO_INTERNET, mWifiNai, null /* switchToNai */,
mManager.showNotification(TEST_NOTIF_ID, notifType, mWifiNai, null /* switchToNai */,
pendingIntent, true /* highPriority */);
// Previous notifications are still dismissed
verify(mNotificationManager).cancel(TEST_NOTIF_TAG, NETWORK_SWITCH.eventId);
if (!isLowestPrioNotif) {
// Previous notifications are still dismissed
verify(mNotificationManager).cancel(TEST_NOTIF_TAG, NETWORK_SWITCH.eventId);
}
// Verify that the activity is shown (the activity shows the action on screen)
final UiObject actionText = uiDevice.findObject(new UiSelector().text(testAction));
assertTrue("Activity not shown", actionText.waitForExists(TEST_TIMEOUT_MS));
if (expectBehavior == EXPECT_DIALOG) {
// Verify that the activity is shown (the activity shows the action on screen)
final UiObject actionText = uiDevice.findObject(new UiSelector().text(testAction));
assertTrue("Activity not shown", actionText.waitForExists(TEST_TIMEOUT_MS));
// Tapping the text should dismiss the dialog
actionText.click();
assertTrue("Activity not dismissed", actionText.waitUntilGone(TEST_TIMEOUT_MS));
// Tapping the text should dismiss the dialog
actionText.click();
assertTrue("Activity not dismissed", actionText.waitUntilGone(TEST_TIMEOUT_MS));
// Verify no NO_INTERNET notification was posted
verify(mNotificationManager, never()).notify(any(), eq(NO_INTERNET.eventId), any());
// Verify that the notification was not posted
verify(mNotificationManager, never()).notify(any(), eq(notifType.eventId), any());
} else {
// Notification should have been posted, and will have overridden the previous
// one because it has the same id (hence no cancel).
verify(mNotificationManager).notify(eq(TEST_NOTIF_TAG), eq(notifType.eventId), any());
}
}
private void doNotificationTextTest(NotificationType type, @StringRes int expectedTitleRes,