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 com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_2GHZ;
20 import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_2GHZ_5GHZ;
21 import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_5GHZ;
22 import static com.android.settings.wifi.repository.WifiHotspotRepository.SPEED_6GHZ;
23 
24 import android.app.Application;
25 import android.util.Log;
26 
27 import androidx.annotation.VisibleForTesting;
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.R;
34 import com.android.settings.overlay.FeatureFactory;
35 import com.android.settings.wifi.repository.WifiHotspotRepository;
36 
37 import org.jetbrains.annotations.NotNull;
38 
39 import java.util.HashMap;
40 import java.util.Map;
41 
42 /**
43  * Wi-Fi Hotspot Speed View Model
44  */
45 public class WifiHotspotSpeedViewModel extends AndroidViewModel {
46     private static final String TAG = "WifiHotspotSpeedViewModel";
47     @VisibleForTesting
48     static final int RES_SPEED_5G_SUMMARY = R.string.wifi_hotspot_speed_5g_summary;
49     @VisibleForTesting
50     static final int RES_SPEED_6G_SUMMARY = R.string.wifi_hotspot_speed_6g_summary;
51     @VisibleForTesting
52     static final int RES_SUMMARY_UNAVAILABLE = R.string.wifi_hotspot_speed_summary_unavailable;
53 
54     protected final WifiHotspotRepository mWifiHotspotRepository;
55     protected Map<Integer, SpeedInfo> mSpeedInfoMap = new HashMap<>();
56     protected MutableLiveData<Map<Integer, SpeedInfo>> mSpeedInfoMapData;
57     protected SpeedInfo mSpeedInfo2g = new SpeedInfo(false, true, false);
58     protected SpeedInfo mSpeedInfo5g = new SpeedInfo(false, true, false);
59     protected SpeedInfo mSpeedInfo2g5g = new SpeedInfo(false, true, true);
60     protected SpeedInfo mSpeedInfo6g = new SpeedInfo(false, true, true);
61 
62     protected final Observer<Boolean> m6gAvailableObserver = a -> on6gAvailableChanged(a);
63     protected final Observer<Boolean> m5gAvailableObserver = a -> on5gAvailableChanged(a);
64     protected final Observer<Integer> mSpeedTypeObserver = st -> onSpeedTypeChanged(st);
65 
WifiHotspotSpeedViewModel(@otNull Application application)66     public WifiHotspotSpeedViewModel(@NotNull Application application) {
67         super(application);
68         mWifiHotspotRepository = FeatureFactory.getFeatureFactory().getWifiFeatureProvider()
69                 .getWifiHotspotRepository();
70         mWifiHotspotRepository.get6gAvailable().observeForever(m6gAvailableObserver);
71         mWifiHotspotRepository.get5gAvailable().observeForever(m5gAvailableObserver);
72         mWifiHotspotRepository.getSpeedType().observeForever(mSpeedTypeObserver);
73         mWifiHotspotRepository.setAutoRefresh(true);
74 
75         // The visibility of the 6 GHz speed option will not change on a Pixel device.
76         mSpeedInfo6g.mIsVisible = mWifiHotspotRepository.is6GHzBandSupported();
77     }
78 
79     @Override
onCleared()80     protected void onCleared() {
81         mWifiHotspotRepository.get6gAvailable().removeObserver(m6gAvailableObserver);
82         mWifiHotspotRepository.get5gAvailable().removeObserver(m5gAvailableObserver);
83         mWifiHotspotRepository.getSpeedType().removeObserver(mSpeedTypeObserver);
84     }
85 
on6gAvailableChanged(Boolean available)86     protected void on6gAvailableChanged(Boolean available) {
87         Log.d(TAG, "on6gAvailableChanged(), available:" + available);
88         mSpeedInfo6g.mIsEnabled = available;
89         mSpeedInfo6g.mSummary = getApplication()
90                 .getString(available ? RES_SPEED_6G_SUMMARY : RES_SUMMARY_UNAVAILABLE);
91         updateSpeedInfoMapData();
92     }
93 
on5gAvailableChanged(Boolean available)94     protected void on5gAvailableChanged(Boolean available) {
95         Log.d(TAG, "on5gAvailableChanged(), available:" + available);
96         mSpeedInfo5g.mIsEnabled = available;
97         mSpeedInfo5g.mSummary = getApplication()
98                 .getString(available ? RES_SPEED_5G_SUMMARY : RES_SUMMARY_UNAVAILABLE);
99 
100         boolean showDualBand = mWifiHotspotRepository.isDualBand() && available;
101         log("on5gAvailableChanged(), showDualBand:" + showDualBand);
102         mSpeedInfo2g5g.mIsVisible = showDualBand;
103         mSpeedInfo2g.mIsVisible = !showDualBand;
104         mSpeedInfo5g.mIsVisible = !showDualBand;
105         updateSpeedInfoMapData();
106     }
107 
onSpeedTypeChanged(Integer speedType)108     protected void onSpeedTypeChanged(Integer speedType) {
109         log("onSpeedTypeChanged(), speedType:" + speedType);
110         mSpeedInfo2g.mIsChecked = speedType.equals(SPEED_2GHZ);
111         mSpeedInfo5g.mIsChecked = speedType.equals(SPEED_5GHZ);
112         mSpeedInfo2g5g.mIsChecked = speedType.equals(SPEED_2GHZ_5GHZ);
113         mSpeedInfo6g.mIsChecked = speedType.equals(SPEED_6GHZ);
114         updateSpeedInfoMapData();
115     }
116 
117     /**
118      * Sets SpeedType
119      */
setSpeedType(Integer speedType)120     public void setSpeedType(Integer speedType) {
121         mWifiHotspotRepository.setSpeedType(speedType);
122     }
123 
124     /**
125      * Gets Speed Information LiveData
126      */
getSpeedInfoMapData()127     public LiveData<Map<Integer, SpeedInfo>> getSpeedInfoMapData() {
128         if (mSpeedInfoMapData == null) {
129             mSpeedInfoMapData = new MutableLiveData<>();
130             mSpeedInfoMapData.setValue(mSpeedInfoMap);
131             log("getSpeedViewData(), mSpeedInfoMap:" + mSpeedInfoMapData.getValue());
132         }
133         return mSpeedInfoMapData;
134     }
135 
updateSpeedInfoMapData()136     protected void updateSpeedInfoMapData() {
137         mSpeedInfoMap.put(SPEED_2GHZ, mSpeedInfo2g);
138         mSpeedInfoMap.put(SPEED_5GHZ, mSpeedInfo5g);
139         mSpeedInfoMap.put(SPEED_2GHZ_5GHZ, mSpeedInfo2g5g);
140         mSpeedInfoMap.put(SPEED_6GHZ, mSpeedInfo6g);
141         if (mSpeedInfoMapData != null) {
142             mSpeedInfoMapData.setValue(mSpeedInfoMap);
143         }
144     }
145 
146     /**
147      * Gets Restarting LiveData
148      */
getRestarting()149     public LiveData<Boolean> getRestarting() {
150         return mWifiHotspotRepository.getRestarting();
151     }
152 
153     /**
154      * Wi-Fi Hotspot Speed Information
155      */
156     public static final class SpeedInfo {
157         Boolean mIsChecked;
158         boolean mIsEnabled;
159         boolean mIsVisible;
160         String mSummary;
161 
SpeedInfo(boolean isChecked, boolean isEnabled, boolean isVisible)162         public SpeedInfo(boolean isChecked, boolean isEnabled, boolean isVisible) {
163             this.mIsChecked = isChecked;
164             this.mIsEnabled = isEnabled;
165             this.mIsVisible = isVisible;
166         }
167 
168         @Override
toString()169         public String toString() {
170             return new StringBuilder("SpeedInfo{")
171                     .append("isChecked:").append(mIsChecked)
172                     .append(",isEnabled:").append(mIsEnabled)
173                     .append(",isVisible:").append(mIsVisible)
174                     .append(",mSummary:").append(mSummary)
175                     .append('}').toString();
176         }
177     }
178 
log(String msg)179     private void log(String msg) {
180         FeatureFactory.getFeatureFactory().getWifiFeatureProvider().verboseLog(TAG, msg);
181     }
182 }
183