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