1 /*
2  * Copyright (C) 2019 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.car.settings.wifi;
18 
19 import android.car.drivingstate.CarUxRestrictions;
20 import android.content.Context;
21 import android.content.res.Resources;
22 import android.net.wifi.SoftApConfiguration;
23 import android.util.Log;
24 
25 import androidx.preference.ListPreference;
26 
27 import com.android.car.settings.R;
28 import com.android.car.settings.common.FragmentController;
29 
30 /**
31  * Controls WiFi Hotspot AP Band configuration.
32  */
33 public class WifiTetherApBandPreferenceController extends
34         WifiTetherBasePreferenceController<ListPreference> {
35     private static final String TAG = "CarWifiTetherApBandPref";
36 
37     private String[] mBandEntries;
38     private String[] mBandSummaries;
39     private int mBand;
40 
WifiTetherApBandPreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions)41     public WifiTetherApBandPreferenceController(Context context, String preferenceKey,
42             FragmentController fragmentController, CarUxRestrictions uxRestrictions) {
43         super(context, preferenceKey, fragmentController, uxRestrictions);
44     }
45 
46     @Override
getPreferenceType()47     protected Class<ListPreference> getPreferenceType() {
48         return ListPreference.class;
49     }
50 
51     @Override
onCreateInternal()52     protected void onCreateInternal() {
53         super.onCreateInternal();
54         updatePreferenceEntries();
55         getPreference().setEntries(mBandSummaries);
56         getPreference().setEntryValues(mBandEntries);
57     }
58 
59     @Override
updateState(ListPreference preference)60     public void updateState(ListPreference preference) {
61         super.updateState(preference);
62 
63         SoftApConfiguration config = getCarSoftApConfig();
64         if (config == null) {
65             mBand = SoftApConfiguration.BAND_2GHZ;
66         } else if (!is5GhzBandSupported() && config.getBand() == SoftApConfiguration.BAND_5GHZ) {
67             SoftApConfiguration newConfig = new SoftApConfiguration.Builder(config)
68                     .setBand(SoftApConfiguration.BAND_2GHZ)
69                     .build();
70             setCarSoftApConfig(newConfig);
71             mBand = newConfig.getBand();
72         } else {
73             mBand = validateSelection(config.getBand());
74         }
75 
76         if (!is5GhzBandSupported()) {
77             preference.setEnabled(false);
78             preference.setSummary(R.string.wifi_ap_choose_2G);
79         } else {
80             preference.setValue(Integer.toString(config.getBand()));
81             preference.setSummary(getSummary());
82         }
83 
84     }
85 
86     @Override
getSummary()87     protected String getSummary() {
88         if (!is5GhzBandSupported()) {
89             return getContext().getString(R.string.wifi_ap_choose_2G);
90         }
91         switch (mBand) {
92             case SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ:
93                 return getContext().getString(R.string.wifi_ap_prefer_5G);
94             case SoftApConfiguration.BAND_2GHZ:
95                 return mBandSummaries[0];
96             case SoftApConfiguration.BAND_5GHZ:
97                 return mBandSummaries[1];
98             default:
99                 Log.e(TAG, "Unknown band: " + mBand);
100                 return getContext().getString(R.string.wifi_ap_prefer_5G);
101         }
102     }
103 
104     @Override
getDefaultSummary()105     protected String getDefaultSummary() {
106         return null;
107     }
108 
109     @Override
handlePreferenceChanged(ListPreference preference, Object newValue)110     public boolean handlePreferenceChanged(ListPreference preference, Object newValue) {
111         mBand = validateSelection(Integer.parseInt((String) newValue));
112         updateApBand(); // updating AP band because mBandIndex may have been assigned a new value.
113         refreshUi();
114         return true;
115     }
116 
validateSelection(int band)117     private int validateSelection(int band) {
118         // unsupported states:
119         // 1: BAND_5GHZ only - include 2GHZ since some of countries doesn't support 5G hotspot
120         // 2: no 5 GHZ support means we can't have BAND_5GHZ - default to 2GHZ
121         if (SoftApConfiguration.BAND_5GHZ == band) {
122             if (!is5GhzBandSupported()) {
123                 return SoftApConfiguration.BAND_2GHZ;
124             }
125             return SoftApConfiguration.BAND_5GHZ | SoftApConfiguration.BAND_2GHZ;
126         }
127         return band;
128     }
129 
updatePreferenceEntries()130     private void updatePreferenceEntries() {
131         Resources res = getContext().getResources();
132         int entriesRes = R.array.wifi_ap_band;
133         int summariesRes = R.array.wifi_ap_band_summary;
134         mBandEntries = res.getStringArray(entriesRes);
135         mBandSummaries = res.getStringArray(summariesRes);
136     }
137 
updateApBand()138     private void updateApBand() {
139         SoftApConfiguration config = new SoftApConfiguration.Builder(getCarSoftApConfig())
140                 .setBand(mBand)
141                 .build();
142         setCarSoftApConfig(config);
143         getPreference().setValue(getBandEntry());
144     }
145 
getBandEntry()146     private String getBandEntry() {
147         switch (mBand) {
148             case SoftApConfiguration.BAND_2GHZ | SoftApConfiguration.BAND_5GHZ:
149             case SoftApConfiguration.BAND_2GHZ:
150                 return mBandEntries[0];
151             case SoftApConfiguration.BAND_5GHZ:
152                 return mBandEntries[1];
153             default:
154                 Log.e(TAG, "Unknown band: " + mBand + ", defaulting to 2GHz");
155                 return mBandEntries[0];
156         }
157     }
158 
is5GhzBandSupported()159     private boolean is5GhzBandSupported() {
160         String countryCode = getCarWifiManager().getCountryCode();
161         return getCarWifiManager().is5GhzBandSupported() && countryCode != null;
162     }
163 }
164