/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wifi; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.provider.Settings; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.server.wifi.util.NativeUtil; /** * Responsible for notifying user for wrong password errors. */ public class WrongPasswordNotifier { // Number of milliseconds to wait before automatically dismiss the notification. private static final long CANCEL_TIMEOUT_MILLISECONDS = 5 * 60 * 1000; // Unique ID associated with the notification. @VisibleForTesting public static final int NOTIFICATION_ID = SystemMessage.NOTE_WIFI_WRONG_PASSWORD; // Flag indicating if a wrong password error is detected for the current connection. private boolean mWrongPasswordDetected; private final Context mContext; private final NotificationManager mNotificationManager; private final FrameworkFacade mFrameworkFacade; public WrongPasswordNotifier(Context context, FrameworkFacade frameworkFacade) { mContext = context; mFrameworkFacade = frameworkFacade; mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); } /** * Invoked when a wrong password error for a Wi-Fi network is detected. * * @param ssid The SSID of the Wi-Fi network */ public void onWrongPasswordError(String ssid) { showNotification(ssid); mWrongPasswordDetected = true; } /** * Invoked when attempting a new Wi-Fi network connection. */ public void onNewConnectionAttempt() { if (mWrongPasswordDetected) { dismissNotification(); mWrongPasswordDetected = false; } } /** * Display wrong password notification for a given Wi-Fi network (specified by its SSID). * * @param ssid SSID of the Wi-FI network */ private void showNotification(String ssid) { Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS); intent.putExtra("wifi_start_connect_ssid", NativeUtil.removeEnclosingQuotes(ssid)); Notification.Builder builder = mFrameworkFacade.makeNotificationBuilder(mContext, SystemNotificationChannels.NETWORK_ALERTS) .setAutoCancel(true) .setTimeoutAfter(CANCEL_TIMEOUT_MILLISECONDS) // TODO(zqiu): consider creating a new icon. .setSmallIcon(com.android.internal.R.drawable.stat_notify_wifi_in_range) .setContentTitle(mContext.getString( com.android.internal.R.string.wifi_available_title_failed_to_connect)) .setContentText(ssid) .setContentIntent(mFrameworkFacade.getActivity( mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)) .setColor(mContext.getResources().getColor( com.android.internal.R.color.system_notification_accent_color)); mNotificationManager.notify(NOTIFICATION_ID, builder.build()); } /** * Dismiss the notification that was generated by {@link #showNotification}. The notification * might have already been dismissed, either by user or timeout. We'll attempt to dismiss it * regardless if it is been dismissed or not, to reduce code complexity. */ private void dismissNotification() { // Notification might have already been dismissed, either by user or timeout. It is // still okay to cancel it if already dismissed. mNotificationManager.cancel(null, NOTIFICATION_ID); } }