| /* |
| * 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); |
| } |
| } |