Fix venue info notification not displaying
The venue info notification was never displayed, because querying the
notification channel from UserHandle.ALL returns no channel.
Channels must be handled from the NetworkStack (owner) user, not the ALL
user that is used to send notifications.
Bug: 157203874
Test: atest NetworkStackTests; manual: verified showing or disabling the
notification as owner or alternate user.
Original-Change: https://android-review.googlesource.com/1321357
Merged-In: I9ce908cebdef81bb524353219f7ee9ead2487056
Change-Id: I9ce908cebdef81bb524353219f7ee9ead2487056
diff --git a/src/com/android/networkstack/NetworkStackNotifier.java b/src/com/android/networkstack/NetworkStackNotifier.java
index a330c70..872834a 100644
--- a/src/com/android/networkstack/NetworkStackNotifier.java
+++ b/src/com/android/networkstack/NetworkStackNotifier.java
@@ -16,6 +16,8 @@
package com.android.networkstack;
+import static android.app.NotificationManager.IMPORTANCE_NONE;
+
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -142,7 +144,19 @@
resources.getString(title),
importance);
channel.setDescription(resources.getString(description));
- mNotificationManager.createNotificationChannel(channel);
+ getNotificationManagerForChannels().createNotificationChannel(channel);
+ }
+
+ /**
+ * Get the NotificationManager to use to query channels, as opposed to posting notifications.
+ *
+ * Although notifications are posted as USER_ALL, notification channels are always created
+ * based on the UID calling NotificationManager, regardless of the context UserHandle.
+ * When querying notification channels, using a USER_ALL context would return no channel: the
+ * default context (as UserHandle 0 for NetworkStack) must be used.
+ */
+ private NotificationManager getNotificationManagerForChannels() {
+ return mContext.getSystemService(NotificationManager.class);
}
/**
@@ -284,7 +298,11 @@
}
private boolean isVenueInfoNotificationEnabled() {
- return mNotificationManager.getNotificationChannel(CHANNEL_VENUE_INFO) != null;
+ final NotificationChannel channel = getNotificationManagerForChannels()
+ .getNotificationChannel(CHANNEL_VENUE_INFO);
+ if (channel == null) return false;
+
+ return channel.getImportance() != IMPORTANCE_NONE;
}
private static String getNotificationTag(@NonNull Network network) {
diff --git a/tests/unit/src/com/android/networkstack/NetworkStackNotifierTest.kt b/tests/unit/src/com/android/networkstack/NetworkStackNotifierTest.kt
index 1be6ee7..b2607eb 100644
--- a/tests/unit/src/com/android/networkstack/NetworkStackNotifierTest.kt
+++ b/tests/unit/src/com/android/networkstack/NetworkStackNotifierTest.kt
@@ -20,6 +20,7 @@
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.NotificationManager.IMPORTANCE_DEFAULT
+import android.app.NotificationManager.IMPORTANCE_NONE
import android.app.PendingIntent
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.content.Context
@@ -80,6 +81,8 @@
@Mock
private lateinit var mNm: NotificationManager
@Mock
+ private lateinit var mNotificationChannelsNm: NotificationManager
+ @Mock
private lateinit var mCm: ConnectivityManager
@Mock
private lateinit var mResources: Resources
@@ -141,10 +144,12 @@
realContext.packageName, 0, UserHandle.ALL)
mAllUserContext.mockService(Context.NOTIFICATION_SERVICE, NotificationManager::class, mNm)
+ mContext.mockService(Context.NOTIFICATION_SERVICE, NotificationManager::class,
+ mNotificationChannelsNm)
mContext.mockService(Context.CONNECTIVITY_SERVICE, ConnectivityManager::class, mCm)
doReturn(NotificationChannel(CHANNEL_VENUE_INFO, "TestChannel", IMPORTANCE_DEFAULT))
- .`when`(mNm).getNotificationChannel(CHANNEL_VENUE_INFO)
+ .`when`(mNotificationChannelsNm).getNotificationChannel(CHANNEL_VENUE_INFO)
doReturn(mPendingIntent).`when`(mDependencies).getActivityPendingIntent(
any(), any(), anyInt())
@@ -247,7 +252,8 @@
fun testConnectedVenueInfoNotification_VenueInfoDisabled() {
// Venue info (CaptivePortalData) is not available for API <= Q
assumeTrue(NetworkInformationShimImpl.useApiAboveQ())
- doReturn(null).`when`(mNm).getNotificationChannel(CHANNEL_VENUE_INFO)
+ val channel = NotificationChannel(CHANNEL_VENUE_INFO, "test channel", IMPORTANCE_NONE)
+ doReturn(channel).`when`(mNotificationChannelsNm).getNotificationChannel(CHANNEL_VENUE_INFO)
mNotifier.notifyCaptivePortalValidationPending(TEST_NETWORK)
onLinkPropertiesChanged(mTestCapportLp)
onDefaultNetworkAvailable(TEST_NETWORK)