diff options
Diffstat (limited to 'src/com/android/settings/wifi/WifiSettings.java')
-rw-r--r-- | src/com/android/settings/wifi/WifiSettings.java | 438 |
1 files changed, 438 insertions, 0 deletions
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java new file mode 100644 index 0000000..ceb995b --- /dev/null +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -0,0 +1,438 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi; + +import com.android.settings.ProgressCategory; +import com.android.settings.R; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.wifi.WifiManager; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.PreferenceActivity; +import android.preference.PreferenceScreen; +import android.preference.CheckBoxPreference; +import android.provider.Settings; +import android.util.Log; +import android.view.ContextMenu; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ContextMenu.ContextMenuInfo; +import android.widget.AdapterView; +import android.widget.Toast; +import android.widget.AdapterView.AdapterContextMenuInfo; + +import java.util.Set; +import java.util.WeakHashMap; + +/** + * Settings screen for WiFi. This will be launched from the main system settings. + */ +public class WifiSettings extends PreferenceActivity implements WifiLayer.Callback, + DialogInterface.OnDismissListener { + + private static final String TAG = "WifiSettings"; + + //============================ + // Preference/activity member variables + //============================ + + private static final String INSTANCE_KEY_DIALOG_BUNDLE = + "com.android.settings.wifi.WifiSettings:dialogBundle"; + /* + * We don't use Activity's dialog management because AlertDialog isn't fully + * able to change many of its features after it's been created, and the + * dialog management only creates once. + */ + private Dialog mDialog; + + private static final String KEY_ADD_OTHER_NETWORK = "add_other_network"; + + private static final int CONTEXT_MENU_ID_CONNECT = Menu.FIRST; + private static final int CONTEXT_MENU_ID_FORGET = Menu.FIRST + 1; + private static final int CONTEXT_MENU_ID_CHANGE_PASSWORD = Menu.FIRST + 2; + + private static final int MENU_ID_SCAN = Menu.FIRST; + private static final int MENU_ID_ADVANCED = Menu.FIRST + 1; + + private static final String KEY_WIFI_ENABLED = "wifi_enabled"; + private static final String KEY_OPEN_NETWORK_NOTIFICATIONS_ENABLED = + "open_network_notifications_enabled"; + private static final String KEY_ACCESS_POINTS = "access_points"; + + private ProgressCategory mApCategory; + private CheckBoxPreference mWifiEnabled; + private WifiEnabler mWifiEnabler; + private CheckBoxPreference mOpenNetworkNotificationsEnabled; + private Preference mAddOtherNetwork; + + private WeakHashMap<AccessPointState, AccessPointPreference> mAps; + + //============================ + // Wifi member variables + //============================ + + private WifiLayer mWifiLayer; + + //============================ + // Activity lifecycle + //============================ + + public WifiSettings() { + mAps = new WeakHashMap<AccessPointState, AccessPointPreference>(); + mWifiLayer = new WifiLayer(this, this); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + onCreatePreferences(); + mWifiLayer.onCreate(); + + onCreatedWifi(); + mWifiLayer.onCreatedCallback(); + } + + /** + * Shouldn't have any dependency on the wifi layer. + */ + private void onCreatePreferences() { + addPreferencesFromResource(R.xml.wifi_settings); + + final PreferenceScreen preferenceScreen = getPreferenceScreen(); + + mApCategory = (ProgressCategory) preferenceScreen.findPreference(KEY_ACCESS_POINTS); + // We don't want the ordering to be the order preferences are added, + // instead we want*: + // 1) preferred, visible APs + // 2) visible APs + // 3) preferred, APs out of range + // * this ordering logic is in AccessPointPreference's compareTo + mApCategory.setOrderingAsAdded(false); + + mWifiEnabled = (CheckBoxPreference) preferenceScreen.findPreference(KEY_WIFI_ENABLED); + mWifiEnabler = new WifiEnabler(this, (WifiManager) getSystemService(WIFI_SERVICE), + mWifiEnabled); + + mOpenNetworkNotificationsEnabled = (CheckBoxPreference) preferenceScreen + .findPreference(KEY_OPEN_NETWORK_NOTIFICATIONS_ENABLED); + mOpenNetworkNotificationsEnabled.setChecked(Settings.System.getInt(getContentResolver(), + Settings.System.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1); + + mAddOtherNetwork = preferenceScreen.findPreference(KEY_ADD_OTHER_NETWORK); + + registerForContextMenu(getListView()); + } + + private void onCreatedWifi() { + } + + @Override + protected void onResume() { + super.onResume(); + mWifiLayer.onResume(); + mWifiEnabler.resume(); + } + + @Override + protected void onPause() { + super.onPause(); + mWifiLayer.onPause(); + mWifiEnabler.pause(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + if (mDialog != null) { + mDialog.dismiss(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + + menu.add(0, MENU_ID_SCAN, 0, R.string.scan_wifi) + .setIcon(R.drawable.ic_menu_scan_network); + + menu.add(0, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced) + .setIcon(R.drawable.ic_menu_manage); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + super.onOptionsItemSelected(item); + + switch (item.getItemId()) { + + case MENU_ID_SCAN: + mWifiLayer.attemptScan(); + return true; + + case MENU_ID_ADVANCED: + Intent intent = new Intent(this, IpSettings.class); + startActivity(intent); + return true; + + default: + return false; + } + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + + if (mDialog != null) { + Bundle dialogBundle = mDialog.onSaveInstanceState(); + outState.putBundle(INSTANCE_KEY_DIALOG_BUNDLE, dialogBundle); + } + } + + @Override + protected void onRestoreInstanceState(Bundle state) { + super.onRestoreInstanceState(state); + + Bundle dialogBundle = state.getBundle(INSTANCE_KEY_DIALOG_BUNDLE); + if (dialogBundle != null) { + mDialog = new AccessPointDialog(this, mWifiLayer); + mDialog.onRestoreInstanceState(dialogBundle); + showDialog(mDialog); + } + } + + /** + * {@inheritDoc} + */ + public void onDismiss(DialogInterface dialog) { + if (dialog == mDialog) { + mDialog = null; + } + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + + AccessPointState state = getStateFromMenuInfo(menuInfo); + if (state == null) { + return; + } + + menu.setHeaderTitle(state.getHumanReadableSsid()); + + if (state.isConnectable()) { + menu.add(0, CONTEXT_MENU_ID_CONNECT, 0, R.string.wifi_context_menu_connect); + } + + if (state.isForgetable()) { + menu.add(0, CONTEXT_MENU_ID_FORGET, 1, R.string.wifi_context_menu_forget); + + if (state.hasPassword()) { + menu.add(0, CONTEXT_MENU_ID_CHANGE_PASSWORD, 2, + R.string.wifi_context_menu_change_password); + } + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + + AccessPointState state = getStateFromMenuInfo(item.getMenuInfo()); + if (state == null) { + return false; + } + + switch (item.getItemId()) { + + case CONTEXT_MENU_ID_CONNECT: + connectToNetwork(state); + return true; + + case CONTEXT_MENU_ID_FORGET: + mWifiLayer.forgetNetwork(state); + return true; + + case CONTEXT_MENU_ID_CHANGE_PASSWORD: + showAccessPointDialog(state, AccessPointDialog.MODE_CONFIGURE); + return true; + + default: + return false; + } + } + + /** + * Decides what needs to happen to connect to a particular access point. If + * it is secured and doesn't already have a password, it will bring up a + * password box. Otherwise it will just connect. + */ + private void connectToNetwork(AccessPointState state) { + if (state.hasSecurity() && !state.hasPassword()) { + showAccessPointDialog(state, AccessPointDialog.MODE_INFO); + } else { + mWifiLayer.connectToNetwork(state); + } + } + + private AccessPointState getStateFromMenuInfo(ContextMenuInfo menuInfo) { + if ((menuInfo == null) || !(menuInfo instanceof AdapterContextMenuInfo)) { + return null; + } + + AdapterContextMenuInfo adapterMenuInfo = (AdapterContextMenuInfo) menuInfo; + Preference pref = (Preference) getPreferenceScreen().getRootAdapter().getItem( + adapterMenuInfo.position); + if (pref == null || !(pref instanceof AccessPointPreference)) { + return null; + } + + return ((AccessPointPreference) pref).getAccessPointState(); + } + + //============================ + // Preference callbacks + //============================ + + @Override + public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { + super.onPreferenceTreeClick(preferenceScreen, preference); + + if (preference == mAddOtherNetwork) { + showAddOtherNetworkDialog(); + } else if (preference == mOpenNetworkNotificationsEnabled) { + Settings.System.putInt(getContentResolver(), + Settings.System.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, + mOpenNetworkNotificationsEnabled.isChecked() ? 1 : 0); + } else if (preference instanceof AccessPointPreference) { + AccessPointState state = ((AccessPointPreference) preference).getAccessPointState(); + showAccessPointDialog(state, AccessPointDialog.MODE_INFO); + } + + return false; + } + + //============================ + // Wifi-related + //============================ + + public WifiLayer getWifiLayer() { + return mWifiLayer; + } + + private void showAddOtherNetworkDialog() { + AccessPointDialog dialog = new AccessPointDialog(this, mWifiLayer); + dialog.setState(new AccessPointState(this)); + dialog.setMode(AccessPointDialog.MODE_CONFIGURE); + dialog.setTitle(R.string.wifi_add_other_network); + dialog.setAutoSecurityAllowed(false); + showDialog(dialog); + } + + public void showAccessPointDialog(AccessPointState state, int mode) { + AccessPointDialog dialog = new AccessPointDialog(this, mWifiLayer); + dialog.setMode(mode); + dialog.setState(state); + showDialog(dialog); + } + + private void showDialog(Dialog dialog) { + // Have only one dialog open at a time + if (mDialog != null) { + mDialog.dismiss(); + } + + mDialog = dialog; + dialog.setOnDismissListener(this); + if (dialog != null) { + dialog.show(); + } + } + + //============================ + // Wifi callbacks + //============================ + + public void onError(int messageResId) { + Toast.makeText(this, messageResId, Toast.LENGTH_LONG).show(); + } + + public void onScanningStatusChanged(boolean started) { + mApCategory.setProgress(started); + } + + public void onAccessPointSetChanged(AccessPointState ap, boolean added) { + + AccessPointPreference pref = mAps.get(ap); + + if (WifiLayer.LOGV) { + Log.v(TAG, "onAccessPointSetChanged with " + ap + " and " + + (added ? "added" : "removed") + ", found pref " + pref); + } + + if (added) { + + if (pref == null) { + pref = new AccessPointPreference(this, ap); + mAps.put(ap, pref); + } else { + pref.setEnabled(true); + } + + mApCategory.addPreference(pref); + + } else { + + mAps.remove(ap); + + if (pref != null) { + mApCategory.removePreference(pref); + } + + } + } + + public void onAccessPointsStateChanged(boolean enabled) { + if (enabled) { + mApCategory.setEnabled(true); + } else { + mApCategory.removeAll(); + mAps.clear(); + } + + mAddOtherNetwork.setEnabled(enabled); + } + + public void onRetryPassword(AccessPointState ap) { + + if ((mDialog != null) && mDialog.isShowing()) { + // If we're already showing a dialog, ignore this request + return; + } + + showAccessPointDialog(ap, AccessPointDialog.MODE_RETRY_PASSWORD); + } + +} |