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.settings.wifi.details2; 18 19 import android.content.Context; 20 import android.net.wifi.WifiConfiguration; 21 import android.net.wifi.WifiManager; 22 23 import androidx.annotation.VisibleForTesting; 24 import androidx.preference.DropDownPreference; 25 import androidx.preference.Preference; 26 import androidx.preference.PreferenceScreen; 27 28 import com.android.settings.R; 29 import com.android.settings.core.BasePreferenceController; 30 import com.android.settings.wifi.WifiDialog2; 31 import com.android.wifitrackerlib.WifiEntry; 32 33 /** 34 * {@link AbstractPreferenceController} that controls whether the wifi network is mac randomized 35 * or not 36 */ 37 public class WifiPrivacyPreferenceController2 extends BasePreferenceController implements 38 Preference.OnPreferenceChangeListener, WifiDialog2.WifiDialog2Listener { 39 40 private static final String KEY_WIFI_PRIVACY = "privacy"; 41 private WifiManager mWifiManager; 42 private WifiEntry mWifiEntry; 43 private Preference mPreference; 44 WifiPrivacyPreferenceController2(Context context)45 public WifiPrivacyPreferenceController2(Context context) { 46 super(context, KEY_WIFI_PRIVACY); 47 48 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 49 } 50 setWifiEntry(WifiEntry wifiEntry)51 public void setWifiEntry(WifiEntry wifiEntry) { 52 mWifiEntry = wifiEntry; 53 } 54 55 @Override getAvailabilityStatus()56 public int getAvailabilityStatus() { 57 return mWifiManager.isConnectedMacRandomizationSupported() 58 ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; 59 } 60 61 @Override displayPreference(PreferenceScreen screen)62 public void displayPreference(PreferenceScreen screen) { 63 super.displayPreference(screen); 64 mPreference = screen.findPreference(getPreferenceKey()); 65 } 66 67 @Override updateState(Preference preference)68 public void updateState(Preference preference) { 69 final DropDownPreference dropDownPreference = (DropDownPreference) preference; 70 final int randomizationLevel = getRandomizationValue(); 71 final boolean isSelectable = mWifiEntry.canSetPrivacy(); 72 preference.setSelectable(isSelectable); 73 dropDownPreference.setValue(Integer.toString(randomizationLevel)); 74 updateSummary(dropDownPreference, randomizationLevel); 75 76 // If the preference cannot be selectable, display a temporary network in the summary. 77 if (!isSelectable) { 78 dropDownPreference.setSummary(R.string.wifi_privacy_settings_ephemeral_summary); 79 } 80 } 81 82 @Override onPreferenceChange(Preference preference, Object newValue)83 public boolean onPreferenceChange(Preference preference, Object newValue) { 84 final int privacy = Integer.parseInt((String) newValue); 85 mWifiEntry.setPrivacy(privacy); 86 87 // To activate changing, we need to reconnect network. WiFi will auto connect to 88 // current network after disconnect(). Only needed when this is connected network. 89 if (mWifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) { 90 mWifiEntry.disconnect(null /* callback */); 91 mWifiEntry.connect(null /* callback */); 92 } 93 updateSummary((DropDownPreference) preference, privacy); 94 return true; 95 } 96 97 @VisibleForTesting getRandomizationValue()98 int getRandomizationValue() { 99 return mWifiEntry.getPrivacy(); 100 } 101 102 private static final int PREF_RANDOMIZATION_PERSISTENT = 0; 103 private static final int PREF_RANDOMIZATION_NONE = 1; 104 105 /** 106 * Returns preference index value. 107 * 108 * @param macRandomized is mac randomized value 109 * @return index value of preference 110 */ translateMacRandomizedValueToPrefValue(int macRandomized)111 public static int translateMacRandomizedValueToPrefValue(int macRandomized) { 112 return (macRandomized == WifiEntry.PRIVACY_RANDOMIZED_MAC) 113 ? PREF_RANDOMIZATION_PERSISTENT : PREF_RANDOMIZATION_NONE; 114 } 115 116 /** 117 * Returns mac randomized value. 118 * 119 * @param prefMacRandomized is preference index value 120 * @return mac randomized value 121 */ translatePrefValueToMacRandomizedValue(int prefMacRandomized)122 public static int translatePrefValueToMacRandomizedValue(int prefMacRandomized) { 123 return (prefMacRandomized == PREF_RANDOMIZATION_PERSISTENT) 124 ? WifiEntry.PRIVACY_RANDOMIZED_MAC : WifiEntry.PRIVACY_DEVICE_MAC; 125 } 126 updateSummary(DropDownPreference preference, int macRandomized)127 private void updateSummary(DropDownPreference preference, int macRandomized) { 128 // Translates value here to set RANDOMIZATION_PERSISTENT as first item in UI for better UX. 129 final int prefMacRandomized = translateMacRandomizedValueToPrefValue(macRandomized); 130 preference.setSummary(preference.getEntries()[prefMacRandomized]); 131 } 132 133 @Override onSubmit(WifiDialog2 dialog)134 public void onSubmit(WifiDialog2 dialog) { 135 if (dialog.getController() != null) { 136 final WifiConfiguration newConfig = dialog.getController().getConfig(); 137 if (newConfig == null) { 138 return; 139 } 140 141 if (getWifiEntryPrivacy(newConfig) != mWifiEntry.getPrivacy()) { 142 mWifiEntry.setPrivacy(getWifiEntryPrivacy(newConfig)); 143 onPreferenceChange(mPreference, String.valueOf(newConfig.macRandomizationSetting)); 144 } 145 } 146 } 147 getWifiEntryPrivacy(WifiConfiguration wifiConfiguration)148 private int getWifiEntryPrivacy(WifiConfiguration wifiConfiguration) { 149 switch (wifiConfiguration.macRandomizationSetting) { 150 case WifiConfiguration.RANDOMIZATION_NONE: 151 return WifiEntry.PRIVACY_DEVICE_MAC; 152 case WifiConfiguration.RANDOMIZATION_PERSISTENT: 153 return WifiEntry.PRIVACY_RANDOMIZED_MAC; 154 default: 155 return WifiEntry.PRIVACY_UNKNOWN; 156 } 157 } 158 } 159