WifiSettings.java revision d36699282cbd0a6897f425106081d3f2c0db55d4
1/*
2 * Copyright (C) 2010 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.Activity;
20import android.content.BroadcastReceiver;
21import android.content.Context;
22import android.content.DialogInterface;
23import android.content.Intent;
24import android.content.IntentFilter;
25import android.net.ConnectivityManager;
26import android.net.NetworkInfo;
27import android.net.NetworkInfo.DetailedState;
28import android.net.wifi.ScanResult;
29import android.net.wifi.SupplicantState;
30import android.net.wifi.WifiConfiguration;
31import android.net.wifi.WifiConfiguration.KeyMgmt;
32import android.net.wifi.WifiInfo;
33import android.net.wifi.WifiManager;
34import android.os.Bundle;
35import android.os.Handler;
36import android.os.Message;
37import android.preference.CheckBoxPreference;
38import android.preference.Preference;
39import android.preference.PreferenceScreen;
40import android.provider.Settings.Secure;
41import android.security.Credentials;
42import android.security.KeyStore;
43import android.util.Log;
44import android.view.ContextMenu;
45import android.view.ContextMenu.ContextMenuInfo;
46import android.view.Menu;
47import android.view.MenuInflater;
48import android.view.MenuItem;
49import android.view.View;
50import android.view.View.OnClickListener;
51import android.widget.AdapterView.AdapterContextMenuInfo;
52import android.widget.Button;
53import android.widget.ProgressBar;
54import android.widget.TextView;
55import android.widget.Toast;
56
57import com.android.settings.ProgressCategoryBase;
58import com.android.settings.R;
59import com.android.settings.SettingsPreferenceFragment;
60
61import java.util.Collection;
62import java.util.List;
63import java.util.TreeSet;
64
65/**
66 * This currently provides three types of UI.
67 *
68 * Two are for phones with relatively small screens: "for SetupWizard" and "for usual Settings".
69 * Users just need to launch WifiSettings Activity as usual. The request will be appropriately
70 * handled by ActivityManager, and they will have appropriate look-and-feel with this fragment.
71 *
72 * Third type is for Setup Wizard with X-Large, landscape UI. Users need to launch
73 * {@link WifiSettingsForSetupWizardXL} Activity, which contains this fragment but also has
74 * other decorations specific to that screen.
75 */
76public class WifiSettings extends SettingsPreferenceFragment
77        implements DialogInterface.OnClickListener {
78    private static final int MENU_ID_SCAN = Menu.FIRST;
79    private static final int MENU_ID_ADVANCED = Menu.FIRST + 1;
80    private static final int MENU_ID_CONNECT = Menu.FIRST + 2;
81    private static final int MENU_ID_FORGET = Menu.FIRST + 3;
82    private static final int MENU_ID_MODIFY = Menu.FIRST + 4;
83
84    // Indicates that this fragment is used as a part of Setup Wizard with XL screen settings.
85    // This fragment should show information which has been shown as Dialog in combined UI
86    // inside this fragment.
87    /* package */ static final String IN_XL_SETUP_WIZARD = "in_setup_wizard";
88
89    // this boolean extra specifies whether to disable the Next button when not connected
90    // Note: this is only effective in Setup Wizard with XL screen size.
91    private static final String EXTRA_ENABLE_NEXT_ON_CONNECT = "wifi_enable_next_on_connect";
92
93    private final IntentFilter mFilter;
94    private final BroadcastReceiver mReceiver;
95    private final Scanner mScanner;
96
97    private WifiManager mWifiManager;
98    private WifiEnabler mWifiEnabler;
99    private CheckBoxPreference mNotifyOpenNetworks;
100    private ProgressCategoryBase mAccessPoints;
101    private Preference mAddNetwork;
102    // An access point being editted is stored here.
103    private AccessPoint mSelectedAccessPoint;
104
105    private DetailedState mLastState;
106    private WifiInfo mLastInfo;
107
108    private int mKeyStoreNetworkId = -1;
109
110    // should Next button only be enabled when we have a connection?
111    private boolean mEnableNextOnConnection;
112    private boolean mInXlSetupWizard;
113
114
115    // TODO: merge into one
116    private WifiConfigPreference mConfigPreference;
117    private WifiDialog mDialog;
118
119    private boolean mRefrainListUpdate;
120
121    public WifiSettings() {
122        mFilter = new IntentFilter();
123        mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
124        mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
125        mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
126        mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
127        mFilter.addAction(WifiManager.SUPPLICANT_CONFIG_CHANGED_ACTION);
128        mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
129        mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
130
131        mReceiver = new BroadcastReceiver() {
132            @Override
133            public void onReceive(Context context, Intent intent) {
134                handleEvent(intent);
135            }
136        };
137
138        mScanner = new Scanner();
139    }
140
141    @Override
142    public void onActivityCreated(Bundle savedInstanceState) {
143        // We don't call super.onActivityCreated() here, since it assumes we already set up
144        // Preference (probably in onCreate()), while WifiSettings exceptionally set it up in
145        // this method.
146
147        mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
148
149        final Activity activity = getActivity();
150        final Intent intent = activity.getIntent();
151
152        mInXlSetupWizard = intent.getBooleanExtra(IN_XL_SETUP_WIZARD, false);
153
154        // if we're supposed to enable/disable the Next button based on our current connection
155        // state, start it off in the right state
156        mEnableNextOnConnection = intent.getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false);
157
158        if (mEnableNextOnConnection) {
159            if (mEnableNextOnConnection && hasNextButton()) {
160                final ConnectivityManager connectivity = (ConnectivityManager)
161                        getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
162                if (connectivity != null) {
163                    NetworkInfo info = connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
164                    changeNextButtonState(info.isConnected());
165                }
166            }
167        }
168
169        if (mInXlSetupWizard) {
170            addPreferencesFromResource(R.xml.wifi_access_points_for_wifi_setup_xl);
171        } else if (intent.getBooleanExtra("only_access_points", false)) {
172            addPreferencesFromResource(R.xml.wifi_access_points);
173        } else {
174            addPreferencesFromResource(R.xml.wifi_settings);
175            mWifiEnabler = new WifiEnabler(activity,
176                    (CheckBoxPreference) findPreference("enable_wifi"));
177            mNotifyOpenNetworks =
178                    (CheckBoxPreference) findPreference("notify_open_networks");
179            mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(),
180                    Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1);
181        }
182
183        // After confirming PreferenceScreen is available, we call super.
184        super.onActivityCreated(savedInstanceState);
185
186        // This may be either ProgressCategory or AccessPointCategoryForXL.
187        final ProgressCategoryBase preference =
188                (ProgressCategoryBase) findPreference("access_points");
189        mAccessPoints = preference;
190        mAccessPoints.setOrderingAsAdded(true);
191        mAddNetwork = findPreference("add_network");
192
193        registerForContextMenu(getListView());
194
195        setHasOptionsMenu(true);
196    }
197
198    @Override
199    public void onResume() {
200        super.onResume();
201        if (mWifiEnabler != null) {
202            mWifiEnabler.resume();
203        }
204        getActivity().registerReceiver(mReceiver, mFilter);
205        if (mKeyStoreNetworkId != -1 && KeyStore.getInstance().test() == KeyStore.NO_ERROR) {
206            mWifiManager.connectNetwork(mKeyStoreNetworkId);
207        }
208        mKeyStoreNetworkId = -1;
209        if (mInXlSetupWizard) {
210            // We show "Now scanning"
211            final int wifiState = mWifiManager.getWifiState();
212            switch (wifiState) {
213            case WifiManager.WIFI_STATE_ENABLED: {
214                updateAccessPoints();
215                break;
216            }
217            case WifiManager.WIFI_STATE_DISABLED:
218            case WifiManager.WIFI_STATE_DISABLING:
219            case WifiManager.WIFI_STATE_UNKNOWN: {
220                mWifiManager.setWifiEnabled(true);
221            } // $FALL-THROUGH$
222            default: {
223                mAccessPoints.removeAll();
224                Preference preference = new Preference(getActivity());
225                preference.setLayoutResource(R.layout.preference_widget_shortcut);
226                preference.setSelectable(false);
227                preference.setTitle("Connecting");
228                preference.setSummary("COONNECTING");
229                mAccessPoints.addPreference(preference);
230                break;
231            }
232            }
233        } else {
234            Log.d("@@@", "updateAccessPoints");
235            updateAccessPoints();
236        }
237    }
238
239    @Override
240    public void onPause() {
241        super.onPause();
242        if (mWifiEnabler != null) {
243            mWifiEnabler.pause();
244        }
245        getActivity().unregisterReceiver(mReceiver);
246        mScanner.pause();
247        if (mDialog != null) {
248            mDialog.dismiss();
249            mDialog = null;
250        }
251    }
252
253    @Override
254    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
255        // We don't want menus in Setup Wizard XL.
256        if (!mInXlSetupWizard) {
257            menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)
258                    .setIcon(R.drawable.ic_menu_scan_network);
259            menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)
260                    .setIcon(android.R.drawable.ic_menu_manage);
261        }
262        super.onCreateOptionsMenu(menu, inflater);
263    }
264
265    @Override
266    public boolean onOptionsItemSelected(MenuItem item) {
267        switch (item.getItemId()) {
268            case MENU_ID_SCAN:
269                if (mWifiManager.isWifiEnabled()) {
270                    mScanner.resume();
271                }
272                return true;
273            case MENU_ID_ADVANCED:
274                startActivity(new Intent(getActivity(), AdvancedSettings.class));
275                return true;
276        }
277        return super.onOptionsItemSelected(item);
278    }
279
280    @Override
281    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo info) {
282        if (info instanceof AdapterContextMenuInfo) {
283            Preference preference = (Preference) getListView().getItemAtPosition(
284                    ((AdapterContextMenuInfo) info).position);
285
286            if (preference instanceof AccessPoint) {
287                mSelectedAccessPoint = (AccessPoint) preference;
288                menu.setHeaderTitle(mSelectedAccessPoint.ssid);
289                if (mSelectedAccessPoint.getLevel() != -1
290                        && mSelectedAccessPoint.getState() == null) {
291                    menu.add(Menu.NONE, MENU_ID_CONNECT, 0, R.string.wifi_menu_connect);
292                }
293                if (mSelectedAccessPoint.networkId != -1) {
294                    menu.add(Menu.NONE, MENU_ID_FORGET, 0, R.string.wifi_menu_forget);
295                    if (mSelectedAccessPoint.security != AccessPoint.SECURITY_NONE) {
296                        menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
297                    }
298                }
299            }
300        }
301    }
302
303    @Override
304    public boolean onContextItemSelected(MenuItem item) {
305        if (mSelectedAccessPoint == null) {
306            return super.onContextItemSelected(item);
307        }
308        switch (item.getItemId()) {
309            case MENU_ID_CONNECT: {
310                if (mSelectedAccessPoint.networkId != -1) {
311                    if (!requireKeyStore(mSelectedAccessPoint.getConfig())) {
312                        mWifiManager.connectNetwork(mSelectedAccessPoint.networkId);
313                    }
314                } else if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE) {
315                    // Shortcut for open networks.
316                    WifiConfiguration config = new WifiConfiguration();
317                    config.SSID = AccessPoint.convertToQuotedString(mSelectedAccessPoint.ssid);
318                    config.allowedKeyManagement.set(KeyMgmt.NONE);
319                    mWifiManager.connectNetwork(config);
320                } else {
321                    showConfigUi(mSelectedAccessPoint, true);
322                }
323                return true;
324            }
325            case MENU_ID_FORGET: {
326                mWifiManager.forgetNetwork(mSelectedAccessPoint.networkId);
327                return true;
328            }
329            case MENU_ID_MODIFY: {
330                showConfigUi(mSelectedAccessPoint, true);
331                return true;
332            }
333        }
334        return super.onContextItemSelected(item);
335    }
336
337    @Override
338    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
339        if (preference instanceof AccessPoint) {
340            mSelectedAccessPoint = (AccessPoint) preference;
341            showConfigUi(mSelectedAccessPoint, false);
342        } else if (preference == mAddNetwork) {
343            onAddNetworkPressed();
344        } else if (preference == mNotifyOpenNetworks) {
345            Secure.putInt(getContentResolver(),
346                    Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
347                    mNotifyOpenNetworks.isChecked() ? 1 : 0);
348        } else {
349            return super.onPreferenceTreeClick(screen, preference);
350        }
351        return true;
352    }
353
354    /**
355     * Called when a user clicks "Add network" preference or relevant button.
356     */
357    private void showConfigUi(AccessPoint accessPoint, boolean edit) {
358        synchronized (this) {
359            mRefrainListUpdate = false;
360        }
361        if (mInXlSetupWizard) {
362            final Activity activity = getActivity();
363            activity.findViewById(R.id.wifi_setup_connect).setVisibility(View.VISIBLE);
364            activity.findViewById(R.id.wifi_setup_cancel).setVisibility(View.VISIBLE);
365            showConfigPreference(accessPoint, edit);
366        } else {
367            showDialog(accessPoint, edit);
368        }
369    }
370
371    private void showConfigPreference(AccessPoint accessPoint, boolean edit) {
372        // We don't want to show more than one WifiConfigPreference
373        if (mConfigPreference != null) {
374            mAccessPoints.removePreference(mConfigPreference);
375        }
376
377        mConfigPreference = new WifiConfigPreference(this, this, accessPoint, edit);
378        toggleButtonsVisibility(false);
379
380        updateAccessPoints();
381        mScanner.pause();
382    }
383
384    private void toggleButtonsVisibility(boolean firstLayout) {
385        final Activity activity = getActivity();
386        if (firstLayout) {
387            activity.findViewById(R.id.wifi_setup_add_network).setVisibility(View.VISIBLE);
388            activity.findViewById(R.id.wifi_setup_refresh_list).setVisibility(View.VISIBLE);
389            activity.findViewById(R.id.wifi_setup_skip_or_next).setVisibility(View.VISIBLE);
390            activity.findViewById(R.id.wifi_setup_connect).setVisibility(View.GONE);
391            activity.findViewById(R.id.wifi_setup_forget).setVisibility(View.GONE);
392            activity.findViewById(R.id.wifi_setup_cancel).setVisibility(View.GONE);
393        } else {
394            activity.findViewById(R.id.wifi_setup_add_network).setVisibility(View.GONE);
395            activity.findViewById(R.id.wifi_setup_refresh_list).setVisibility(View.GONE);
396            activity.findViewById(R.id.wifi_setup_skip_or_next).setVisibility(View.GONE);
397
398            // made visible from controller.
399        }
400    }
401
402    private void showDialog(AccessPoint accessPoint, boolean edit) {
403        if (mDialog != null) {
404            mDialog.dismiss();
405        }
406        mDialog = new WifiDialog(getActivity(), this, accessPoint, edit);
407        mDialog.show();
408    }
409
410    private boolean requireKeyStore(WifiConfiguration config) {
411        if (WifiConfigController.requireKeyStore(config) &&
412                KeyStore.getInstance().test() != KeyStore.NO_ERROR) {
413            mKeyStoreNetworkId = config.networkId;
414            Credentials.getInstance().unlock(getActivity());
415            return true;
416        }
417        return false;
418    }
419
420    /**
421     * Shows the latest access points available with supplimental information like
422     * the strength of network and the security for it.
423     */
424    private void updateAccessPoints() {
425        synchronized (this) {
426            if (mRefrainListUpdate) {
427                return;
428            }
429        }
430
431        if (mConfigPreference != null) {
432            mAccessPoints.removeAll();
433            final AccessPoint parent = mConfigPreference.getAccessPoint();
434            if (parent != null) {
435                parent.setSelectable(false);
436                mAccessPoints.addPreference(parent);
437            }
438            mAccessPoints.addPreference(mConfigPreference);
439        } else {
440            // AccessPoints are automatically sorted with TreeSet.
441            final Collection<AccessPoint> accessPoints = constructAccessPoints();
442            mAccessPoints.removeAll();
443            for (AccessPoint accessPoint : accessPoints) {
444                mAccessPoints.addPreference(accessPoint);
445            }
446        }
447    }
448
449    private Collection<AccessPoint> constructAccessPoints() {
450        Collection<AccessPoint> accessPoints =
451                new TreeSet<AccessPoint>(new AccessPoint.Comparater());
452
453        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
454        if (configs != null) {
455            for (WifiConfiguration config : configs) {
456                AccessPoint accessPoint = new AccessPoint(getActivity(), config);
457                accessPoint.update(mLastInfo, mLastState);
458                accessPoints.add(accessPoint);
459            }
460        }
461
462        final List<ScanResult> results = mWifiManager.getScanResults();
463        if (results != null) {
464            for (ScanResult result : results) {
465                // Ignore hidden and ad-hoc networks.
466                if (result.SSID == null || result.SSID.length() == 0 ||
467                        result.capabilities.contains("[IBSS]")) {
468                    continue;
469                }
470
471                boolean found = false;
472                for (AccessPoint accessPoint : accessPoints) {
473                    if (accessPoint.update(result)) {
474                        found = true;
475                    }
476                }
477                if (!found) {
478                    accessPoints.add(new AccessPoint(getActivity(), result));
479                }
480            }
481        }
482
483        return accessPoints;
484    }
485
486    private void handleEvent(Intent intent) {
487        String action = intent.getAction();
488        if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
489            updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
490                    WifiManager.WIFI_STATE_UNKNOWN));
491        } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) ||
492                WifiManager.SUPPLICANT_CONFIG_CHANGED_ACTION.equals(action)) {
493                updateAccessPoints();
494        } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
495            updateConnectionState(WifiInfo.getDetailedStateOf((SupplicantState)
496                    intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)));
497        } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
498            NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(
499                    WifiManager.EXTRA_NETWORK_INFO);
500            changeNextButtonState(info.isConnected());
501            updateConnectionState(info.getDetailedState());
502        } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
503            updateConnectionState(null);
504        }
505    }
506
507    private void updateConnectionState(DetailedState state) {
508        /* sticky broadcasts can call this when wifi is disabled */
509        if (!mWifiManager.isWifiEnabled()) {
510            mScanner.pause();
511            return;
512        }
513
514        if (state == DetailedState.OBTAINING_IPADDR) {
515            mScanner.pause();
516        } else {
517            mScanner.resume();
518        }
519
520        mLastInfo = mWifiManager.getConnectionInfo();
521        if (state != null) {
522            mLastState = state;
523        }
524
525        for (int i = mAccessPoints.getPreferenceCount() - 1; i >= 0; --i) {
526            // Maybe there's a WifiConfigPreference
527            Preference preference = mAccessPoints.getPreference(i);
528            if (preference instanceof AccessPoint) {
529                ((AccessPoint) preference).update(mLastInfo, mLastState);
530            }
531        }
532
533        final Activity activity = getActivity();
534        if (activity instanceof WifiSettingsForSetupWizardXL) {
535            ((WifiSettingsForSetupWizardXL)activity).updateConnectionState(mLastState);
536        }
537    }
538
539    private void updateWifiState(int state) {
540        if (state == WifiManager.WIFI_STATE_ENABLED) {
541            mScanner.resume();
542        } else {
543            mScanner.pause();
544            mAccessPoints.removeAll();
545        }
546    }
547
548    private class Scanner extends Handler {
549        private int mRetry = 0;
550
551        void resume() {
552            synchronized (WifiSettings.this) {
553                mRefrainListUpdate = false;
554            }
555            if (!hasMessages(0)) {
556                sendEmptyMessage(0);
557            }
558        }
559
560        void pause() {
561            mRetry = 0;
562            mAccessPoints.setProgress(false);
563            synchronized (WifiSettings.this) {
564                mRefrainListUpdate = true;
565            }
566            removeMessages(0);
567        }
568
569        @Override
570        public void handleMessage(Message message) {
571            if (mWifiManager.startScanActive()) {
572                mRetry = 0;
573            } else if (++mRetry >= 3) {
574                mRetry = 0;
575                Toast.makeText(getActivity(), R.string.wifi_fail_to_scan,
576                        Toast.LENGTH_LONG).show();
577                return;
578            }
579            mAccessPoints.setProgress(mRetry != 0);
580            // Combo scans can take 5-6s to complete. Increase interval to 10s.
581            sendEmptyMessageDelayed(0, 10000);
582        }
583    }
584
585    private void changeNextButtonState(boolean wifiAvailable) {
586        if (mInXlSetupWizard) {
587            final Button button =
588                    (Button)getActivity().findViewById(R.id.wifi_setup_skip_or_next);
589            button.setEnabled(true);
590            if (wifiAvailable) {
591                button.setText(R.string.wifi_setup_next);
592            } else {
593                button.setText(R.string.wifi_setup_skip);
594            }
595        } else if (mEnableNextOnConnection && hasNextButton()) {
596            // Assumes layout for phones has next button inside it.
597            getNextButton().setEnabled(wifiAvailable);
598        }
599    }
600
601    public void onClick(DialogInterface dialogInterface, int button) {
602        if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) {
603            forget();
604        } else if (button == WifiDialog.BUTTON_SUBMIT) {
605            submit();
606        }
607    }
608
609    /* package */ void submit() {
610        final WifiConfigUiBase uiBase = (mDialog != null ? mDialog : mConfigPreference);
611        final WifiConfiguration config = uiBase.getController().getConfig();
612
613        if (config == null) {
614            if (mSelectedAccessPoint != null
615                    && !requireKeyStore(mSelectedAccessPoint.getConfig())) {
616                mWifiManager.connectNetwork(mSelectedAccessPoint.networkId);
617            }
618        } else if (config.networkId != -1) {
619            if (mSelectedAccessPoint != null) {
620                mWifiManager.saveNetwork(config);
621            }
622        } else {
623            if (uiBase.isEdit() || requireKeyStore(config)) {
624                mWifiManager.saveNetwork(config);
625            } else {
626                mWifiManager.connectNetwork(config);
627            }
628        }
629
630        detachConfigPreference();
631    }
632
633    /* package */ void forget() {
634        mWifiManager.forgetNetwork(mSelectedAccessPoint.networkId);
635
636        detachConfigPreference();
637
638        changeNextButtonState(false);
639
640        final Activity activity = getActivity();
641        if (activity instanceof WifiSettingsForSetupWizardXL) {
642            ((WifiSettingsForSetupWizardXL)activity).onForget();
643        }
644    }
645
646    /* package */ void refreshAccessPoints() {
647        if (mWifiManager.isWifiEnabled()) {
648            mScanner.resume();
649        }
650
651        mConfigPreference = null;
652        mAccessPoints.removeAll();
653
654        final Activity activity = getActivity();
655        if (activity instanceof WifiSettingsForSetupWizardXL) {
656            ((WifiSettingsForSetupWizardXL)activity).onRefreshAccessPoints();
657        }
658    }
659
660    /* package */ void detachConfigPreference() {
661        if (mConfigPreference != null) {
662            if (mWifiManager.isWifiEnabled()) {
663                mScanner.resume();
664            }
665            mAccessPoints.removePreference(mConfigPreference);
666            mConfigPreference = null;
667            updateAccessPoints();
668            toggleButtonsVisibility(true);
669        }
670    }
671
672    /* package */ void onAddNetworkPressed() {
673        mSelectedAccessPoint = null;
674        showConfigUi(null, true);
675    }
676}
677