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.NotificationManager;
     21 import android.app.PendingIntent;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.provider.Settings;
     25 
     26 import com.android.internal.annotations.VisibleForTesting;
     27 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
     28 import com.android.internal.notification.SystemNotificationChannels;
     29 import com.android.server.wifi.util.NativeUtil;
     30 
     31 /**
     32  * Responsible for notifying user for wrong password errors.
     33  */
     34 public class WrongPasswordNotifier {
     35     // Number of milliseconds to wait before automatically dismiss the notification.
     36     private static final long CANCEL_TIMEOUT_MILLISECONDS = 5 * 60 * 1000;
     37 
     38     // Unique ID associated with the notification.
     39     @VisibleForTesting
     40     public static final int NOTIFICATION_ID = SystemMessage.NOTE_WIFI_WRONG_PASSWORD;
     41 
     42     // Flag indicating if a wrong password error is detected for the current connection.
     43     private boolean mWrongPasswordDetected;
     44 
     45     private final Context mContext;
     46     private final NotificationManager mNotificationManager;
     47     private final FrameworkFacade mFrameworkFacade;
     48 
     49     public WrongPasswordNotifier(Context context, FrameworkFacade frameworkFacade) {
     50         mContext = context;
     51         mFrameworkFacade = frameworkFacade;
     52         mNotificationManager =
     53                 (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
     54     }
     55 
     56     /**
     57      * Invoked when a wrong password error for a Wi-Fi network is detected.
     58      *
     59      * @param ssid The SSID of the Wi-Fi network
     60      */
     61     public void onWrongPasswordError(String ssid) {
     62         showNotification(ssid);
     63         mWrongPasswordDetected = true;
     64     }
     65 
     66     /**
     67      * Invoked when attempting a new Wi-Fi network connection.
     68      */
     69     public void onNewConnectionAttempt() {
     70         if (mWrongPasswordDetected) {
     71             dismissNotification();
     72             mWrongPasswordDetected = false;
     73         }
     74     }
     75 
     76     /**
     77      * Display wrong password notification for a given Wi-Fi network (specified by its SSID).
     78      *
     79      * @param ssid SSID of the Wi-FI network
     80      */
     81     private void showNotification(String ssid) {
     82         Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
     83         intent.putExtra("wifi_start_connect_ssid", NativeUtil.removeEnclosingQuotes(ssid));
     84         Notification.Builder builder = mFrameworkFacade.makeNotificationBuilder(mContext,
     85                 SystemNotificationChannels.NETWORK_ALERTS)
     86                 .setAutoCancel(true)
     87                 .setTimeoutAfter(CANCEL_TIMEOUT_MILLISECONDS)
     88                 // TODO(zqiu): consider creating a new icon.
     89                 .setSmallIcon(com.android.internal.R.drawable.stat_notify_wifi_in_range)
     90                 .setContentTitle(mContext.getString(
     91                         com.android.internal.R.string.wifi_available_title_failed_to_connect))
     92                 .setContentText(ssid)
     93                 .setContentIntent(mFrameworkFacade.getActivity(
     94                         mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT))
     95                 .setColor(mContext.getResources().getColor(
     96                         com.android.internal.R.color.system_notification_accent_color));
     97         mNotificationManager.notify(NOTIFICATION_ID, builder.build());
     98     }
     99 
    100     /**
    101      * Dismiss the notification that was generated by {@link #showNotification}. The notification
    102      * might have already been dismissed, either by user or timeout. We'll attempt to dismiss it
    103      * regardless if it is been dismissed or not, to reduce code complexity.
    104      */
    105     private void dismissNotification() {
    106         // Notification might have already been dismissed, either by user or timeout. It is
    107         // still okay to cancel it if already dismissed.
    108         mNotificationManager.cancel(null, NOTIFICATION_ID);
    109     }
    110 }
    111