• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.AlertDialog;
20 import android.app.Notification;
21 import android.content.BroadcastReceiver;
22 import android.content.Context;
23 import android.content.DialogInterface;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.net.wifi.WifiConfiguration;
27 import android.os.Handler;
28 import android.os.Process;
29 import android.util.Log;
30 
31 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
32 import com.android.wifi.resources.R;
33 
34 /**
35  * This class may be used to launch notifications when wifi connections fail.
36  */
37 public class ConnectionFailureNotifier {
38     private static final String TAG = "ConnectionFailureNotifier";
39 
40     private final WifiContext mContext;
41     private final FrameworkFacade mFrameworkFacade;
42     private final WifiConfigManager mWifiConfigManager;
43     private final WifiConnectivityManager mWifiConnectivityManager;
44     private final WifiNotificationManager mNotificationManager;
45     private final Handler mHandler;
46     private final ConnectionFailureNotificationBuilder mConnectionFailureNotificationBuilder;
47 
ConnectionFailureNotifier( WifiContext context, FrameworkFacade framework, WifiConfigManager wifiConfigManager, WifiConnectivityManager wifiConnectivityManager, Handler handler, WifiNotificationManager notificationManager, ConnectionFailureNotificationBuilder connectionFailureNotificationBuilder)48     public ConnectionFailureNotifier(
49             WifiContext context,
50             FrameworkFacade framework,
51             WifiConfigManager wifiConfigManager,
52             WifiConnectivityManager wifiConnectivityManager,
53             Handler handler,
54             WifiNotificationManager notificationManager,
55             ConnectionFailureNotificationBuilder connectionFailureNotificationBuilder) {
56         mContext = context;
57         mFrameworkFacade = framework;
58         mWifiConfigManager = wifiConfigManager;
59         mWifiConnectivityManager = wifiConnectivityManager;
60         mNotificationManager = notificationManager;
61         mHandler = handler;
62         mConnectionFailureNotificationBuilder = connectionFailureNotificationBuilder;
63 
64         IntentFilter filter = new IntentFilter();
65         filter.addAction(ConnectionFailureNotificationBuilder
66                 .ACTION_SHOW_SET_RANDOMIZATION_DETAILS);
67         mContext.registerReceiver(
68                 new BroadcastReceiver() {
69                     @Override
70                     public void onReceive(Context context, Intent intent) {
71                         String action = intent.getAction();
72                         if (action.equals(ConnectionFailureNotificationBuilder
73                                 .ACTION_SHOW_SET_RANDOMIZATION_DETAILS)) {
74                             int networkId = intent.getIntExtra(
75                                     ConnectionFailureNotificationBuilder
76                                             .RANDOMIZATION_SETTINGS_NETWORK_ID,
77                                     WifiConfiguration.INVALID_NETWORK_ID);
78                             String ssidAndSecurityType = intent.getStringExtra(
79                                     ConnectionFailureNotificationBuilder
80                                             .RANDOMIZATION_SETTINGS_NETWORK_SSID);
81                             showRandomizationSettingsDialog(networkId, ssidAndSecurityType);
82                         }
83                     }
84                 }, filter);
85     }
86 
87     /**
88      * Shows a notification which will bring up a dialog which offers the user an option to disable
89      * MAC randomization on |networkdId|.
90      * @param networkId
91      */
showFailedToConnectDueToNoRandomizedMacSupportNotification(int networkId)92     public void showFailedToConnectDueToNoRandomizedMacSupportNotification(int networkId) {
93         WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(networkId);
94         if (config == null) {
95             return;
96         }
97         Notification notification = mConnectionFailureNotificationBuilder
98                 .buildNoMacRandomizationSupportNotification(config);
99         mNotificationManager.notify(SystemMessage.NOTE_NETWORK_NO_MAC_RANDOMIZATION_SUPPORT,
100                 notification);
101     }
102 
103     class DisableMacRandomizationListener implements DialogInterface.OnClickListener {
104         private WifiConfiguration mConfig;
105 
DisableMacRandomizationListener(WifiConfiguration config)106         DisableMacRandomizationListener(WifiConfiguration config) {
107             mConfig = config;
108         }
109 
110         @Override
onClick(DialogInterface dialog, int which)111         public void onClick(DialogInterface dialog, int which) {
112             mHandler.post(() -> {
113                 mConfig.macRandomizationSetting =
114                         WifiConfiguration.RANDOMIZATION_NONE;
115                 mWifiConfigManager.addOrUpdateNetwork(mConfig, Process.SYSTEM_UID);
116                 WifiConfiguration updatedConfig =
117                         mWifiConfigManager.getConfiguredNetwork(mConfig.networkId);
118                 if (updatedConfig.macRandomizationSetting
119                         == WifiConfiguration.RANDOMIZATION_NONE) {
120                     String message = mContext.getResources().getString(
121                             R.string.wifi_disable_mac_randomization_dialog_success);
122                     mFrameworkFacade.showToast(mContext, message);
123                     mWifiConfigManager.enableNetwork(updatedConfig.networkId, true,
124                             Process.SYSTEM_UID, null);
125                     mWifiConnectivityManager.forceConnectivityScan(
126                             ClientModeImpl.WIFI_WORK_SOURCE);
127                 } else {
128                     // Shouldn't ever fail, but here for completeness
129                     String message = mContext.getResources().getString(
130                             R.string.wifi_disable_mac_randomization_dialog_failure);
131                     mFrameworkFacade.showToast(mContext, message);
132                     Log.e(TAG, "Failed to modify mac randomization setting");
133                 }
134             });
135         }
136     }
137 
138     /**
139      * Class to show a AlertDialog which notifies the user of a network not being privacy
140      * compliant and then suggests an action.
141      */
showRandomizationSettingsDialog(int networkId, String ssidAndSecurityType)142     private void showRandomizationSettingsDialog(int networkId, String ssidAndSecurityType) {
143         WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(networkId);
144         // Make sure the networkId is still pointing to the correct WifiConfiguration since
145         // there might be a large time gap between when the notification shows and when
146         // it's tapped.
147         if (config == null || ssidAndSecurityType == null
148                 || !ssidAndSecurityType.equals(config.getSsidAndSecurityTypeString())) {
149             String message = mContext.getResources().getString(
150                     R.string.wifi_disable_mac_randomization_dialog_network_not_found);
151             mFrameworkFacade.showToast(mContext, message);
152             return;
153         }
154 
155         AlertDialog dialog = mConnectionFailureNotificationBuilder
156                 .buildChangeMacRandomizationSettingDialog(config.SSID,
157                         new DisableMacRandomizationListener(config));
158         dialog.show();
159     }
160 }
161