Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b599067 authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

Refactor NetworkNotificationManager.

1. Move from deprecated network types to transport types.
2. Rename and simplify (by passing in a NetworkAgentInfo object)
   the call signature of the method that displays notifications.
3. Add a method to clear notification, and unindent lots of code.
4. Move the legacy DcTracker-issued notification code to
   NetworkNotificationManager.

Bug: 31025214
Change-Id: Ie49c60126d0ed5bac620bc47e84fe038791b2d6c
parent f3ae2eea
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -2929,6 +2929,18 @@
    <!-- A notification is shown when the user connects to a Wi-Fi network and the system detects that that network has no Internet access. This is the notification's message. -->
    <string name="wifi_no_internet_detailed">Tap for options</string>

    <!-- Network type names used in the network_switch_metered and network_switch_metered_detail strings. These must be kept in the sync with the values NetworkCapabilities.TRANSPORT_xxx values, and in the same order. -->
    <string-array name="network_switch_type_name">
        <item>cellular data</item>
        <item>Wi-Fi</item>
        <item>Bluetooth</item>
        <item>Ethernet</item>
        <item>VPN</item>
    </string-array>

    <!-- Network type name displayed if one of the types is not found in network_switch_type_name. -->
    <string name="network_switch_type_name_unknown">an unknown network type</string>

     <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  This is the notification's title / ticker. -->
     <string name="wifi_watchdog_network_disabled">Couldn\'t connect to Wi-Fi</string>
     <!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems.  The complete alert msg is: <hotspot name> + this string, i.e. "Linksys has a poor internet connection" -->
+2 −0
Original line number Diff line number Diff line
@@ -947,6 +947,8 @@
  <java-symbol type="string" name="wifi_available_sign_in" />
  <java-symbol type="string" name="network_available_sign_in" />
  <java-symbol type="string" name="network_available_sign_in_detailed" />
  <java-symbol type="array" name="network_switch_type_name" />
  <java-symbol type="string" name="network_switch_type_name_unknown" />
  <java-symbol type="string" name="wifi_no_internet" />
  <java-symbol type="string" name="wifi_no_internet_detailed" />
  <java-symbol type="string" name="wifi_connect_alert_title" />
+11 −11
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import static android.net.NetworkPolicyManager.uidRulesToString;

