1/* 2 * Copyright (C) 2011 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 17package com.android.settings.wifi; 18 19import android.app.Dialog; 20import android.app.DialogFragment; 21import android.content.BroadcastReceiver; 22import android.content.Context; 23import android.content.Intent; 24import android.content.IntentFilter; 25import android.net.NetworkScoreManager; 26import android.net.NetworkScorerAppManager; 27import android.net.NetworkScorerAppManager.NetworkScorerAppData; 28import android.net.wifi.WifiInfo; 29import android.net.wifi.WifiManager; 30import android.net.wifi.WpsInfo; 31import android.os.Bundle; 32import android.preference.CheckBoxPreference; 33import android.preference.ListPreference; 34import android.preference.Preference; 35import android.preference.Preference.OnPreferenceClickListener; 36import android.preference.PreferenceScreen; 37import android.preference.SwitchPreference; 38import android.provider.Settings; 39import android.provider.Settings.Global; 40import android.security.Credentials; 41import android.text.TextUtils; 42import android.util.Log; 43import android.widget.Toast; 44 45import com.android.settings.R; 46import com.android.settings.SettingsPreferenceFragment; 47import com.android.settings.Utils; 48 49import java.util.Collection; 50 51public class AdvancedWifiSettings extends SettingsPreferenceFragment 52 implements Preference.OnPreferenceChangeListener { 53 54 private static final String TAG = "AdvancedWifiSettings"; 55 private static final String KEY_MAC_ADDRESS = "mac_address"; 56 private static final String KEY_CURRENT_IP_ADDRESS = "current_ip_address"; 57 private static final String KEY_FREQUENCY_BAND = "frequency_band"; 58 private static final String KEY_NOTIFY_OPEN_NETWORKS = "notify_open_networks"; 59 private static final String KEY_SLEEP_POLICY = "sleep_policy"; 60 private static final String KEY_SCAN_ALWAYS_AVAILABLE = "wifi_scan_always_available"; 61 private static final String KEY_INSTALL_CREDENTIALS = "install_credentials"; 62 private static final String KEY_WIFI_ASSISTANT = "wifi_assistant"; 63 private static final String KEY_WIFI_DIRECT = "wifi_direct"; 64 private static final String KEY_WPS_PUSH = "wps_push_button"; 65 private static final String KEY_WPS_PIN = "wps_pin_entry"; 66 67 private WifiManager mWifiManager; 68 private NetworkScoreManager mNetworkScoreManager; 69 70 private IntentFilter mFilter; 71 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 72 @Override 73 public void onReceive(Context context, Intent intent) { 74 String action = intent.getAction(); 75 if (action.equals(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION) || 76 action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 77 refreshWifiInfo(); 78 } 79 } 80 }; 81 82 @Override 83 public void onCreate(Bundle savedInstanceState) { 84 super.onCreate(savedInstanceState); 85 addPreferencesFromResource(R.xml.wifi_advanced_settings); 86 } 87 88 @Override 89 public void onActivityCreated(Bundle savedInstanceState) { 90 super.onActivityCreated(savedInstanceState); 91 mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 92 mFilter = new IntentFilter(); 93 mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); 94 mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 95 mNetworkScoreManager = 96 (NetworkScoreManager) getSystemService(Context.NETWORK_SCORE_SERVICE); 97 } 98 99 @Override 100 public void onResume() { 101 super.onResume(); 102 initPreferences(); 103 getActivity().registerReceiver(mReceiver, mFilter); 104 refreshWifiInfo(); 105 } 106 107 @Override 108 public void onPause() { 109 super.onPause(); 110 getActivity().unregisterReceiver(mReceiver); 111 } 112 113 private void initPreferences() { 114 SwitchPreference notifyOpenNetworks = 115 (SwitchPreference) findPreference(KEY_NOTIFY_OPEN_NETWORKS); 116 notifyOpenNetworks.setChecked(Settings.Global.getInt(getContentResolver(), 117 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1); 118 notifyOpenNetworks.setEnabled(mWifiManager.isWifiEnabled()); 119 120 SwitchPreference scanAlwaysAvailable = 121 (SwitchPreference) findPreference(KEY_SCAN_ALWAYS_AVAILABLE); 122 scanAlwaysAvailable.setChecked(Global.getInt(getContentResolver(), 123 Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1); 124 125 Intent intent = new Intent(Credentials.INSTALL_AS_USER_ACTION); 126 intent.setClassName("com.android.certinstaller", 127 "com.android.certinstaller.CertInstallerMain"); 128 intent.putExtra(Credentials.EXTRA_INSTALL_AS_UID, android.os.Process.WIFI_UID); 129 Preference pref = findPreference(KEY_INSTALL_CREDENTIALS); 130 pref.setIntent(intent); 131 132 final Context context = getActivity(); 133 NetworkScorerAppData scorer = WifiSettings.getWifiAssistantApp(context); 134 SwitchPreference wifiAssistant = (SwitchPreference)findPreference(KEY_WIFI_ASSISTANT); 135 if (scorer != null) { 136 final boolean checked = NetworkScorerAppManager.getActiveScorer(context) != null; 137 wifiAssistant.setSummary(getResources().getString( 138 R.string.wifi_automatically_manage_summary, scorer.mScorerName)); 139 wifiAssistant.setOnPreferenceChangeListener(this); 140 wifiAssistant.setChecked(checked); 141 } else { 142 if (wifiAssistant != null) { 143 getPreferenceScreen().removePreference(wifiAssistant); 144 } 145 } 146 147 Intent wifiDirectIntent = new Intent(context, 148 com.android.settings.Settings.WifiP2pSettingsActivity.class); 149 Preference wifiDirectPref = findPreference(KEY_WIFI_DIRECT); 150 wifiDirectPref.setIntent(wifiDirectIntent); 151 152 // WpsDialog: Create the dialog like WifiSettings does. 153 Preference wpsPushPref = findPreference(KEY_WPS_PUSH); 154 wpsPushPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { 155 public boolean onPreferenceClick(Preference arg0) { 156 WpsFragment wpsFragment = new WpsFragment(WpsInfo.PBC); 157 wpsFragment.show(getFragmentManager(), KEY_WPS_PUSH); 158 return true; 159 } 160 }); 161 162 // WpsDialog: Create the dialog like WifiSettings does. 163 Preference wpsPinPref = findPreference(KEY_WPS_PIN); 164 wpsPinPref.setOnPreferenceClickListener(new OnPreferenceClickListener(){ 165 public boolean onPreferenceClick(Preference arg0) { 166 WpsFragment wpsFragment = new WpsFragment(WpsInfo.DISPLAY); 167 wpsFragment.show(getFragmentManager(), KEY_WPS_PIN); 168 return true; 169 } 170 }); 171 172 ListPreference frequencyPref = (ListPreference) findPreference(KEY_FREQUENCY_BAND); 173 174 if (mWifiManager.isDualBandSupported()) { 175 frequencyPref.setOnPreferenceChangeListener(this); 176 int value = mWifiManager.getFrequencyBand(); 177 if (value != -1) { 178 frequencyPref.setValue(String.valueOf(value)); 179 updateFrequencyBandSummary(frequencyPref, value); 180 } else { 181 Log.e(TAG, "Failed to fetch frequency band"); 182 } 183 } else { 184 if (frequencyPref != null) { 185 // null if it has already been removed before resume 186 getPreferenceScreen().removePreference(frequencyPref); 187 } 188 } 189 190 ListPreference sleepPolicyPref = (ListPreference) findPreference(KEY_SLEEP_POLICY); 191 if (sleepPolicyPref != null) { 192 if (Utils.isWifiOnly(context)) { 193 sleepPolicyPref.setEntries(R.array.wifi_sleep_policy_entries_wifi_only); 194 } 195 sleepPolicyPref.setOnPreferenceChangeListener(this); 196 int value = Settings.Global.getInt(getContentResolver(), 197 Settings.Global.WIFI_SLEEP_POLICY, 198 Settings.Global.WIFI_SLEEP_POLICY_NEVER); 199 String stringValue = String.valueOf(value); 200 sleepPolicyPref.setValue(stringValue); 201 updateSleepPolicySummary(sleepPolicyPref, stringValue); 202 } 203 } 204 205 private void updateSleepPolicySummary(Preference sleepPolicyPref, String value) { 206 if (value != null) { 207 String[] values = getResources().getStringArray(R.array.wifi_sleep_policy_values); 208 final int summaryArrayResId = Utils.isWifiOnly(getActivity()) ? 209 R.array.wifi_sleep_policy_entries_wifi_only : R.array.wifi_sleep_policy_entries; 210 String[] summaries = getResources().getStringArray(summaryArrayResId); 211 for (int i = 0; i < values.length; i++) { 212 if (value.equals(values[i])) { 213 if (i < summaries.length) { 214 sleepPolicyPref.setSummary(summaries[i]); 215 return; 216 } 217 } 218 } 219 } 220 221 sleepPolicyPref.setSummary(""); 222 Log.e(TAG, "Invalid sleep policy value: " + value); 223 } 224 225 private void updateFrequencyBandSummary(Preference frequencyBandPref, int index) { 226 String[] summaries = getResources().getStringArray(R.array.wifi_frequency_band_entries); 227 frequencyBandPref.setSummary(summaries[index]); 228 } 229 230 @Override 231 public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) { 232 String key = preference.getKey(); 233 234 if (KEY_NOTIFY_OPEN_NETWORKS.equals(key)) { 235 Global.putInt(getContentResolver(), 236 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 237 ((SwitchPreference) preference).isChecked() ? 1 : 0); 238 } else if (KEY_SCAN_ALWAYS_AVAILABLE.equals(key)) { 239 Global.putInt(getContentResolver(), 240 Global.WIFI_SCAN_ALWAYS_AVAILABLE, 241 ((SwitchPreference) preference).isChecked() ? 1 : 0); 242 } else { 243 return super.onPreferenceTreeClick(screen, preference); 244 } 245 return true; 246 } 247 248 @Override 249 public boolean onPreferenceChange(Preference preference, Object newValue) { 250 final Context context = getActivity(); 251 String key = preference.getKey(); 252 253 if (KEY_FREQUENCY_BAND.equals(key)) { 254 try { 255 int value = Integer.parseInt((String) newValue); 256 mWifiManager.setFrequencyBand(value, true); 257 updateFrequencyBandSummary(preference, value); 258 } catch (NumberFormatException e) { 259 Toast.makeText(context, R.string.wifi_setting_frequency_band_error, 260 Toast.LENGTH_SHORT).show(); 261 return false; 262 } 263 } else if (KEY_WIFI_ASSISTANT.equals(key)) { 264 if (((Boolean)newValue).booleanValue() == false) { 265 mNetworkScoreManager.setActiveScorer(null); 266 return true; 267 } 268 269 NetworkScorerAppData wifiAssistant = WifiSettings.getWifiAssistantApp(context); 270 Intent intent = new Intent(); 271 if (wifiAssistant.mConfigurationActivityClassName != null) { 272 // App has a custom configuration activity; launch that. 273 // This custom activity will be responsible for launching the system 274 // dialog. 275 intent.setClassName(wifiAssistant.mPackageName, 276 wifiAssistant.mConfigurationActivityClassName); 277 } else { 278 // Fall back on the system dialog. 279 intent.setAction(NetworkScoreManager.ACTION_CHANGE_ACTIVE); 280 intent.putExtra(NetworkScoreManager.EXTRA_PACKAGE_NAME, 281 wifiAssistant.mPackageName); 282 } 283 284 startActivity(intent); 285 } 286 287 if (KEY_SLEEP_POLICY.equals(key)) { 288 try { 289 String stringValue = (String) newValue; 290 Settings.Global.putInt(getContentResolver(), Settings.Global.WIFI_SLEEP_POLICY, 291 Integer.parseInt(stringValue)); 292 updateSleepPolicySummary(preference, stringValue); 293 } catch (NumberFormatException e) { 294 Toast.makeText(context, R.string.wifi_setting_sleep_policy_error, 295 Toast.LENGTH_SHORT).show(); 296 return false; 297 } 298 } 299 300 return true; 301 } 302 303 private void refreshWifiInfo() { 304 final Context context = getActivity(); 305 WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 306 307 Preference wifiMacAddressPref = findPreference(KEY_MAC_ADDRESS); 308 String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress(); 309 wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress 310 : context.getString(R.string.status_unavailable)); 311 wifiMacAddressPref.setSelectable(false); 312 313 Preference wifiIpAddressPref = findPreference(KEY_CURRENT_IP_ADDRESS); 314 String ipAddress = Utils.getWifiIpAddresses(context); 315 wifiIpAddressPref.setSummary(ipAddress == null ? 316 context.getString(R.string.status_unavailable) : ipAddress); 317 wifiIpAddressPref.setSelectable(false); 318 } 319 320 /* Wrapper class for the WPS dialog to properly handle life cycle events like rotation. */ 321 public static class WpsFragment extends DialogFragment { 322 private static int mWpsSetup; 323 324 // Public default constructor is required for rotation. 325 public WpsFragment() { 326 super(); 327 } 328 329 public WpsFragment(int wpsSetup) { 330 super(); 331 mWpsSetup = wpsSetup; 332 } 333 334 @Override 335 public Dialog onCreateDialog(Bundle savedInstanceState) { 336 return new WpsDialog(getActivity(), mWpsSetup); 337 } 338 } 339 340} 341