DO NOT MERGE Network notifications: revamp keying scheme
am: e9c9d4bf0c
Change-Id: Ibad7d0210b2c69826462b781f43a82d65849ebfb
This commit is contained in:
@@ -19,7 +19,6 @@ package com.android.server.connectivity;
|
|||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.widget.Toast;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
@@ -27,18 +26,40 @@ import android.net.NetworkCapabilities;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import android.util.SparseArray;
|
||||||
|
import android.util.SparseIntArray;
|
||||||
|
import android.widget.Toast;
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
import com.android.internal.logging.MetricsProto.MetricsEvent;
|
||||||
|
|
||||||
import static android.net.NetworkCapabilities.*;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
|
|
||||||
public class NetworkNotificationManager {
|
public class NetworkNotificationManager {
|
||||||
|
|
||||||
public static enum NotificationType { SIGN_IN, NO_INTERNET, LOST_INTERNET, NETWORK_SWITCH };
|
public static enum NotificationType {
|
||||||
|
LOST_INTERNET(MetricsEvent.NOTIFICATION_NETWORK_LOST_INTERNET),
|
||||||
|
NETWORK_SWITCH(MetricsEvent.NOTIFICATION_NETWORK_SWITCH),
|
||||||
|
NO_INTERNET(MetricsEvent.NOTIFICATION_NETWORK_NO_INTERNET),
|
||||||
|
SIGN_IN(MetricsEvent.NOTIFICATION_NETWORK_SIGN_IN);
|
||||||
|
|
||||||
@VisibleForTesting
|
public final int eventId;
|
||||||
static final String NOTIFICATION_ID = "Connectivity.Notification";
|
|
||||||
|
NotificationType(int eventId) {
|
||||||
|
this.eventId = eventId;
|
||||||
|
Holder.sIdToTypeMap.put(eventId, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Holder {
|
||||||
|
private static SparseArray<NotificationType> sIdToTypeMap = new SparseArray<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NotificationType getFromId(int id) {
|
||||||
|
return Holder.sIdToTypeMap.get(id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private static final String TAG = NetworkNotificationManager.class.getSimpleName();
|
private static final String TAG = NetworkNotificationManager.class.getSimpleName();
|
||||||
private static final boolean DBG = true;
|
private static final boolean DBG = true;
|
||||||
@@ -47,11 +68,14 @@ public class NetworkNotificationManager {
|
|||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final TelephonyManager mTelephonyManager;
|
private final TelephonyManager mTelephonyManager;
|
||||||
private final NotificationManager mNotificationManager;
|
private final NotificationManager mNotificationManager;
|
||||||
|
// Tracks the types of notifications managed by this instance, from creation to cancellation.
|
||||||
|
private final SparseIntArray mNotificationTypeMap;
|
||||||
|
|
||||||
public NetworkNotificationManager(Context c, TelephonyManager t, NotificationManager n) {
|
public NetworkNotificationManager(Context c, TelephonyManager t, NotificationManager n) {
|
||||||
mContext = c;
|
mContext = c;
|
||||||
mTelephonyManager = t;
|
mTelephonyManager = t;
|
||||||
mNotificationManager = n;
|
mNotificationManager = n;
|
||||||
|
mNotificationTypeMap = new SparseIntArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: deal more gracefully with multi-transport networks.
|
// TODO: deal more gracefully with multi-transport networks.
|
||||||
@@ -101,8 +125,10 @@ public class NetworkNotificationManager {
|
|||||||
*/
|
*/
|
||||||
public void showNotification(int id, NotificationType notifyType, NetworkAgentInfo nai,
|
public void showNotification(int id, NotificationType notifyType, NetworkAgentInfo nai,
|
||||||
NetworkAgentInfo switchToNai, PendingIntent intent, boolean highPriority) {
|
NetworkAgentInfo switchToNai, PendingIntent intent, boolean highPriority) {
|
||||||
int transportType;
|
final String tag = tagFor(id);
|
||||||
String extraInfo;
|
final int eventId = notifyType.eventId;
|
||||||
|
final int transportType;
|
||||||
|
final String extraInfo;
|
||||||
if (nai != null) {
|
if (nai != null) {
|
||||||
transportType = getFirstTransportType(nai);
|
transportType = getFirstTransportType(nai);
|
||||||
extraInfo = nai.networkInfo.getExtraInfo();
|
extraInfo = nai.networkInfo.getExtraInfo();
|
||||||
@@ -115,9 +141,9 @@ public class NetworkNotificationManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
Slog.d(TAG, "showNotification id=" + id + " " + notifyType
|
Slog.d(TAG, String.format(
|
||||||
+ " transportType=" + getTransportName(transportType)
|
"showNotification tag=%s event=%s transport=%s extraInfo=%d highPrioriy=%s",
|
||||||
+ " extraInfo=" + extraInfo + " highPriority=" + highPriority);
|
tag, nameOf(eventId), getTransportName(transportType), extraInfo, highPriority));
|
||||||
}
|
}
|
||||||
|
|
||||||
Resources r = Resources.getSystem();
|
Resources r = Resources.getSystem();
|
||||||
@@ -185,22 +211,31 @@ public class NetworkNotificationManager {
|
|||||||
|
|
||||||
Notification notification = builder.build();
|
Notification notification = builder.build();
|
||||||
|
|
||||||
|
mNotificationTypeMap.put(id, eventId);
|
||||||
try {
|
try {
|
||||||
mNotificationManager.notifyAsUser(NOTIFICATION_ID, id, notification, UserHandle.ALL);
|
mNotificationManager.notifyAsUser(tag, eventId, notification, UserHandle.ALL);
|
||||||
} catch (NullPointerException npe) {
|
} catch (NullPointerException npe) {
|
||||||
Slog.d(TAG, "setNotificationVisible: visible notificationManager error", npe);
|
Slog.d(TAG, "setNotificationVisible: visible notificationManager error", npe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearNotification(int id) {
|
public void clearNotification(int id) {
|
||||||
|
final String tag = tagFor(id);
|
||||||
|
if (mNotificationTypeMap.indexOfKey(id) < 0) {
|
||||||
|
Slog.e(TAG, "cannot clear unknown notification with tag=" + tag);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final int eventId = mNotificationTypeMap.get(id);
|
||||||
if (DBG) {
|
if (DBG) {
|
||||||
Slog.d(TAG, "clearNotification id=" + id);
|
Slog.d(TAG, String.format("clearing notification tag=%s event=", tag, nameOf(eventId)));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mNotificationManager.cancelAsUser(NOTIFICATION_ID, id, UserHandle.ALL);
|
mNotificationManager.cancelAsUser(tag, eventId, UserHandle.ALL);
|
||||||
} catch (NullPointerException npe) {
|
} catch (NullPointerException npe) {
|
||||||
Slog.d(TAG, "setNotificationVisible: cancel notificationManager error", npe);
|
Slog.d(TAG, String.format(
|
||||||
|
"failed to clear notification tag=%s event=", tag, nameOf(eventId)), npe);
|
||||||
}
|
}
|
||||||
|
mNotificationTypeMap.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -223,4 +258,15 @@ public class NetworkNotificationManager {
|
|||||||
R.string.network_switch_metered_toast, fromTransport, toTransport);
|
R.string.network_switch_metered_toast, fromTransport, toTransport);
|
||||||
Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
|
Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static String tagFor(int id) {
|
||||||
|
return String.format("ConnectivityNotification:%d", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static String nameOf(int eventId) {
|
||||||
|
NotificationType t = NotificationType.getFromId(eventId);
|
||||||
|
return (t != null) ? t.name() : "UNKNOWN";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,6 @@ import static org.mockito.Mockito.when;
|
|||||||
|
|
||||||
public class NetworkNotificationManagerTest extends TestCase {
|
public class NetworkNotificationManagerTest extends TestCase {
|
||||||
|
|
||||||
static final String NOTIFICATION_ID = NetworkNotificationManager.NOTIFICATION_ID;
|
|
||||||
|
|
||||||
static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities();
|
static final NetworkCapabilities CELL_CAPABILITIES = new NetworkCapabilities();
|
||||||
static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities();
|
static final NetworkCapabilities WIFI_CAPABILITIES = new NetworkCapabilities();
|
||||||
static {
|
static {
|
||||||
@@ -108,11 +106,11 @@ public class NetworkNotificationManagerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < ids.size(); i++) {
|
for (int i = 0; i < ids.size(); i++) {
|
||||||
final int expectedId = NETWORK_ID_BASE + i;
|
final int id = ids.get(i);
|
||||||
verify(mNotificationManager, times(1))
|
final int eventId = types.get(i).eventId;
|
||||||
.notifyAsUser(eq(NOTIFICATION_ID), eq(expectedId), any(), any());
|
final String tag = NetworkNotificationManager.tagFor(id);
|
||||||
verify(mNotificationManager, times(1))
|
verify(mNotificationManager, times(1)).notifyAsUser(eq(tag), eq(eventId), any(), any());
|
||||||
.cancelAsUser(eq(NOTIFICATION_ID), eq(expectedId), any());
|
verify(mNotificationManager, times(1)).cancelAsUser(eq(tag), eq(eventId), any());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +123,9 @@ public class NetworkNotificationManagerTest extends TestCase {
|
|||||||
|
|
||||||
mManager.showNotification(102, NO_INTERNET, mWifiNai, mCellNai, null, false);
|
mManager.showNotification(102, NO_INTERNET, mWifiNai, mCellNai, null, false);
|
||||||
|
|
||||||
verify(mNotificationManager, times(1))
|
final int eventId = NO_INTERNET.eventId;
|
||||||
.notifyAsUser(eq(NOTIFICATION_ID), eq(102), any(), any());
|
final String tag = NetworkNotificationManager.tagFor(102);
|
||||||
|
verify(mNotificationManager, times(1)).notifyAsUser(eq(tag), eq(eventId), any(), any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
|
|||||||
Reference in New Issue
Block a user