import android.annotation.Nullable;
import android.app.BroadcastOptions;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -833,7 +834,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
        mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);

        mKeepaliveTracker = new KeepaliveTracker(mHandler);
        mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager);
        mNotifier = new NetworkNotificationManager(mContext, mTelephonyManager,
                mContext.getSystemService(NotificationManager.class));
    }

    private NetworkRequest createInternetRequestForTransport(int transportType) {
@@ -2232,17 +2234,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
                        updateCapabilities(nai, nai.networkCapabilities);
                    }
                    if (!visible) {
                        mNotifier.setProvNotificationVisibleIntent(false, netId, null, 0, null,
                                null, false);
                        mNotifier.clearNotification(netId);
                    } else {
                        if (nai == null) {
                            loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
                            break;
                        }
                        if (!nai.networkMisc.provisioningNotificationDisabled) {
                            mNotifier.setProvNotificationVisibleIntent(true, netId,
                                    NotificationType.SIGN_IN,
                                    nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(),
                            mNotifier.showNotification(netId, NotificationType.SIGN_IN, nai,
                                    (PendingIntent) msg.obj, nai.networkMisc.explicitlySelected);
                        }
                    }
@@ -2714,9 +2713,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
        PendingIntent pendingIntent = PendingIntent.getActivityAsUser(
                mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);

        mNotifier.setProvNotificationVisibleIntent(true, nai.network.netId,
                NotificationType.NO_INTERNET, nai.networkInfo.getType(),
                nai.networkInfo.getExtraInfo(), pendingIntent, true);
        mNotifier.showNotification(nai.network.netId, NotificationType.NO_INTERNET, nai,
                pendingIntent, true);
    }

    private class InternalHandler extends Handler {
@@ -3725,7 +3723,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
        enforceConnectivityInternalPermission();
        final long ident = Binder.clearCallingIdentity();
        try {
            mNotifier.setProvNotificationVisible(visible, networkType, action);
            // Concatenate the range of types onto the range of NetIDs.
            int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
            mNotifier.setProvNotificationVisible(visible, id, action);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
+118 −86
Original line number Diff line number Diff line
@@ -20,15 +20,16 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.os.UserHandle;
import android.telephony.TelephonyManager;
import android.util.Slog;

import com.android.internal.R;

import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.NetworkCapabilities.*;


public class NetworkNotificationManager {
@@ -43,10 +44,36 @@ public class NetworkNotificationManager {

    private final Context mContext;
    private final TelephonyManager mTelephonyManager;
    private final NotificationManager mNotificationManager;

    public NetworkNotificationManager(Context context, TelephonyManager telephonyManager) {
        mContext = context;
        mTelephonyManager = telephonyManager;
    public NetworkNotificationManager(Context c, TelephonyManager t, NotificationManager n) {
        mContext = c;
        mTelephonyManager = t;
        mNotificationManager = n;
    }

    // TODO: deal more gracefully with multi-transport networks.
    private static int getFirstTransportType(NetworkAgentInfo nai) {
        for (int i = 0; i < 64; i++) {
            if (nai.networkCapabilities.hasTransport(i)) return i;
        }
        return -1;
    }

    private static String getTransportName(int transportType) {
        Resources r = Resources.getSystem();
        String[] networkTypes = r.getStringArray(R.array.network_switch_type_name);
        try {
            return networkTypes[transportType];
        } catch (IndexOutOfBoundsException e) {
            return r.getString(R.string.network_switch_type_name_unknown);
        }
    }

    private static int getIcon(int transportType) {
        return (transportType == TRANSPORT_WIFI) ?
                R.drawable.stat_notify_wifi_in_range :  // TODO: Distinguish ! from ?.
                R.drawable.stat_notify_rssi_in_range;
    }

    /**
@@ -64,54 +91,54 @@ public class NetworkNotificationManager {
     *         between show and hide calls.  We use the NetID value but for legacy callers
     *         we concatenate the range of types with the range of NetIDs.
     */
    public void setProvNotificationVisibleIntent(boolean visible, int id,
            NotificationType notifyType, int networkType, String extraInfo, PendingIntent intent,
            boolean highPriority) {
        if (VDBG || (DBG && visible)) {
            Slog.d(TAG, "setProvNotificationVisibleIntent " + notifyType + " visible=" + visible
                    + " networkType=" + getNetworkTypeName(networkType)
    public void showNotification(int id, NotificationType notifyType,
            NetworkAgentInfo nai, PendingIntent intent, boolean highPriority) {
        int transportType;
        String extraInfo;
        if (nai != null) {
            transportType = getFirstTransportType(nai);
            extraInfo = nai.networkInfo.getExtraInfo();
            // Only notify for Internet-capable networks.
            if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)) return;
        } else {
            // Legacy notifications.
            transportType = TRANSPORT_CELLULAR;
            extraInfo = null;
        }

        if (DBG) {
            Slog.d(TAG, "showNotification " + notifyType
                    + " transportType=" + getTransportName(transportType)
                    + " extraInfo=" + extraInfo + " highPriority=" + highPriority);
        }

        Resources r = Resources.getSystem();
        NotificationManager notificationManager = (NotificationManager) mContext
            .getSystemService(Context.NOTIFICATION_SERVICE);

        if (visible) {
        CharSequence title;
        CharSequence details;
            int icon;
            if (notifyType == NotificationType.NO_INTERNET &&
                    networkType == ConnectivityManager.TYPE_WIFI) {
        int icon = getIcon(transportType);
        if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
            title = r.getString(R.string.wifi_no_internet, 0);
            details = r.getString(R.string.wifi_no_internet_detailed);
                icon = R.drawable.stat_notify_wifi_in_range;  // TODO: Need new icon.
        } else if (notifyType == NotificationType.SIGN_IN) {
                switch (networkType) {
                    case ConnectivityManager.TYPE_WIFI:
            switch (transportType) {
                case TRANSPORT_WIFI:
                    title = r.getString(R.string.wifi_available_sign_in, 0);
                        details = r.getString(R.string.network_available_sign_in_detailed,
                                extraInfo);
                        icon = R.drawable.stat_notify_wifi_in_range;
                    details = r.getString(R.string.network_available_sign_in_detailed, extraInfo);
                    break;
                    case ConnectivityManager.TYPE_MOBILE:
                    case ConnectivityManager.TYPE_MOBILE_HIPRI:
                case TRANSPORT_CELLULAR:
                    title = r.getString(R.string.network_available_sign_in, 0);
                    // TODO: Change this to pull from NetworkInfo once a printable
                    // name has been added to it
                    details = mTelephonyManager.getNetworkOperatorName();
                        icon = R.drawable.stat_notify_rssi_in_range;
                    break;
                default:
                    title = r.getString(R.string.network_available_sign_in, 0);
                        details = r.getString(R.string.network_available_sign_in_detailed,
                                extraInfo);
                        icon = R.drawable.stat_notify_rssi_in_range;
                    details = r.getString(R.string.network_available_sign_in_detailed, extraInfo);
                    break;
            }
        } else {
                Slog.wtf(TAG, "Unknown notification type " + notifyType + "on network type "
                        + getNetworkTypeName(networkType));
            Slog.wtf(TAG, "Unknown notification type " + notifyType + "on network transport "
                    + getTransportName(transportType));
            return;
        }

@@ -134,28 +161,33 @@ public class NetworkNotificationManager {
                .build();

        try {
                notificationManager.notifyAsUser(NOTIFICATION_ID, id, notification, UserHandle.ALL);
            mNotificationManager.notifyAsUser(NOTIFICATION_ID, id, notification, UserHandle.ALL);
        } catch (NullPointerException npe) {
            Slog.d(TAG, "setNotificationVisible: visible notificationManager npe=" + npe);
        }
        } else {
    }

    public void clearNotification(int id) {
        if (DBG) {
            Slog.d(TAG, "clearNotification id=" + id);
        }
        try {
                notificationManager.cancelAsUser(NOTIFICATION_ID, id, UserHandle.ALL);
            mNotificationManager.cancelAsUser(NOTIFICATION_ID, id, UserHandle.ALL);
        } catch (NullPointerException npe) {
            Slog.d(TAG, "setNotificationVisible: cancel notificationManager npe=" + npe);
        }
    }
    }

    /**
     * Legacy provisioning notifications coming directly from DcTracker.
     */
    public void setProvNotificationVisible(boolean visible, int networkType, String action) {
    public void setProvNotificationVisible(boolean visible, int id, String action) {
        if (visible) {
            Intent intent = new Intent(action);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
        // Concatenate the range of types onto the range of NetIDs.
        int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
        mNotifier.setProvNotificationVisibleIntent(visible, id, NotificationType.SIGN_IN,
                networkType, null, pendingIntent, false);
            showNotification(id, NotificationType.SIGN_IN, null, pendingIntent, false);
        } else {
            clearNotification(id);
        }
    }
}