OSDN Git Service

Merge "Refactor NetworkScoreAppManager for testing."
[android-x86/packages-apps-Settings.git] / src / com / android / settings / wifi / ConfigureWifiSettings.java
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                 new NetworkScorerAppManager(context).getAllValidScorers();
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                     new NetworkScorerAppManager(context).getScorer((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 }