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.internal.logging.MetricsLogger; 46 import com.android.settings.AppListSwitchPreference; 47 import com.android.settings.R; 48 import com.android.settings.SettingsPreferenceFragment; 49 import com.android.settings.Utils; 50 51 import java.util.Collection; 52 53 public class AdvancedWifiSettings extends SettingsPreferenceFragment 54 implements Preference.OnPreferenceChangeListener { 55 56 private static final String TAG = "AdvancedWifiSettings"; 57 private static final String KEY_MAC_ADDRESS = "mac_address"; 58 private static final String KEY_CURRENT_IP_ADDRESS = "current_ip_address"; 59 private static final String KEY_FREQUENCY_BAND = "frequency_band"; 60 private static final String KEY_NOTIFY_OPEN_NETWORKS = "notify_open_networks"; 61 private static final String KEY_SLEEP_POLICY = "sleep_policy"; 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 getMetricsCategory()85 protected int getMetricsCategory() { 86 return MetricsLogger.WIFI_ADVANCED; 87 } 88 89 @Override onCreate(Bundle savedInstanceState)90 public void onCreate(Bundle savedInstanceState) { 91 super.onCreate(savedInstanceState); 92 addPreferencesFromResource(R.xml.wifi_advanced_settings); 93 } 94 95 @Override onActivityCreated(Bundle savedInstanceState)96 public void onActivityCreated(Bundle savedInstanceState) { 97 super.onActivityCreated(savedInstanceState); 98 mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 99 mFilter = new IntentFilter(); 100 mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); 101 mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 102 mNetworkScoreManager = 103 (NetworkScoreManager) getSystemService(Context.NETWORK_SCORE_SERVICE); 104 } 105 106 @Override onResume()107 public void onResume() { 108 super.onResume(); 109 initPreferences(); 110 getActivity().registerReceiver(mReceiver, mFilter); 111 refreshWifiInfo(); 112 } 113 114 @Override onPause()115 public void onPause() { 116 super.onPause(); 117 getActivity().unregisterReceiver(mReceiver); 118 } 119 initPreferences()120 private void initPreferences() { 121 SwitchPreference notifyOpenNetworks = 122 (SwitchPreference) findPreference(KEY_NOTIFY_OPEN_NETWORKS); 123 notifyOpenNetworks.setChecked(Settings.Global.getInt(getContentResolver(), 124 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1); 125 notifyOpenNetworks.setEnabled(mWifiManager.isWifiEnabled()); 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 { 249 return super.onPreferenceTreeClick(screen, preference); 250 } 251 return true; 252 } 253 254 @Override onPreferenceChange(Preference preference, Object newValue)255 public boolean onPreferenceChange(Preference preference, Object newValue) { 256 final Context context = getActivity(); 257 String key = preference.getKey(); 258 259 if (KEY_FREQUENCY_BAND.equals(key)) { 260 try { 261 int value = Integer.parseInt((String) newValue); 262 mWifiManager.setFrequencyBand(value, true); 263 updateFrequencyBandSummary(preference, value); 264 } catch (NumberFormatException e) { 265 Toast.makeText(context, R.string.wifi_setting_frequency_band_error, 266 Toast.LENGTH_SHORT).show(); 267 return false; 268 } 269 } else if (KEY_WIFI_ASSISTANT.equals(key)) { 270 NetworkScorerAppData wifiAssistant = 271 NetworkScorerAppManager.getScorer(context, (String) newValue); 272 if (wifiAssistant == null) { 273 mNetworkScoreManager.setActiveScorer(null); 274 return true; 275 } 276 277 Intent intent = new Intent(); 278 if (wifiAssistant.mConfigurationActivityClassName != null) { 279 // App has a custom configuration activity; launch that. 280 // This custom activity will be responsible for launching the system 281 // dialog. 282 intent.setClassName(wifiAssistant.mPackageName, 283 wifiAssistant.mConfigurationActivityClassName); 284 } else { 285 // Fall back on the system dialog. 286 intent.setAction(NetworkScoreManager.ACTION_CHANGE_ACTIVE); 287 intent.putExtra(NetworkScoreManager.EXTRA_PACKAGE_NAME, 288 wifiAssistant.mPackageName); 289 } 290 291 startActivity(intent); 292 // Don't update the preference widget state until the child activity returns. 293 // It will be updated in onResume after the activity finishes. 294 return false; 295 } 296 297 if (KEY_SLEEP_POLICY.equals(key)) { 298 try { 299 String stringValue = (String) newValue; 300 Settings.Global.putInt(getContentResolver(), Settings.Global.WIFI_SLEEP_POLICY, 301 Integer.parseInt(stringValue)); 302 updateSleepPolicySummary(preference, stringValue); 303 } catch (NumberFormatException e) { 304 Toast.makeText(context, R.string.wifi_setting_sleep_policy_error, 305 Toast.LENGTH_SHORT).show(); 306 return false; 307 } 308 } 309 310 return true; 311 } 312 refreshWifiInfo()313 private void refreshWifiInfo() { 314 final Context context = getActivity(); 315 WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); 316 317 Preference wifiMacAddressPref = findPreference(KEY_MAC_ADDRESS); 318 String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress(); 319 wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress 320 : context.getString(R.string.status_unavailable)); 321 wifiMacAddressPref.setSelectable(false); 322 323 Preference wifiIpAddressPref = findPreference(KEY_CURRENT_IP_ADDRESS); 324 String ipAddress = Utils.getWifiIpAddresses(context); 325 wifiIpAddressPref.setSummary(ipAddress == null ? 326 context.getString(R.string.status_unavailable) : ipAddress); 327 wifiIpAddressPref.setSelectable(false); 328 } 329 330 /* Wrapper class for the WPS dialog to properly handle life cycle events like rotation. */ 331 public static class WpsFragment extends DialogFragment { 332 private static int mWpsSetup; 333 334 // Public default constructor is required for rotation. WpsFragment()335 public WpsFragment() { 336 super(); 337 } 338 WpsFragment(int wpsSetup)339 public WpsFragment(int wpsSetup) { 340 super(); 341 mWpsSetup = wpsSetup; 342 } 343 344 @Override onCreateDialog(Bundle savedInstanceState)345 public Dialog onCreateDialog(Bundle savedInstanceState) { 346 return new WpsDialog(getActivity(), mWpsSetup); 347 } 348 } 349 350 } 351