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