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