1 /* 2 * Copyright (C) 2021 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.annotation.NonNull; 22 import android.content.Context; 23 import android.net.wifi.SoftApCapability; 24 import android.net.wifi.SoftApConfiguration; 25 import android.net.wifi.WifiManager; 26 import android.util.FeatureFlagUtils; 27 import android.util.Log; 28 29 import androidx.annotation.VisibleForTesting; 30 import androidx.preference.ListPreference; 31 import androidx.preference.Preference; 32 33 import com.android.settings.R; 34 import com.android.settings.core.FeatureFlags; 35 36 import java.util.LinkedHashMap; 37 import java.util.Map; 38 39 /** 40 * Controller for logic pertaining to the security type of Wi-Fi tethering. 41 */ 42 public class WifiTetherSecurityPreferenceController extends WifiTetherBasePreferenceController 43 implements WifiManager.SoftApCallback { 44 45 private static final String PREF_KEY = "wifi_tether_security"; 46 47 private Map<Integer, String> mSecurityMap = new LinkedHashMap<Integer, String>(); 48 private int mSecurityValue; 49 @VisibleForTesting 50 boolean mIsWpa3Supported = true; 51 WifiTetherSecurityPreferenceController(Context context, OnTetherConfigUpdateListener listener)52 public WifiTetherSecurityPreferenceController(Context context, 53 OnTetherConfigUpdateListener listener) { 54 super(context, listener); 55 final String[] securityNames = mContext.getResources().getStringArray( 56 R.array.wifi_tether_security); 57 final String[] securityValues = mContext.getResources().getStringArray( 58 R.array.wifi_tether_security_values); 59 for (int i = 0; i < securityNames.length; i++) { 60 mSecurityMap.put(Integer.parseInt(securityValues[i]), securityNames[i]); 61 } 62 mWifiManager.registerSoftApCallback(context.getMainExecutor(), this); 63 } 64 65 @Override getPreferenceKey()66 public String getPreferenceKey() { 67 return FeatureFlagUtils.isEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE) 68 ? PREF_KEY + DEDUP_POSTFIX : PREF_KEY; 69 } 70 71 @Override updateDisplay()72 public void updateDisplay() { 73 // The mPreference will be ready when the fragment calls displayPreference(). Since the 74 // capability of WPA3 hotspot callback will update the preference list here, add null point 75 // checking to avoid the mPreference is not ready when the fragment is loading for settings 76 // keyword searching only. 77 if (mPreference == null) { 78 return; 79 } 80 final ListPreference preference = (ListPreference) mPreference; 81 // If the device is not support WPA3 then remove the WPA3 options. 82 if (!mIsWpa3Supported && mSecurityMap.keySet() 83 .removeIf(key -> key > SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)) { 84 preference.setEntries(mSecurityMap.values().stream().toArray(CharSequence[]::new)); 85 preference.setEntryValues(mSecurityMap.keySet().stream().map(Integer::toBinaryString) 86 .toArray(CharSequence[]::new)); 87 } 88 89 final int securityType = mWifiManager.getSoftApConfiguration().getSecurityType(); 90 mSecurityValue = mSecurityMap.get(securityType) != null 91 ? securityType : SoftApConfiguration.SECURITY_TYPE_WPA2_PSK; 92 93 preference.setSummary(mSecurityMap.get(mSecurityValue)); 94 preference.setValue(String.valueOf(mSecurityValue)); 95 } 96 97 @Override onPreferenceChange(Preference preference, Object newValue)98 public boolean onPreferenceChange(Preference preference, Object newValue) { 99 mSecurityValue = Integer.parseInt((String) newValue); 100 preference.setSummary(mSecurityMap.get(mSecurityValue)); 101 if (mListener != null) { 102 mListener.onTetherConfigUpdated(this); 103 } 104 return true; 105 } 106 107 @Override onCapabilityChanged(@onNull SoftApCapability softApCapability)108 public void onCapabilityChanged(@NonNull SoftApCapability softApCapability) { 109 final boolean isWpa3Supported = 110 softApCapability.areFeaturesSupported(SoftApCapability.SOFTAP_FEATURE_WPA3_SAE); 111 if (!isWpa3Supported) { 112 Log.i(PREF_KEY, "WPA3 SAE is not supported on this device"); 113 } 114 if (mIsWpa3Supported != isWpa3Supported) { 115 mIsWpa3Supported = isWpa3Supported; 116 updateDisplay(); 117 } 118 mWifiManager.unregisterSoftApCallback(this); 119 } 120 getSecurityType()121 public int getSecurityType() { 122 return mSecurityValue; 123 } 124 } 125