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_6GHZ;
25 
26 import android.app.Application;
27 
28 import androidx.lifecycle.AndroidViewModel;
29 import androidx.lifecycle.LiveData;
30 import androidx.lifecycle.MutableLiveData;
31 import androidx.lifecycle.Observer;
32 
33 import com.android.settings.overlay.FeatureFactory;
34 import com.android.settings.wifi.repository.WifiHotspotRepository;
35 
36 import org.jetbrains.annotations.NotNull;
37 
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 
42 /**
43  * Wi-Fi Hotspot Security View Model for {@link WifiHotspotSecuritySettings}
44  */
45 public class WifiHotspotSecurityViewModel extends AndroidViewModel {
46     private static final String TAG = "WifiHotspotSecurityViewModel";
47 
48     public static final String KEY_SECURITY_WPA3 = "wifi_hotspot_security_wpa3";
49     public static final String KEY_SECURITY_WPA2_WPA3 = "wifi_hotspot_security_wpa2_wpa3";
50     public static final String KEY_SECURITY_WPA2 = "wifi_hotspot_security_wpa2";
51     public static final String KEY_SECURITY_NONE = "wifi_hotspot_security_none";
52 
53     protected Map<Integer, ViewItem> mViewItemMap = new HashMap<>();
54     protected MutableLiveData<List<ViewItem>> mViewInfoListData;
55 
56     protected final WifiHotspotRepository mWifiHotspotRepository;
57     protected final Observer<Integer> mSecurityTypeObserver = st -> onSecurityTypeChanged(st);
58     protected final Observer<Integer> mSpeedTypeObserver = st -> onSpeedTypeChanged(st);
59 
WifiHotspotSecurityViewModel( @otNull Application application)60     public WifiHotspotSecurityViewModel(
61             @NotNull Application application) {
62         super(application);
63         mViewItemMap.put(SECURITY_TYPE_WPA3_SAE, new ViewItem(KEY_SECURITY_WPA3));
64         mViewItemMap.put(SECURITY_TYPE_WPA3_SAE_TRANSITION, new ViewItem(KEY_SECURITY_WPA2_WPA3));
65         mViewItemMap.put(SECURITY_TYPE_WPA2_PSK, new ViewItem(KEY_SECURITY_WPA2));
66         mViewItemMap.put(SECURITY_TYPE_OPEN, new ViewItem(KEY_SECURITY_NONE));
67 
68         mWifiHotspotRepository = FeatureFactory.getFeatureFactory().getWifiFeatureProvider()
69                 .getWifiHotspotRepository();
70         mWifiHotspotRepository.getSecurityType().observeForever(mSecurityTypeObserver);
71         mWifiHotspotRepository.getSpeedType().observeForever(mSpeedTypeObserver);
72     }
73 
74     @Override
onCleared()75     protected void onCleared() {
76         mWifiHotspotRepository.getSecurityType().removeObserver(mSecurityTypeObserver);
77         mWifiHotspotRepository.getSpeedType().removeObserver(mSpeedTypeObserver);
78     }
79 
onSecurityTypeChanged(int securityType)80     protected void onSecurityTypeChanged(int securityType) {
81         log("onSecurityTypeChanged(), securityType:" + securityType);
82         for (Map.Entry<Integer, ViewItem> entry : mViewItemMap.entrySet()) {
83             entry.getValue().mIsChecked = entry.getKey().equals(securityType);
84         }
85         updateViewItemListData();
86     }
87 
onSpeedTypeChanged(Integer speedType)88     protected void onSpeedTypeChanged(Integer speedType) {
89         log("onSpeedTypeChanged(), speedType:" + speedType);
90         boolean isWpa3Only = (speedType == SPEED_6GHZ);
91         for (Map.Entry<Integer, ViewItem> entry : mViewItemMap.entrySet()) {
92             if (entry.getKey() != SECURITY_TYPE_WPA3_SAE) {
93                 entry.getValue().mIsEnabled = !isWpa3Only;
94             }
95         }
96         updateViewItemListData();
97     }
98 
99     /**
100      * Handle RadioButton Clicked
101      */
handleRadioButtonClicked(String key)102     public void handleRadioButtonClicked(String key) {
103         log("handleRadioButtonClicked(), key:" + key);
104         for (Map.Entry<Integer, ViewItem> entry : mViewItemMap.entrySet()) {
105             ViewItem viewItem = entry.getValue();
106             if (viewItem.mKey.equals(key)) {
107                 mWifiHotspotRepository.setSecurityType(entry.getKey());
108                 return;
109             }
110         }
111     }
112 
113     /**
114      * Gets ViewItemList LiveData
115      */
getViewItemListData()116     public LiveData<List<ViewItem>> getViewItemListData() {
117         if (mViewInfoListData == null) {
118             mViewInfoListData = new MutableLiveData<>();
119             updateViewItemListData();
120             log("getViewItemListData(), mViewInfoListData:" + mViewInfoListData.getValue());
121         }
122         return mViewInfoListData;
123     }
124 
updateViewItemListData()125     protected void updateViewItemListData() {
126         if (mViewInfoListData == null) {
127             return;
128         }
129         mViewInfoListData.setValue(mViewItemMap.values().stream().toList());
130     }
131 
132     /**
133      * Gets Restarting LiveData
134      */
getRestarting()135     public LiveData<Boolean> getRestarting() {
136         return mWifiHotspotRepository.getRestarting();
137     }
138 
139     /**
140      * Wi-Fi Hotspot View Item
141      */
142     public static final class ViewItem {
143         String mKey;
144         boolean mIsChecked;
145         boolean mIsEnabled = true;
146 
ViewItem(String key)147         public ViewItem(String key) {
148             mKey = key;
149         }
150 
151         @Override
toString()152         public String toString() {
153             return new StringBuilder("ViewItem:{")
154                     .append("Key:").append(mKey)
155                     .append(",IsChecked:").append(mIsChecked)
156                     .append(",IsEnabled:").append(mIsEnabled)
157                     .append('}').toString();
158         }
159     }
160 
log(String msg)161     private void log(String msg) {
162         FeatureFactory.getFeatureFactory().getWifiFeatureProvider().verboseLog(TAG, msg);
163     }
164 }
165