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