Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2015 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 package com.android.settings.wifi;
     17 
     18 import android.content.BroadcastReceiver;
     19 import android.content.Context;
     20 import android.content.Intent;
     21 import android.content.IntentFilter;
     22 import android.content.res.Resources;
     23 import android.net.NetworkScoreManager;
     24 import android.net.NetworkScorerAppManager;
     25 import android.net.wifi.WifiConfiguration;
     26 import android.net.wifi.WifiInfo;
     27 import android.net.wifi.WifiManager;
     28 import android.os.Bundle;
     29 import android.os.UserManager;
     30 import android.provider.Settings;
     31 import android.support.v14.preference.SwitchPreference;
     32 import android.support.v7.preference.ListPreference;
     33 import android.support.v7.preference.Preference;
     34 import android.text.TextUtils;
     35 import android.util.Log;
     36 import android.widget.Toast;
     37 import com.android.internal.logging.MetricsProto.MetricsEvent;
     38 import com.android.settings.AppListSwitchPreference;
     39 import com.android.settings.R;
     40 import com.android.settings.SettingsPreferenceFragment;
     41 import com.android.settings.Utils;
     42 
     43 import java.util.Collection;
     44 import java.util.List;
     45 
     46 public class ConfigureWifiSettings extends SettingsPreferenceFragment
     47         implements Preference.OnPreferenceChangeListener {
     48     private static final String TAG = "ConfigureWifiSettings";
     49 
     50     private static final String KEY_MAC_ADDRESS = "mac_address";
     51     private static final String KEY_SAVED_NETWORKS = "saved_networks";
     52     private static final String KEY_CURRENT_IP_ADDRESS = "current_ip_address";
     53     private static final String KEY_NOTIFY_OPEN_NETWORKS = "notify_open_networks";
     54     private static final String KEY_SLEEP_POLICY = "sleep_policy";
     55     private static final String KEY_CELLULAR_FALLBACK = "wifi_cellular_data_fallback";
     56     private static final String KEY_WIFI_ASSISTANT = "wifi_assistant";
     57 
     58     private WifiManager mWifiManager;
     59     private NetworkScoreManager mNetworkScoreManager;
     60     private AppListSwitchPreference mWifiAssistantPreference;
     61 
     62     private IntentFilter mFilter;
     63 
     64     @Override
     65     public void onCreate(Bundle icicle) {
     66         super.onCreate(icicle);
     67         addPreferencesFromResource(R.xml.wifi_configure_settings);
     68     }
     69 
     70     @Override
     71     public void onActivityCreated(Bundle savedInstanceState) {
     72         super.onActivityCreated(savedInstanceState);
     73         mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
     74         mFilter = new IntentFilter();
     75         mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
     76         mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
     77         mNetworkScoreManager =
     78                 (NetworkScoreManager) getSystemService(Context.NETWORK_SCORE_SERVICE);
     79     }
     80 
     81     @Override
     82     public void onResume() {
     83         super.onResume();
     84         initPreferences();
     85         getActivity().registerReceiver(mReceiver, mFilter);
     86         refreshWifiInfo();
     87     }
     88 
     89     @Override
     90     public void onPause() {
     91         super.onPause();
     92         getActivity().unregisterReceiver(mReceiver);
     93     }
     94 
     95     private void initPreferences() {
     96         List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
     97         if (configs == null || configs.size() == 0) {
     98             removePreference(KEY_SAVED_NETWORKS);
     99         }
    100 
    101         SwitchPreference notifyOpenNetworks =
    102                 (SwitchPreference) findPreference(KEY_NOTIFY_OPEN_NETWORKS);
    103         notifyOpenNetworks.setChecked(Settings.Global.getInt(getContentResolver(),
    104                 Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1);
    105         notifyOpenNetworks.setEnabled(mWifiManager.isWifiEnabled());
    106 
    107         final Context context = getActivity();
    108         if (avoidBadWifiConfig()) {
    109             // Hide preference toggle, always avoid bad wifi networks.
    110             removePreference(KEY_CELLULAR_FALLBACK);
    111         } else {
    112             // Show preference toggle, initialized based on current settings value.
    113             boolean currentSetting = avoidBadWifiCurrentSettings();
    114             SwitchPreference pref = (SwitchPreference) findPreference(KEY_CELLULAR_FALLBACK);
    115             // TODO: can this ever be null? The return value of avoidBadWifiConfig() can only
    116             // change if the resources change, but if that happens the activity will be recreated...
    117             if (pref != null) {
    118                 pref.setChecked(currentSetting);
    119             }
    120         }
    121 
    122         mWifiAssistantPreference = (AppListSwitchPreference) findPreference(KEY_WIFI_ASSISTANT);
    123         Collection<NetworkScorerAppManager.NetworkScorerAppData> scorers =
    124                 NetworkScorerAppManager.getAllValidScorers(context);
    125         if (UserManager.get(context).isAdminUser() && !scorers.isEmpty()) {
    126             mWifiAssistantPreference.setOnPreferenceChangeListener(this);
    127             initWifiAssistantPreference(scorers);
    128         } else if (mWifiAssistantPreference != null) {
    129             getPreferenceScreen().removePreference(mWifiAssistantPreference);
    130         }
    131 
    132         ListPreference sleepPolicyPref = (ListPreference) findPreference(KEY_SLEEP_POLICY);
    133         if (sleepPolicyPref != null) {
    134             if (Utils.isWifiOnly(context)) {
    135                 sleepPolicyPref.setEntries(R.array.wifi_sleep_policy_entries_wifi_only);
    136             }
    137             sleepPolicyPref.setOnPreferenceChangeListener(this);
    138             int value = Settings.Global.getInt(getContentResolver(),
    139                     Settings.Global.WIFI_SLEEP_POLICY,
    140                     Settings.Global.WIFI_SLEEP_POLICY_NEVER);
    141             String stringValue = String.valueOf(value);
    142             sleepPolicyPref.setValue(stringValue);
    143             updateSleepPolicySummary(sleepPolicyPref, stringValue);
    144         }
    145     }
    146 
    147     private void updateSleepPolicySummary(Preference sleepPolicyPref, String value) {
    148         if (value != null) {
    149             String[] values = getResources().getStringArray(R.array.wifi_sleep_policy_values);
    150             final int summaryArrayResId = Utils.isWifiOnly(getActivity()) ?
    151                     R.array.wifi_sleep_policy_entries_wifi_only : R.array.wifi_sleep_policy_entries;
    152             String[] summaries = getResources().getStringArray(summaryArrayResId);
    153             for (int i = 0; i < values.length; i++) {
    154                 if (value.equals(values[i])) {
    155                     if (i < summaries.length) {
    156                         sleepPolicyPref.setSummary(summaries[i]);
    157                         return;
    158                     }
    159                 }
    160             }
    161         }
    162 
    163         sleepPolicyPref.setSummary("");
    164         Log.e(TAG, "Invalid sleep policy value: " + value);
    165     }
    166 
    167     private boolean avoidBadWifiConfig() {
    168         return getActivity().getResources().getInteger(
    169                 com.android.internal.R.integer.config_networkAvoidBadWifi) == 1;
    170     }
    171 
    172     private boolean avoidBadWifiCurrentSettings() {
    173         return "1".equals(Settings.Global.getString(getContentResolver(),
    174                 Settings.Global.NETWORK_AVOID_BAD_WIFI));
    175     }
    176 
    177     @Override
    178     public boolean onPreferenceTreeClick(Preference preference) {
    179         String key = preference.getKey();
    180 
    181         if (KEY_NOTIFY_OPEN_NETWORKS.equals(key)) {
    182             Settings.Global.putInt(getContentResolver(),
    183                     Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
    184                     ((SwitchPreference) preference).isChecked() ? 1 : 0);
    185         } else if (KEY_CELLULAR_FALLBACK.equals(key)) {
    186             // On: avoid bad wifi. Off: prompt.
    187             String settingName = Settings.Global.NETWORK_AVOID_BAD_WIFI;
    188             Settings.Global.putString(getContentResolver(), settingName,
    189                     ((SwitchPreference) preference).isChecked() ? "1" : null);
    190         } else {
    191             return super.onPreferenceTreeClick(preference);
    192         }
    193         return true;
    194     }
    195 
    196     @Override
    197     public boolean onPreferenceChange(Preference preference, Object newValue) {
    198         final Context context = getActivity();
    199         String key = preference.getKey();
    200 
    201         if (KEY_WIFI_ASSISTANT.equals(key)) {
    202             NetworkScorerAppManager.NetworkScorerAppData wifiAssistant =
    203                     NetworkScorerAppManager.getScorer(context, (String) newValue);
    204             if (wifiAssistant == null) {
    205                 mNetworkScoreManager.setActiveScorer(null);
    206                 return true;
    207             }
    208 
    209             Intent intent = new Intent();
    210             if (wifiAssistant.mConfigurationActivityClassName != null) {
    211                 // App has a custom configuration activity; launch that.
    212                 // This custom activity will be responsible for launching the system
    213                 // dialog.
    214                 intent.setClassName(wifiAssistant.mPackageName,
    215                         wifiAssistant.mConfigurationActivityClassName);
    216             } else {
    217                 // Fall back on the system dialog.
    218                 intent.setAction(NetworkScoreManager.ACTION_CHANGE_ACTIVE);
    219                 intent.putExtra(NetworkScoreManager.EXTRA_PACKAGE_NAME,
    220                         wifiAssistant.mPackageName);
    221             }
    222 
    223             startActivity(intent);
    224             // Don't update the preference widget state until the child activity returns.
    225             // It will be updated in onResume after the activity finishes.
    226             return false;
    227         }
    228 
    229         if (KEY_SLEEP_POLICY.equals(key)) {
    230             try {
    231                 String stringValue = (String) newValue;
    232                 Settings.Global.putInt(getContentResolver(), Settings.Global.WIFI_SLEEP_POLICY,
    233                         Integer.parseInt(stringValue));
    234                 updateSleepPolicySummary(preference, stringValue);
    235             } catch (NumberFormatException e) {
    236                 Toast.makeText(context, R.string.wifi_setting_sleep_policy_error,
    237                         Toast.LENGTH_SHORT).show();
    238                 return false;
    239             }
    240         }
    241 
    242         return true;
    243     }
    244 
    245     private void refreshWifiInfo() {
    246         final Context context = getActivity();
    247         WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
    248 
    249         Preference wifiMacAddressPref = findPreference(KEY_MAC_ADDRESS);
    250         String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
    251         wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress
    252                 : context.getString(R.string.status_unavailable));
    253         wifiMacAddressPref.setSelectable(false);
    254 
    255         Preference wifiIpAddressPref = findPreference(KEY_CURRENT_IP_ADDRESS);
    256         String ipAddress = Utils.getWifiIpAddresses(context);
    257         wifiIpAddressPref.setSummary(ipAddress == null ?
    258                 context.getString(R.string.status_unavailable) : ipAddress);
    259         wifiIpAddressPref.setSelectable(false);
    260     }
    261 
    262     private void initWifiAssistantPreference(
    263             Collection<NetworkScorerAppManager.NetworkScorerAppData> scorers) {
    264         int count = scorers.size();
    265         String[] packageNames = new String[count];
    266         int i = 0;
    267         for (NetworkScorerAppManager.NetworkScorerAppData scorer : scorers) {
    268             packageNames[i] = scorer.mPackageName;
    269             i++;
    270         }
    271         mWifiAssistantPreference.setPackageNames(packageNames,
    272                 mNetworkScoreManager.getActiveScorerPackage());
    273     }
    274 
    275     @Override
    276     protected int getMetricsCategory() {
    277         return MetricsEvent.CONFIGURE_WIFI;
    278     }
    279 
    280     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    281         @Override
    282         public void onReceive(Context context, Intent intent) {
    283             String action = intent.getAction();
    284             if (action.equals(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION) ||
    285                 action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
    286                 refreshWifiInfo();
    287             }
    288         }
    289     };
    290 }
    291