1/* 2 * Copyright (C) 2014 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.content.Context; 21import android.content.DialogInterface; 22import android.content.res.Resources; 23import android.net.wifi.ScanResult; 24import android.net.wifi.WifiConfiguration; 25import android.net.wifi.WifiManager; 26import android.os.Bundle; 27import android.preference.Preference; 28import android.preference.Preference.OnPreferenceClickListener; 29import android.preference.PreferenceScreen; 30 31import com.android.settings.search.BaseSearchIndexProvider; 32import com.android.settings.search.Indexable; 33import com.android.settings.search.SearchIndexableRaw; 34 35import android.util.Log; 36import android.view.View; 37 38import com.android.settings.R; 39import com.android.settings.SettingsPreferenceFragment; 40 41import java.util.ArrayList; 42import java.util.HashMap; 43import java.util.List; 44import java.util.Map; 45 46/** 47 * UI to manage saved networks/access points. 48 */ 49public class SavedAccessPointsWifiSettings extends SettingsPreferenceFragment 50 implements DialogInterface.OnClickListener, Indexable { 51 private static final String TAG = "SavedAccessPointsWifiSettings"; 52 53 private WifiDialog mDialog; 54 private WifiManager mWifiManager; 55 private AccessPoint mDlgAccessPoint; 56 private Bundle mAccessPointSavedState; 57 private AccessPoint mSelectedAccessPoint; 58 59 // Instance state key 60 private static final String SAVE_DIALOG_ACCESS_POINT_STATE = "wifi_ap_state"; 61 62 @Override 63 public void onCreate(Bundle savedInstanceState) { 64 super.onCreate(savedInstanceState); 65 addPreferencesFromResource(R.xml.wifi_display_saved_access_points); 66 } 67 68 @Override 69 public void onResume() { 70 super.onResume(); 71 initPreferences(); 72 } 73 74 @Override 75 public void onActivityCreated(Bundle savedInstanceState) { 76 super.onActivityCreated(savedInstanceState); 77 mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 78 79 if (savedInstanceState != null) { 80 if (savedInstanceState.containsKey(SAVE_DIALOG_ACCESS_POINT_STATE)) { 81 mAccessPointSavedState = 82 savedInstanceState.getBundle(SAVE_DIALOG_ACCESS_POINT_STATE); 83 } 84 } 85 } 86 87 private void initPreferences() { 88 PreferenceScreen preferenceScreen = getPreferenceScreen(); 89 final Context context = getActivity(); 90 91 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 92 final List<AccessPoint> accessPoints = constructSavedAccessPoints(context, mWifiManager); 93 94 preferenceScreen.removeAll(); 95 96 final int accessPointsSize = accessPoints.size(); 97 for (int i = 0; i < accessPointsSize; ++i){ 98 preferenceScreen.addPreference(accessPoints.get(i)); 99 } 100 101 if(getPreferenceScreen().getPreferenceCount() < 1) { 102 Log.w(TAG, "Saved networks activity loaded, but there are no saved networks!"); 103 } 104 } 105 106 private static List<AccessPoint> constructSavedAccessPoints(Context context, 107 WifiManager wifiManager){ 108 List<AccessPoint> accessPoints = new ArrayList<AccessPoint>(); 109 Map<String, List<ScanResult>> resultsMap = new HashMap<String, List<ScanResult>>(); 110 111 final List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks(); 112 final List<ScanResult> scanResults = wifiManager.getScanResults(); 113 114 if (configs != null) { 115 //Construct a Map for quick searching of a wifi network via ssid. 116 final int scanResultsSize = scanResults.size(); 117 for (int i = 0; i < scanResultsSize; ++i){ 118 final ScanResult result = scanResults.get(i); 119 List<ScanResult> res = resultsMap.get(result.SSID); 120 121 if(res == null){ 122 res = new ArrayList<ScanResult>(); 123 resultsMap.put(result.SSID, res); 124 } 125 126 res.add(result); 127 } 128 129 final int configsSize = configs.size(); 130 for (int i = 0; i < configsSize; ++i){ 131 WifiConfiguration config = configs.get(i); 132 if (config.selfAdded && config.numAssociation == 0) { 133 continue; 134 } 135 AccessPoint accessPoint = new AccessPoint(context, config); 136 final List<ScanResult> results = resultsMap.get(accessPoint.ssid); 137 138 accessPoint.setShowSummary(false); 139 if(results != null){ 140 final int resultsSize = results.size(); 141 for (int j = 0; j < resultsSize; ++j){ 142 accessPoint.update(results.get(j)); 143 accessPoint.setIcon(null); 144 } 145 } 146 147 accessPoints.add(accessPoint); 148 } 149 } 150 151 return accessPoints; 152 } 153 154 private void showDialog(AccessPoint accessPoint, boolean edit) { 155 if (mDialog != null) { 156 removeDialog(WifiSettings.WIFI_DIALOG_ID); 157 mDialog = null; 158 } 159 160 // Save the access point and edit mode 161 mDlgAccessPoint = accessPoint; 162 163 showDialog(WifiSettings.WIFI_DIALOG_ID); 164 } 165 166 @Override 167 public Dialog onCreateDialog(int dialogId) { 168 switch (dialogId) { 169 case WifiSettings.WIFI_DIALOG_ID: 170 if (mDlgAccessPoint == null) { // For re-launch from saved state 171 mDlgAccessPoint = new AccessPoint(getActivity(), mAccessPointSavedState); 172 // Reset the saved access point data 173 mAccessPointSavedState = null; 174 } 175 mSelectedAccessPoint = mDlgAccessPoint; 176 mDialog = new WifiDialog(getActivity(), this, mDlgAccessPoint, 177 false /* not editting */, true /* hide the submit button */); 178 return mDialog; 179 180 } 181 return super.onCreateDialog(dialogId); 182 } 183 184 @Override 185 public void onSaveInstanceState(Bundle outState) { 186 super.onSaveInstanceState(outState); 187 188 // If the dialog is showing, save its state. 189 if (mDialog != null && mDialog.isShowing()) { 190 if (mDlgAccessPoint != null) { 191 mAccessPointSavedState = new Bundle(); 192 mDlgAccessPoint.saveWifiState(mAccessPointSavedState); 193 outState.putBundle(SAVE_DIALOG_ACCESS_POINT_STATE, mAccessPointSavedState); 194 } 195 } 196 } 197 198 @Override 199 public void onClick(DialogInterface dialogInterface, int button) { 200 if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) { 201 mWifiManager.forget(mSelectedAccessPoint.networkId, null); 202 getPreferenceScreen().removePreference(mSelectedAccessPoint); 203 mSelectedAccessPoint = null; 204 } 205 } 206 207 @Override 208 public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) { 209 if (preference instanceof AccessPoint) { 210 showDialog((AccessPoint) preference, false); 211 return true; 212 } else{ 213 return super.onPreferenceTreeClick(screen, preference); 214 } 215 } 216 217 /** 218 * For search. 219 */ 220 public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 221 new BaseSearchIndexProvider() { 222 @Override 223 public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { 224 final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(); 225 final Resources res = context.getResources(); 226 final String title = res.getString(R.string.wifi_saved_access_points_titlebar); 227 228 // Add fragment title 229 SearchIndexableRaw data = new SearchIndexableRaw(context); 230 data.title = title; 231 data.screenTitle = title; 232 data.enabled = enabled; 233 result.add(data); 234 235 // Add available Wi-Fi access points 236 WifiManager wifiManager = 237 (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 238 final List<AccessPoint> accessPoints = 239 constructSavedAccessPoints(context, wifiManager); 240 241 final int accessPointsSize = accessPoints.size(); 242 for (int i = 0; i < accessPointsSize; ++i){ 243 data = new SearchIndexableRaw(context); 244 data.title = accessPoints.get(i).getTitle().toString(); 245 data.screenTitle = title; 246 data.enabled = enabled; 247 result.add(data); 248 } 249 250 return result; 251 } 252 }; 253} 254