DO NOT MERGE Network notifications: revamp keying scheme

am: e9c9d4bf0c

Change-Id: Ibad7d0210b2c69826462b781f43a82d65849ebfb
This commit is contained in:
Hugo Benichi
2016-12-19 08:29:23 +00:00
committed by android-build-merger
2 changed files with 70 additions and 25 deletions

View File

@@ -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";
}
} }

View File

@@ -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