1 /*
2  * Copyright (C) 2017 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.tether;
18 
19 import android.app.settings.SettingsEnums;
20 import android.content.Context;
21 import android.net.wifi.SoftApConfiguration;
22 import android.text.TextUtils;
23 
24 import androidx.annotation.VisibleForTesting;
25 import androidx.preference.EditTextPreference;
26 import androidx.preference.Preference;
27 
28 import com.android.settings.R;
29 import com.android.settings.overlay.FeatureFactory;
30 import com.android.settings.widget.ValidatedEditTextPreference;
31 import com.android.settings.wifi.WifiUtils;
32 import com.android.settings.wifi.repository.WifiHotspotRepository;
33 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
34 
35 /**
36  * Controller for logic pertaining to the password of Wi-Fi tethering.
37  */
38 public class WifiTetherPasswordPreferenceController extends WifiTetherBasePreferenceController
39         implements ValidatedEditTextPreference.Validator {
40 
41     private static final String PREF_KEY = "wifi_tether_network_password";
42 
43     private String mPassword;
44     private int mSecurityType;
45 
46     private final MetricsFeatureProvider mMetricsFeatureProvider;
47     private final WifiHotspotRepository mWifiHotspotRepository;
48 
49     @VisibleForTesting
WifiTetherPasswordPreferenceController(Context context, OnTetherConfigUpdateListener listener, MetricsFeatureProvider provider)50     WifiTetherPasswordPreferenceController(Context context, OnTetherConfigUpdateListener listener,
51             MetricsFeatureProvider provider) {
52         super(context, listener);
53         FeatureFactory featureFactory = FeatureFactory.getFeatureFactory();
54         mMetricsFeatureProvider = (provider != null) ? provider
55                 : featureFactory.getMetricsFeatureProvider();
56         mWifiHotspotRepository = featureFactory.getWifiFeatureProvider().getWifiHotspotRepository();
57         mWifiHotspotRepository.queryLastPasswordIfNeeded();
58     }
59 
WifiTetherPasswordPreferenceController(Context context, OnTetherConfigUpdateListener listener)60     public WifiTetherPasswordPreferenceController(Context context,
61             OnTetherConfigUpdateListener listener) {
62         this(context, listener, null /* MetricsFeatureProvider */);
63     }
64 
65     @Override
getPreferenceKey()66     public String getPreferenceKey() {
67         return PREF_KEY;
68     }
69 
70     @Override
updateDisplay()71     public void updateDisplay() {
72         final SoftApConfiguration config = mWifiManager.getSoftApConfiguration();
73         if (config.getSecurityType() != SoftApConfiguration.SECURITY_TYPE_OPEN
74                 && TextUtils.isEmpty(config.getPassphrase())) {
75             mPassword = mWifiHotspotRepository.generatePassword();
76         } else {
77             mPassword = config.getPassphrase();
78         }
79         mSecurityType = config.getSecurityType();
80         ((ValidatedEditTextPreference) mPreference).setValidator(this);
81         ((ValidatedEditTextPreference) mPreference).setIsPassword(true);
82         ((ValidatedEditTextPreference) mPreference).setIsSummaryPassword(true);
83         updatePasswordDisplay((EditTextPreference) mPreference);
84     }
85 
86     @Override
onPreferenceChange(Preference preference, Object newValue)87     public boolean onPreferenceChange(Preference preference, Object newValue) {
88         if (!TextUtils.equals(mPassword, (String) newValue)) {
89             mMetricsFeatureProvider.action(mContext,
90                     SettingsEnums.ACTION_SETTINGS_CHANGE_WIFI_HOTSPOT_PASSWORD);
91         }
92         mPassword = (String) newValue;
93         updatePasswordDisplay((EditTextPreference) mPreference);
94         mListener.onTetherConfigUpdated(this);
95         return true;
96     }
97 
98     /**
99      * This method returns the current password if it is valid for the indicated security type. If
100      * the password currently set is invalid it will forcefully set a random password that is valid.
101      *
102      * @param securityType The security type for the password.
103      * @return The current password if it is valid for the indicated security type. A new randomly
104      * generated password if it is not.
105      */
getPasswordValidated(int securityType)106     public String getPasswordValidated(int securityType) {
107         // don't actually overwrite unless we get a new config in case it was accidentally toggled.
108         if (securityType == SoftApConfiguration.SECURITY_TYPE_OPEN) {
109             return "";
110         } else if (!WifiUtils.isHotspotPasswordValid(mPassword, securityType)) {
111             mPassword = mWifiHotspotRepository.generatePassword();
112             updatePasswordDisplay((EditTextPreference) mPreference);
113         }
114         return mPassword;
115     }
116 
117     /**
118      * This method set the security type of user selection. Then the controller will based on the
119      * security type changed to update the password changed on the preference.
120      *
121      * @param securityType The security type of SoftApConfiguration.
122      */
setSecurityType(int securityType)123     public void setSecurityType(int securityType) {
124         mSecurityType = securityType;
125         mPreference.setVisible(securityType != SoftApConfiguration.SECURITY_TYPE_OPEN);
126     }
127 
128     @Override
isTextValid(String value)129     public boolean isTextValid(String value) {
130         return WifiUtils.isHotspotPasswordValid(value, mSecurityType);
131     }
132 
updatePasswordDisplay(EditTextPreference preference)133     private void updatePasswordDisplay(EditTextPreference preference) {
134         ValidatedEditTextPreference pref = (ValidatedEditTextPreference) preference;
135         pref.setText(mPassword);
136         if (!TextUtils.isEmpty(mPassword)) {
137             pref.setIsSummaryPassword(true);
138             pref.setSummary(mPassword);
139             pref.setVisible(true);
140         } else {
141             pref.setIsSummaryPassword(false);
142             pref.setSummary(R.string.wifi_hotspot_no_password_subtext);
143             pref.setVisible(false);
144         }
145     }
146 }
147