Loading services/core/java/com/android/server/ConnectivityService.java +5 −1 Original line number Diff line number Diff line Loading @@ -1147,7 +1147,11 @@ public class ConnectivityService extends IConnectivityManager.Stub mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler); mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager, mContext.getSystemService(NotificationManager.class)); // Pass a NotificationManager obtained from a context with UserHandle.ALL, then // NetworkNotificationManager can put up a notification to all users. // TODO: Create NotificationManager in NetworkNotificationManager directly. (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */) .getSystemService(Context.NOTIFICATION_SERVICE)); final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, Loading services/core/java/com/android/server/connectivity/NetworkNotificationManager.java +5 −3 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.content.res.Resources; import android.net.NetworkSpecifier; import android.net.TelephonyNetworkSpecifier; import android.net.wifi.WifiInfo; import android.os.UserHandle; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; Loading Loading @@ -75,8 +74,11 @@ public class NetworkNotificationManager { private static final boolean DBG = true; private static final boolean VDBG = false; // The context is for the current user (system server) private final Context mContext; private final TelephonyManager mTelephonyManager; // The notification manager is created from a context for User.ALL, so notifications // will be sent to all users. private final NotificationManager mNotificationManager; // Tracks the types of notifications managed by this instance, from creation to cancellation. private final SparseIntArray mNotificationTypeMap; Loading Loading @@ -282,7 +284,7 @@ public class NetworkNotificationManager { mNotificationTypeMap.put(id, eventId); try { mNotificationManager.notifyAsUser(tag, eventId, notification, UserHandle.ALL); mNotificationManager.notify(tag, eventId, notification); } catch (NullPointerException npe) { Slog.d(TAG, "setNotificationVisible: visible notificationManager error", npe); } Loading Loading @@ -311,7 +313,7 @@ public class NetworkNotificationManager { nameOf(eventId))); } try { mNotificationManager.cancelAsUser(tag, eventId, UserHandle.ALL); mNotificationManager.cancel(tag, eventId); } catch (NullPointerException npe) { Slog.d(TAG, String.format( "failed to clear notification tag=%s event=%s", tag, nameOf(eventId)), npe); Loading services/core/java/com/android/server/connectivity/Vpn.java +7 −4 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ public class Vpn { // automated reconnection private final Context mContext; // The context is for specific user which is created from mUserId private final Context mUserIdContext; @VisibleForTesting final Dependencies mDeps; private final NetworkInfo mNetworkInfo; private int mLegacyState; Loading Loading @@ -399,6 +401,7 @@ public class Vpn { int userId, @NonNull KeyStore keyStore, SystemServices systemServices, Ikev2SessionCreator ikev2SessionCreator) { mContext = context; mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */); mDeps = deps; mNetd = netService; mUserId = userId; Loading Loading @@ -1925,9 +1928,10 @@ public class Vpn { final UserHandle user = UserHandle.of(mUserId); final long token = Binder.clearCallingIdentity(); try { final NotificationManager notificationManager = NotificationManager.from(mContext); final NotificationManager notificationManager = mUserIdContext.getSystemService(NotificationManager.class); if (!visible) { notificationManager.cancelAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, user); notificationManager.cancel(TAG, SystemMessage.NOTE_VPN_DISCONNECTED); return; } final Intent intent = new Intent(); Loading @@ -1947,8 +1951,7 @@ public class Vpn { .setVisibility(Notification.VISIBILITY_PUBLIC) .setOngoing(true) .setColor(mContext.getColor(R.color.system_notification_accent_color)); notificationManager.notifyAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, builder.build(), user); notificationManager.notify(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, builder.build()); } finally { Binder.restoreCallingIdentity(token); } Loading services/core/java/com/android/server/net/LockdownVpnTracker.java +4 −2 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ public class LockdownVpnTracker { @NonNull private final Context mContext; @NonNull private final ConnectivityService mConnService; @NonNull private final NotificationManager mNotificationManager; @NonNull private final Handler mHandler; @NonNull private final Vpn mVpn; @NonNull private final VpnProfile mProfile; Loading Loading @@ -93,6 +94,7 @@ public class LockdownVpnTracker { mHandler = Objects.requireNonNull(handler); mVpn = Objects.requireNonNull(vpn); mProfile = Objects.requireNonNull(profile); mNotificationManager = mContext.getSystemService(NotificationManager.class); final Intent configIntent = new Intent(ACTION_VPN_SETTINGS); mConfigIntent = PendingIntent.getActivity(mContext, 0 /* requestCode */, configIntent, Loading Loading @@ -266,11 +268,11 @@ public class LockdownVpnTracker { .setColor(mContext.getColor( com.android.internal.R.color.system_notification_accent_color)); NotificationManager.from(mContext).notify(null, SystemMessage.NOTE_VPN_STATUS, mNotificationManager.notify(null /* tag */, SystemMessage.NOTE_VPN_STATUS, builder.build()); } private void hideNotification() { NotificationManager.from(mContext).cancel(null, SystemMessage.NOTE_VPN_STATUS); mNotificationManager.cancel(null, SystemMessage.NOTE_VPN_STATUS); } } tests/net/java/com/android/server/ConnectivityServiceTest.java +14 −6 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.AdditionalAnswers; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; Loading Loading @@ -451,6 +452,13 @@ public class ConnectivityServiceTest { return super.getSystemService(name); } @Override public Context createContextAsUser(UserHandle user, int flags) { final Context asUser = mock(Context.class, AdditionalAnswers.delegatesTo(this)); doReturn(user).when(asUser).getUser(); return asUser; } @Override public ContentResolver getContentResolver() { return mContentResolver; Loading Loading @@ -4992,22 +5000,22 @@ public class ConnectivityServiceTest { // simulate that situation and check if ConnectivityService could filter that case. mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); waitForIdle(); verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notifyAsUser(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any(), eq(UserHandle.ALL)); verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notify(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); // If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be // shown. mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */); mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); waitForIdle(); verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancelAsUser(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), eq(UserHandle.ALL)); verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancel(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId)); // If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be // shown again. mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); waitForIdle(); verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notifyAsUser(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any(), eq(UserHandle.ALL)); verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notify(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); } @Test Loading Loading
services/core/java/com/android/server/ConnectivityService.java +5 −1 Original line number Diff line number Diff line Loading @@ -1147,7 +1147,11 @@ public class ConnectivityService extends IConnectivityManager.Stub mKeepaliveTracker = new KeepaliveTracker(mContext, mHandler); mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager, mContext.getSystemService(NotificationManager.class)); // Pass a NotificationManager obtained from a context with UserHandle.ALL, then // NetworkNotificationManager can put up a notification to all users. // TODO: Create NotificationManager in NetworkNotificationManager directly. (NotificationManager) mContext.createContextAsUser(UserHandle.ALL, 0 /* flags */) .getSystemService(Context.NOTIFICATION_SERVICE)); final int dailyLimit = Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.NETWORK_SWITCH_NOTIFICATION_DAILY_LIMIT, Loading
services/core/java/com/android/server/connectivity/NetworkNotificationManager.java +5 −3 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.content.res.Resources; import android.net.NetworkSpecifier; import android.net.TelephonyNetworkSpecifier; import android.net.wifi.WifiInfo; import android.os.UserHandle; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; Loading Loading @@ -75,8 +74,11 @@ public class NetworkNotificationManager { private static final boolean DBG = true; private static final boolean VDBG = false; // The context is for the current user (system server) private final Context mContext; private final TelephonyManager mTelephonyManager; // The notification manager is created from a context for User.ALL, so notifications // will be sent to all users. private final NotificationManager mNotificationManager; // Tracks the types of notifications managed by this instance, from creation to cancellation. private final SparseIntArray mNotificationTypeMap; Loading Loading @@ -282,7 +284,7 @@ public class NetworkNotificationManager { mNotificationTypeMap.put(id, eventId); try { mNotificationManager.notifyAsUser(tag, eventId, notification, UserHandle.ALL); mNotificationManager.notify(tag, eventId, notification); } catch (NullPointerException npe) { Slog.d(TAG, "setNotificationVisible: visible notificationManager error", npe); } Loading Loading @@ -311,7 +313,7 @@ public class NetworkNotificationManager { nameOf(eventId))); } try { mNotificationManager.cancelAsUser(tag, eventId, UserHandle.ALL); mNotificationManager.cancel(tag, eventId); } catch (NullPointerException npe) { Slog.d(TAG, String.format( "failed to clear notification tag=%s event=%s", tag, nameOf(eventId)), npe); Loading
services/core/java/com/android/server/connectivity/Vpn.java +7 −4 Original line number Diff line number Diff line Loading @@ -199,6 +199,8 @@ public class Vpn { // automated reconnection private final Context mContext; // The context is for specific user which is created from mUserId private final Context mUserIdContext; @VisibleForTesting final Dependencies mDeps; private final NetworkInfo mNetworkInfo; private int mLegacyState; Loading Loading @@ -399,6 +401,7 @@ public class Vpn { int userId, @NonNull KeyStore keyStore, SystemServices systemServices, Ikev2SessionCreator ikev2SessionCreator) { mContext = context; mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */); mDeps = deps; mNetd = netService; mUserId = userId; Loading Loading @@ -1925,9 +1928,10 @@ public class Vpn { final UserHandle user = UserHandle.of(mUserId); final long token = Binder.clearCallingIdentity(); try { final NotificationManager notificationManager = NotificationManager.from(mContext); final NotificationManager notificationManager = mUserIdContext.getSystemService(NotificationManager.class); if (!visible) { notificationManager.cancelAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, user); notificationManager.cancel(TAG, SystemMessage.NOTE_VPN_DISCONNECTED); return; } final Intent intent = new Intent(); Loading @@ -1947,8 +1951,7 @@ public class Vpn { .setVisibility(Notification.VISIBILITY_PUBLIC) .setOngoing(true) .setColor(mContext.getColor(R.color.system_notification_accent_color)); notificationManager.notifyAsUser(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, builder.build(), user); notificationManager.notify(TAG, SystemMessage.NOTE_VPN_DISCONNECTED, builder.build()); } finally { Binder.restoreCallingIdentity(token); } Loading
services/core/java/com/android/server/net/LockdownVpnTracker.java +4 −2 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ public class LockdownVpnTracker { @NonNull private final Context mContext; @NonNull private final ConnectivityService mConnService; @NonNull private final NotificationManager mNotificationManager; @NonNull private final Handler mHandler; @NonNull private final Vpn mVpn; @NonNull private final VpnProfile mProfile; Loading Loading @@ -93,6 +94,7 @@ public class LockdownVpnTracker { mHandler = Objects.requireNonNull(handler); mVpn = Objects.requireNonNull(vpn); mProfile = Objects.requireNonNull(profile); mNotificationManager = mContext.getSystemService(NotificationManager.class); final Intent configIntent = new Intent(ACTION_VPN_SETTINGS); mConfigIntent = PendingIntent.getActivity(mContext, 0 /* requestCode */, configIntent, Loading Loading @@ -266,11 +268,11 @@ public class LockdownVpnTracker { .setColor(mContext.getColor( com.android.internal.R.color.system_notification_accent_color)); NotificationManager.from(mContext).notify(null, SystemMessage.NOTE_VPN_STATUS, mNotificationManager.notify(null /* tag */, SystemMessage.NOTE_VPN_STATUS, builder.build()); } private void hideNotification() { NotificationManager.from(mContext).cancel(null, SystemMessage.NOTE_VPN_STATUS); mNotificationManager.cancel(null, SystemMessage.NOTE_VPN_STATUS); } }
tests/net/java/com/android/server/ConnectivityServiceTest.java +14 −6 Original line number Diff line number Diff line Loading @@ -251,6 +251,7 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.AdditionalAnswers; import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; Loading Loading @@ -451,6 +452,13 @@ public class ConnectivityServiceTest { return super.getSystemService(name); } @Override public Context createContextAsUser(UserHandle user, int flags) { final Context asUser = mock(Context.class, AdditionalAnswers.delegatesTo(this)); doReturn(user).when(asUser).getUser(); return asUser; } @Override public ContentResolver getContentResolver() { return mContentResolver; Loading Loading @@ -4992,22 +5000,22 @@ public class ConnectivityServiceTest { // simulate that situation and check if ConnectivityService could filter that case. mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); waitForIdle(); verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notifyAsUser(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any(), eq(UserHandle.ALL)); verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).notify(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); // If private DNS resolution successful, the PRIVATE_DNS_BROKEN notification shouldn't be // shown. mWiFiNetworkAgent.setNetworkValid(true /* isStrictMode */); mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); waitForIdle(); verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancelAsUser(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), eq(UserHandle.ALL)); verify(mNotificationManager, timeout(TIMEOUT_MS).times(1)).cancel(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId)); // If private DNS resolution failed again, the PRIVATE_DNS_BROKEN notification should be // shown again. mWiFiNetworkAgent.setNetworkInvalid(true /* isStrictMode */); mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid()); waitForIdle(); verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notifyAsUser(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any(), eq(UserHandle.ALL)); verify(mNotificationManager, timeout(TIMEOUT_MS).times(2)).notify(anyString(), eq(NotificationType.PRIVATE_DNS_BROKEN.eventId), any()); } @Test Loading