Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.wifi;
     18 
     19 import android.app.Notification;
     20 import android.app.PendingIntent;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.res.Resources;
     24 import android.net.wifi.ScanResult;
     25 import android.util.Log;
     26 
     27 import com.android.internal.R;
     28 import com.android.internal.notification.SystemNotificationChannels;
     29 
     30 /**
     31  * Helper to create notifications for {@link OpenNetworkNotifier}.
     32  */
     33 public class ConnectToNetworkNotificationBuilder {
     34 
     35     /** Intent when user dismissed the "Connect to Network" notification. */
     36     public static final String ACTION_USER_DISMISSED_NOTIFICATION =
     37             "com.android.server.wifi.ConnectToNetworkNotification.USER_DISMISSED_NOTIFICATION";
     38 
     39     /** Intent when user tapped action button to connect to recommended network. */
     40     public static final String ACTION_CONNECT_TO_NETWORK =
     41             "com.android.server.wifi.ConnectToNetworkNotification.CONNECT_TO_NETWORK";
     42 
     43     /** Intent when user tapped action button to open Wi-Fi Settings. */
     44     public static final String ACTION_PICK_WIFI_NETWORK =
     45             "com.android.server.wifi.ConnectToNetworkNotification.PICK_WIFI_NETWORK";
     46 
     47     /** Intent when user tapped "Failed to connect" notification to open Wi-Fi Settings. */
     48     public static final String ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE =
     49             "com.android.server.wifi.ConnectToNetworkNotification.PICK_NETWORK_AFTER_FAILURE";
     50 
     51     /** Extra data added to the Intent to specify the registering network notifier. */
     52     public static final String AVAILABLE_NETWORK_NOTIFIER_TAG =
     53             "com.android.server.wifi.ConnectToNetworkNotification.AVAILABLE_NETWORK_NOTIFIER_TAG";
     54 
     55     private Context mContext;
     56     private Resources mResources;
     57     private FrameworkFacade mFrameworkFacade;
     58 
     59     public ConnectToNetworkNotificationBuilder(
     60             Context context,
     61             FrameworkFacade framework) {
     62         mContext = context;
     63         mResources = context.getResources();
     64         mFrameworkFacade = framework;
     65     }
     66 
     67     /**
     68      * Creates the connect to network notification that alerts users of a recommended connectable
     69      * network.
     70      *
     71      * There are two actions - "Options" link to the Wi-Fi picker activity, and "Connect" prompts
     72      * the connection to the recommended network.
     73      *
     74      * @param notifierTag Unique tag of calling network notifier
     75      * @param network The network to be recommended
     76      */
     77     public Notification createConnectToAvailableNetworkNotification(String notifierTag,
     78             ScanResult network) {
     79         CharSequence title;
     80         switch (notifierTag) {
     81             case OpenNetworkNotifier.TAG:
     82                 title = mContext.getText(R.string.wifi_available_title);
     83                 break;
     84             case CarrierNetworkNotifier.TAG:
     85                 title = mContext.getText(R.string.wifi_available_carrier_network_title);
     86                 break;
     87             default:
     88                 Log.wtf("ConnectToNetworkNotificationBuilder", "Unknown network notifier."
     89                         + notifierTag);
     90                 return null;
     91         }
     92         Notification.Action connectAction = new Notification.Action.Builder(null /* icon */,
     93                 mResources.getText(R.string.wifi_available_action_connect),
     94                 getPrivateBroadcast(ACTION_CONNECT_TO_NETWORK, notifierTag)).build();
     95         Notification.Action allNetworksAction = new Notification.Action.Builder(null /* icon */,
     96                 mResources.getText(R.string.wifi_available_action_all_networks),
     97                 getPrivateBroadcast(ACTION_PICK_WIFI_NETWORK, notifierTag)).build();
     98         return createNotificationBuilder(title, network.SSID, notifierTag)
     99                 .setContentIntent(getPrivateBroadcast(ACTION_PICK_WIFI_NETWORK, notifierTag))
    100                 .addAction(connectAction)
    101                 .addAction(allNetworksAction)
    102                 .build();
    103     }
    104 
    105     /**
    106      * Creates the notification that indicates the controller is attempting to connect to the
    107      * recommended network.
    108      *
    109      * @param notifierTag Unique tag of the calling network notifier
    110      * @param network The network to be recommended
    111      */
    112     public Notification createNetworkConnectingNotification(String notifierTag,
    113             ScanResult network) {
    114         return createNotificationBuilder(
    115                 mContext.getText(R.string.wifi_available_title_connecting), network.SSID,
    116                         notifierTag)
    117                 .setProgress(0 /* max */, 0 /* progress */, true /* indeterminate */)
    118                 .build();
    119     }
    120 
    121     /**
    122      * Creates the notification that indicates the controller successfully connected to the
    123      * recommended network.
    124      *
    125      * @param notifierTag Unique tag of the calling network notifier
    126      * @param network The network to be recommended
    127      */
    128     public Notification createNetworkConnectedNotification(String notifierTag, ScanResult network) {
    129         return createNotificationBuilder(
    130                 mContext.getText(R.string.wifi_available_title_connected), network.SSID,
    131                         notifierTag)
    132                 .build();
    133     }
    134 
    135     /**
    136      * Creates the notification that indicates the controller failed to connect to the recommended
    137      * network. Tapping this notification opens the wifi picker.
    138      *
    139      * @param notifierTag Unique tag of the calling network notifier
    140      */
    141     public Notification createNetworkFailedNotification(String notifierTag) {
    142         return createNotificationBuilder(
    143                 mContext.getText(R.string.wifi_available_title_failed_to_connect),
    144                 mContext.getText(R.string.wifi_available_content_failed_to_connect), notifierTag)
    145                 .setContentIntent(
    146                         getPrivateBroadcast(ACTION_PICK_WIFI_NETWORK_AFTER_CONNECT_FAILURE,
    147                                 notifierTag))
    148                 .setAutoCancel(true)
    149                 .build();
    150     }
    151 
    152     private int getNotifierRequestCode(String notifierTag) {
    153         switch (notifierTag) {
    154             case OpenNetworkNotifier.TAG:
    155                 return 1;
    156             case CarrierNetworkNotifier.TAG:
    157                 return 2;
    158         }
    159         return 0;
    160     }
    161 
    162     private Notification.Builder createNotificationBuilder(
    163             CharSequence title, CharSequence content, String extraData) {
    164         return mFrameworkFacade.makeNotificationBuilder(mContext,
    165                 SystemNotificationChannels.NETWORK_AVAILABLE)
    166                 .setSmallIcon(R.drawable.stat_notify_wifi_in_range)
    167                 .setTicker(title)
    168                 .setContentTitle(title)
    169                 .setContentText(content)
    170                 .setDeleteIntent(getPrivateBroadcast(ACTION_USER_DISMISSED_NOTIFICATION, extraData))
    171                 .setShowWhen(false)
    172                 .setLocalOnly(true)
    173                 .setColor(mResources.getColor(R.color.system_notification_accent_color,
    174                         mContext.getTheme()));
    175     }
    176 
    177     private PendingIntent getPrivateBroadcast(String action, String extraData) {
    178         Intent intent = new Intent(action).setPackage("android");
    179         int requestCode = 0;  // Makes the different kinds of notifications distinguishable
    180         if (extraData != null) {
    181             intent.putExtra(AVAILABLE_NETWORK_NOTIFIER_TAG, extraData);
    182             requestCode = getNotifierRequestCode(extraData);
    183         }
    184         return mFrameworkFacade.getBroadcast(mContext, requestCode, intent,
    185                 PendingIntent.FLAG_UPDATE_CURRENT);
    186     }
    187 }
    188