blob: 6cdbfed1565c57d0a30ea9c47f0a9f35ba1e1166 [file] [log] [blame]
/*
* Copyright (C) 2019 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.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiConfiguration;
import android.os.Handler;
import android.os.Process;
import android.util.Log;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.wifi.resources.R;
/**
* This class may be used to launch notifications when wifi connections fail.
*/
public class ConnectionFailureNotifier {
private static final String TAG = "ConnectionFailureNotifier";
private Context mContext;
private WifiInjector mWifiInjector;
private FrameworkFacade mFrameworkFacade;
private WifiConfigManager mWifiConfigManager;
private WifiConnectivityManager mWifiConnectivityManager;
private NotificationManager mNotificationManager;
private Handler mHandler;
private ConnectionFailureNotificationBuilder mConnectionFailureNotificationBuilder;
public ConnectionFailureNotifier(
Context context, WifiInjector wifiInjector, FrameworkFacade framework,
WifiConfigManager wifiConfigManager, WifiConnectivityManager wifiConnectivityManager,
Handler handler) {
mContext = context;
mWifiInjector = wifiInjector;
mFrameworkFacade = framework;
mWifiConfigManager = wifiConfigManager;
mWifiConnectivityManager = wifiConnectivityManager;
mNotificationManager = mWifiInjector.getNotificationManager();
mHandler = handler;
mConnectionFailureNotificationBuilder =
mWifiInjector.getConnectionFailureNotificationBuilder();
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectionFailureNotificationBuilder
.ACTION_SHOW_SET_RANDOMIZATION_DETAILS);
mContext.registerReceiver(
new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ConnectionFailureNotificationBuilder
.ACTION_SHOW_SET_RANDOMIZATION_DETAILS)) {
int networkId = intent.getIntExtra(
ConnectionFailureNotificationBuilder
.RANDOMIZATION_SETTINGS_NETWORK_ID,
WifiConfiguration.INVALID_NETWORK_ID);
String ssidAndSecurityType = intent.getStringExtra(
ConnectionFailureNotificationBuilder
.RANDOMIZATION_SETTINGS_NETWORK_SSID);
showRandomizationSettingsDialog(networkId, ssidAndSecurityType);
}
}
}, filter);
}
/**
* Shows a notification which will bring up a dialog which offers the user an option to disable
* MAC randomization on |networkdId|.
* @param networkId
*/
public void showFailedToConnectDueToNoRandomizedMacSupportNotification(int networkId) {
WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(networkId);
if (config == null) {
return;
}
Notification notification = mConnectionFailureNotificationBuilder
.buildNoMacRandomizationSupportNotification(config);
mNotificationManager.notify(SystemMessage.NOTE_NETWORK_NO_MAC_RANDOMIZATION_SUPPORT,
notification);
}
class DisableMacRandomizationListener implements DialogInterface.OnClickListener {
private WifiConfiguration mConfig;
DisableMacRandomizationListener(WifiConfiguration config) {
mConfig = config;
}
@Override
public void onClick(DialogInterface dialog, int which) {
mHandler.post(() -> {
mConfig.macRandomizationSetting =
WifiConfiguration.RANDOMIZATION_NONE;
mWifiConfigManager.addOrUpdateNetwork(mConfig, Process.SYSTEM_UID);
WifiConfiguration updatedConfig =
mWifiConfigManager.getConfiguredNetwork(mConfig.networkId);
if (updatedConfig.macRandomizationSetting
== WifiConfiguration.RANDOMIZATION_NONE) {
String message = mContext.getResources().getString(
R.string.wifi_disable_mac_randomization_dialog_success);
mFrameworkFacade.showToast(mContext, message);
mWifiConfigManager.enableNetwork(updatedConfig.networkId, true,
Process.SYSTEM_UID, null);
mWifiConnectivityManager.forceConnectivityScan(
ClientModeImpl.WIFI_WORK_SOURCE);
} else {
// Shouldn't ever fail, but here for completeness
String message = mContext.getResources().getString(
R.string.wifi_disable_mac_randomization_dialog_failure);
mFrameworkFacade.showToast(mContext, message);
Log.e(TAG, "Failed to modify mac randomization setting");
}
});
}
}
/**
* Class to show a AlertDialog which notifies the user of a network not being privacy
* compliant and then suggests an action.
*/
private void showRandomizationSettingsDialog(int networkId, String ssidAndSecurityType) {
WifiConfiguration config = mWifiConfigManager.getConfiguredNetwork(networkId);
// Make sure the networkId is still pointing to the correct WifiConfiguration since
// there might be a large time gap between when the notification shows and when
// it's tapped.
if (config == null || ssidAndSecurityType == null
|| !ssidAndSecurityType.equals(config.getSsidAndSecurityTypeString())) {
String message = mContext.getResources().getString(
R.string.wifi_disable_mac_randomization_dialog_network_not_found);
mFrameworkFacade.showToast(mContext, message);
return;
}
AlertDialog dialog = mConnectionFailureNotificationBuilder
.buildChangeMacRandomizationSettingDialog(config.SSID,
new DisableMacRandomizationListener(config));
dialog.show();
}
}