1 /* 2 * Copyright (C) 2023 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 android.net.wifi.SoftApConfiguration.SECURITY_TYPE_OPEN; 20 import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA2_PSK; 21 import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE; 22 import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION; 23 24 import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_2GHZ; 25 import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_2GHZ_5GHZ; 26 import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_5GHZ; 27 import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_6GHZ; 28 29 import android.app.Application; 30 import android.net.wifi.SoftApConfiguration; 31 import android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState; 32 33 import androidx.annotation.VisibleForTesting; 34 import androidx.lifecycle.AndroidViewModel; 35 import androidx.lifecycle.LiveData; 36 import androidx.lifecycle.MutableLiveData; 37 import androidx.lifecycle.Observer; 38 39 import com.android.settings.R; 40 import com.android.settings.overlay.FeatureFactory; 41 import com.android.settings.wifi.factory.WifiFeatureProvider; 42 import com.android.settings.wifi.repository.SharedConnectivityRepository; 43 import com.android.settings.wifi.repository.WifiHotspotRepository; 44 45 import org.jetbrains.annotations.NotNull; 46 47 import java.util.HashMap; 48 import java.util.Map; 49 50 /** 51 * Wi-Fi Hotspot ViewModel 52 */ 53 public class WifiTetherViewModel extends AndroidViewModel { 54 private static final String TAG = "WifiTetherViewModel"; 55 static final int RES_INSTANT_HOTSPOT_SUMMARY_ON = R.string.wifi_hotspot_instant_summary_on; 56 static final int RES_INSTANT_HOTSPOT_SUMMARY_OFF = R.string.wifi_hotspot_instant_summary_off; 57 58 static Map<Integer, Integer> sSecuritySummaryResMap = new HashMap<>(); 59 60 static { sSecuritySummaryResMap.put( SECURITY_TYPE_WPA3_SAE, com.android.settingslib.R.string.wifi_security_sae)61 sSecuritySummaryResMap.put( 62 SECURITY_TYPE_WPA3_SAE, com.android.settingslib.R.string.wifi_security_sae); sSecuritySummaryResMap.put(SECURITY_TYPE_WPA3_SAE_TRANSITION, com.android.settingslib.R.string.wifi_security_psk_sae)63 sSecuritySummaryResMap.put(SECURITY_TYPE_WPA3_SAE_TRANSITION, 64 com.android.settingslib.R.string.wifi_security_psk_sae); sSecuritySummaryResMap.put( SECURITY_TYPE_WPA2_PSK, com.android.settingslib.R.string.wifi_security_wpa2)65 sSecuritySummaryResMap.put( 66 SECURITY_TYPE_WPA2_PSK, com.android.settingslib.R.string.wifi_security_wpa2); sSecuritySummaryResMap.put( SECURITY_TYPE_OPEN, com.android.settingslib.R.string.wifi_security_none)67 sSecuritySummaryResMap.put( 68 SECURITY_TYPE_OPEN, com.android.settingslib.R.string.wifi_security_none); 69 } 70 71 static Map<Integer, Integer> sSpeedSummaryResMap = new HashMap<>(); 72 73 static { sSpeedSummaryResMap.put(SPEED_2GHZ, R.string.wifi_hotspot_speed_summary_2g)74 sSpeedSummaryResMap.put(SPEED_2GHZ, R.string.wifi_hotspot_speed_summary_2g); sSpeedSummaryResMap.put(SPEED_5GHZ, R.string.wifi_hotspot_speed_summary_5g)75 sSpeedSummaryResMap.put(SPEED_5GHZ, R.string.wifi_hotspot_speed_summary_5g); sSpeedSummaryResMap.put(SPEED_6GHZ, R.string.wifi_hotspot_speed_summary_6g)76 sSpeedSummaryResMap.put(SPEED_6GHZ, R.string.wifi_hotspot_speed_summary_6g); sSpeedSummaryResMap.put(SPEED_2GHZ_5GHZ, R.string.wifi_hotspot_speed_summary_2g_and_5g)77 sSpeedSummaryResMap.put(SPEED_2GHZ_5GHZ, R.string.wifi_hotspot_speed_summary_2g_and_5g); 78 } 79 80 protected final WifiHotspotRepository mWifiHotspotRepository; 81 protected MutableLiveData<Integer> mSecuritySummary; 82 protected MutableLiveData<Integer> mSpeedSummary; 83 84 protected final Observer<Integer> mSecurityTypeObserver = st -> onSecurityTypeChanged(st); 85 protected final Observer<Integer> mSpeedTypeObserver = st -> onSpeedTypeChanged(st); 86 87 private SharedConnectivityRepository mSharedConnectivityRepository; 88 @VisibleForTesting 89 MutableLiveData<String> mInstantHotspotSummary = new MutableLiveData<>(); 90 @VisibleForTesting 91 Observer<SharedConnectivitySettingsState> mInstantHotspotStateObserver = 92 state -> onInstantHotspotStateChanged(state); 93 WifiTetherViewModel(@otNull Application application)94 public WifiTetherViewModel(@NotNull Application application) { 95 super(application); 96 WifiFeatureProvider featureProvider = FeatureFactory.getFeatureFactory() 97 .getWifiFeatureProvider(); 98 mWifiHotspotRepository = featureProvider.getWifiHotspotRepository(); 99 mSharedConnectivityRepository = featureProvider.getSharedConnectivityRepository(); 100 if (mSharedConnectivityRepository.isServiceAvailable()) { 101 mSharedConnectivityRepository.getSettingsState() 102 .observeForever(mInstantHotspotStateObserver); 103 } 104 } 105 106 @Override onCleared()107 protected void onCleared() { 108 if (mSecuritySummary != null) { 109 mWifiHotspotRepository.getSecurityType().removeObserver(mSecurityTypeObserver); 110 } 111 if (mSpeedSummary != null) { 112 mWifiHotspotRepository.getSpeedType().removeObserver(mSpeedTypeObserver); 113 } 114 if (mSharedConnectivityRepository.isServiceAvailable()) { 115 mSharedConnectivityRepository.getSettingsState() 116 .removeObserver(mInstantHotspotStateObserver); 117 } 118 } 119 120 /** 121 * Return whether Wi-Fi Hotspot Speed Feature is available or not. 122 * 123 * @return {@code true} if Wi-Fi Hotspot Speed Feature is available 124 */ isSpeedFeatureAvailable()125 public boolean isSpeedFeatureAvailable() { 126 return mWifiHotspotRepository.isSpeedFeatureAvailable(); 127 } 128 129 /** 130 * Gets the Wi-Fi tethered AP Configuration. 131 * 132 * @return AP details in {@link SoftApConfiguration} 133 */ getSoftApConfiguration()134 public SoftApConfiguration getSoftApConfiguration() { 135 return mWifiHotspotRepository.getSoftApConfiguration(); 136 } 137 138 /** 139 * Sets the tethered Wi-Fi AP Configuration. 140 * 141 * @param config A valid SoftApConfiguration specifying the configuration of the SAP. 142 */ setSoftApConfiguration(SoftApConfiguration config)143 public void setSoftApConfiguration(SoftApConfiguration config) { 144 mWifiHotspotRepository.setSoftApConfiguration(config); 145 } 146 147 /** 148 * Refresh data from the SoftApConfiguration. 149 */ refresh()150 public void refresh() { 151 mWifiHotspotRepository.refresh(); 152 } 153 154 /** 155 * Gets SecuritySummary LiveData 156 */ getSecuritySummary()157 public LiveData<Integer> getSecuritySummary() { 158 if (mSecuritySummary == null) { 159 mSecuritySummary = new MutableLiveData<>(); 160 mWifiHotspotRepository.getSecurityType().observeForever(mSecurityTypeObserver); 161 } 162 return mSecuritySummary; 163 } 164 onSecurityTypeChanged(int securityType)165 protected void onSecurityTypeChanged(int securityType) { 166 int resId = R.string.summary_placeholder; 167 if (sSecuritySummaryResMap.containsKey(securityType)) { 168 resId = sSecuritySummaryResMap.get(securityType); 169 } 170 mSecuritySummary.setValue(resId); 171 } 172 173 /** 174 * Gets SpeedSummary LiveData 175 */ getSpeedSummary()176 public LiveData<Integer> getSpeedSummary() { 177 if (mSpeedSummary == null) { 178 mSpeedSummary = new MutableLiveData<>(); 179 mWifiHotspotRepository.getSpeedType().observeForever(mSpeedTypeObserver); 180 } 181 return mSpeedSummary; 182 } 183 onSpeedTypeChanged(Integer speedType)184 protected void onSpeedTypeChanged(Integer speedType) { 185 int resId = R.string.summary_placeholder; 186 if (sSpeedSummaryResMap.containsKey(speedType)) { 187 resId = sSpeedSummaryResMap.get(speedType); 188 } 189 mSpeedSummary.setValue(resId); 190 } 191 192 /** 193 * Gets Restarting LiveData 194 */ getRestarting()195 public LiveData<Boolean> getRestarting() { 196 return mWifiHotspotRepository.getRestarting(); 197 } 198 199 /** 200 * Return whether Wi-Fi Instant Hotspot feature is available or not. 201 * 202 * @return {@code true} if Wi-Fi Instant Hotspot feature is available 203 */ isInstantHotspotFeatureAvailable()204 public boolean isInstantHotspotFeatureAvailable() { 205 return mSharedConnectivityRepository.isServiceAvailable(); 206 } 207 208 /** 209 * Gets InstantHotspotSummary 210 */ getInstantHotspotSummary()211 public LiveData<String> getInstantHotspotSummary() { 212 return mInstantHotspotSummary; 213 } 214 215 @VisibleForTesting onInstantHotspotStateChanged(SharedConnectivitySettingsState state)216 void onInstantHotspotStateChanged(SharedConnectivitySettingsState state) { 217 log("onInstantHotspotStateChanged(), state:" + state); 218 if (state == null) { 219 mInstantHotspotSummary.setValue(null); 220 return; 221 } 222 mInstantHotspotSummary.setValue(getInstantHotspotSummary(state.isInstantTetherEnabled())); 223 } 224 getInstantHotspotSummary(boolean enabled)225 private String getInstantHotspotSummary(boolean enabled) { 226 return getApplication().getString( 227 enabled ? RES_INSTANT_HOTSPOT_SUMMARY_ON : RES_INSTANT_HOTSPOT_SUMMARY_OFF); 228 } 229 230 /** 231 * Launch Instant Hotspot Settings 232 */ launchInstantHotspotSettings()233 public void launchInstantHotspotSettings() { 234 mSharedConnectivityRepository.launchSettings(); 235 } 236 log(String msg)237 private void log(String msg) { 238 FeatureFactory.getFeatureFactory().getWifiFeatureProvider().verboseLog(TAG, msg); 239 } 240 } 241