Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2007 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 
     17 package com.android.settings.wifi;
     18 
     19 import com.android.settings.R;
     20 
     21 import android.content.ContentResolver;
     22 import android.net.wifi.WifiInfo;
     23 import android.net.wifi.WifiManager;
     24 import android.os.Bundle;
     25 import android.preference.CheckBoxPreference;
     26 import android.preference.EditTextPreference;
     27 import android.preference.ListPreference;
     28 import android.preference.Preference;
     29 import android.preference.PreferenceActivity;
     30 import android.provider.Settings;
     31 import android.provider.Settings.System;
     32 import android.text.TextUtils;
     33 import android.view.KeyEvent;
     34 import android.view.Menu;
     35 import android.view.MenuItem;
     36 import android.widget.Toast;
     37 import android.os.SystemProperties;
     38 
     39 public class AdvancedSettings extends PreferenceActivity
     40         implements Preference.OnPreferenceChangeListener {
     41 
     42     private static final String KEY_MAC_ADDRESS = "mac_address";
     43     private static final String KEY_USE_STATIC_IP = "use_static_ip";
     44     private static final String KEY_NUM_CHANNELS = "num_channels";
     45     private static final String KEY_SLEEP_POLICY = "sleep_policy";
     46 
     47     private String[] mSettingNames = {
     48             System.WIFI_STATIC_IP, System.WIFI_STATIC_GATEWAY, System.WIFI_STATIC_NETMASK,
     49             System.WIFI_STATIC_DNS1, System.WIFI_STATIC_DNS2
     50     };
     51 
     52     private String[] mPreferenceKeys = {
     53             "ip_address", "gateway", "netmask", "dns1", "dns2"
     54     };
     55 
     56     private CheckBoxPreference mUseStaticIpCheckBox;
     57 
     58     private static final int MENU_ITEM_SAVE = Menu.FIRST;
     59     private static final int MENU_ITEM_CANCEL = Menu.FIRST + 1;
     60 
     61     //Tracks ro.debuggable (1 on userdebug builds)
     62     private static int DEBUGGABLE;
     63 
     64     @Override
     65     protected void onCreate(Bundle savedInstanceState) {
     66         super.onCreate(savedInstanceState);
     67 
     68         addPreferencesFromResource(R.xml.wifi_advanced_settings);
     69 
     70         mUseStaticIpCheckBox = (CheckBoxPreference) findPreference(KEY_USE_STATIC_IP);
     71         mUseStaticIpCheckBox.setOnPreferenceChangeListener(this);
     72 
     73         for (int i = 0; i < mPreferenceKeys.length; i++) {
     74             Preference preference = findPreference(mPreferenceKeys[i]);
     75             preference.setOnPreferenceChangeListener(this);
     76         }
     77 
     78         DEBUGGABLE = SystemProperties.getInt("ro.debuggable", 0);
     79 
     80         /**
     81          * Remove user control of regulatory domain
     82          * channel count settings in non userdebug builds
     83          */
     84         if (DEBUGGABLE == 1) {
     85             /*
     86              * Fix the Run-time IllegalStateException that ListPreference requires an entries
     87              * array and an entryValues array, this exception occurs when user open/close the
     88              * slider in the Regulatory domain dialog.
     89              */
     90             initNumChannelsPreference();
     91         } else {
     92             Preference chanPref = findPreference(KEY_NUM_CHANNELS);
     93             if (chanPref != null) {
     94               getPreferenceScreen().removePreference(chanPref);
     95             }
     96         }
     97     }
     98 
     99     @Override
    100     protected void onResume() {
    101         super.onResume();
    102 
    103         updateUi();
    104         /**
    105          * Remove user control of regulatory domain
    106          * channel count settings in non userdebug builds
    107          */
    108         if (DEBUGGABLE == 1) {
    109             initNumChannelsPreference();
    110         }
    111         initSleepPolicyPreference();
    112         refreshMacAddress();
    113     }
    114 
    115     private void initNumChannelsPreference() {
    116         ListPreference pref = (ListPreference) findPreference(KEY_NUM_CHANNELS);
    117         pref.setOnPreferenceChangeListener(this);
    118 
    119         WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
    120         /*
    121          * Generate the list of valid channel counts to show in the ListPreference.
    122          * The values are numerical, so the only text to be localized is the
    123          * "channel_word" resource.
    124          */
    125         int[] validChannelCounts = wifiManager.getValidChannelCounts();
    126         if (validChannelCounts == null) {
    127             Toast.makeText(this, R.string.wifi_setting_num_channels_error,
    128                            Toast.LENGTH_SHORT).show();
    129             pref.setEnabled(false);
    130             return;
    131         }
    132         String[] entries = new String[validChannelCounts.length];
    133         String[] entryValues = new String[validChannelCounts.length];
    134 
    135         for (int i = 0; i < validChannelCounts.length; i++) {
    136             entryValues[i] = String.valueOf(validChannelCounts[i]);
    137             entries[i] = getString(R.string.wifi_setting_num_channels_channel_phrase,
    138                                    validChannelCounts[i]);
    139         }
    140         pref.setEntries(entries);
    141         pref.setEntryValues(entryValues);
    142         pref.setEnabled(true);
    143         int numChannels = wifiManager.getNumAllowedChannels();
    144         if (numChannels >= 0) {
    145             pref.setValue(String.valueOf(numChannels));
    146         }
    147     }
    148 
    149     private void initSleepPolicyPreference() {
    150         ListPreference pref = (ListPreference) findPreference(KEY_SLEEP_POLICY);
    151         pref.setOnPreferenceChangeListener(this);
    152         int value = Settings.System.getInt(getContentResolver(),
    153                 Settings.System.WIFI_SLEEP_POLICY,Settings. System.WIFI_SLEEP_POLICY_DEFAULT);
    154         pref.setValue(String.valueOf(value));
    155     }
    156 
    157     @Override
    158     public boolean onKeyDown(int keyCode, KeyEvent event) {
    159 
    160         if (keyCode == KeyEvent.KEYCODE_BACK) {
    161             updateSettingsProvider();
    162         }
    163 
    164         return super.onKeyDown(keyCode, event);
    165     }
    166 
    167     public boolean onPreferenceChange(Preference preference, Object newValue) {
    168         String key = preference.getKey();
    169         if (key == null) return true;
    170 
    171         if (key.equals(KEY_NUM_CHANNELS)) {
    172             try {
    173                 int numChannels = Integer.parseInt((String) newValue);
    174                 WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
    175                 if (!wifiManager.setNumAllowedChannels(numChannels, true)) {
    176                     Toast.makeText(this, R.string.wifi_setting_num_channels_error,
    177                             Toast.LENGTH_SHORT).show();
    178                 }
    179             } catch (NumberFormatException e) {
    180                 Toast.makeText(this, R.string.wifi_setting_num_channels_error,
    181                         Toast.LENGTH_SHORT).show();
    182                 return false;
    183             }
    184 
    185         } else if (key.equals(KEY_SLEEP_POLICY)) {
    186             try {
    187                 Settings.System.putInt(getContentResolver(),
    188                         Settings.System.WIFI_SLEEP_POLICY, Integer.parseInt(((String) newValue)));
    189             } catch (NumberFormatException e) {
    190                 Toast.makeText(this, R.string.wifi_setting_sleep_policy_error,
    191                         Toast.LENGTH_SHORT).show();
    192                 return false;
    193             }
    194 
    195         } else if (key.equals(KEY_USE_STATIC_IP)) {
    196             boolean value = ((Boolean) newValue).booleanValue();
    197 
    198             try {
    199                 Settings.System.putInt(getContentResolver(),
    200                         Settings.System.WIFI_USE_STATIC_IP, value ? 1 : 0);
    201             } catch (NumberFormatException e) {
    202                 return false;
    203             }
    204         } else {
    205             String value = (String) newValue;
    206 
    207             if (!isIpAddress(value)) {
    208                 Toast.makeText(this, R.string.wifi_ip_settings_invalid_ip, Toast.LENGTH_LONG).show();
    209                 return false;
    210             }
    211 
    212             preference.setSummary(value);
    213             for (int i = 0; i < mSettingNames.length; i++) {
    214                 if (key.equals(mPreferenceKeys[i])) {
    215                     Settings.System.putString(getContentResolver(), mSettingNames[i], value);
    216                     break;
    217                 }
    218             }
    219         }
    220 
    221         return true;
    222     }
    223 
    224     private boolean isIpAddress(String value) {
    225 
    226         int start = 0;
    227         int end = value.indexOf('.');
    228         int numBlocks = 0;
    229 
    230         while (start < value.length()) {
    231 
    232             if (end == -1) {
    233                 end = value.length();
    234             }
    235 
    236             try {
    237                 int block = Integer.parseInt(value.substring(start, end));
    238                 if ((block > 255) || (block < 0)) {
    239                     return false;
    240                 }
    241             } catch (NumberFormatException e) {
    242                 return false;
    243             }
    244 
    245             numBlocks++;
    246 
    247             start = end + 1;
    248             end = value.indexOf('.', start);
    249         }
    250 
    251         return numBlocks == 4;
    252     }
    253 
    254     @Override
    255     public boolean onCreateOptionsMenu(Menu menu) {
    256 
    257         menu.add(0, MENU_ITEM_SAVE, 0, R.string.wifi_ip_settings_menu_save)
    258                 .setIcon(android.R.drawable.ic_menu_save);
    259 
    260         menu.add(0, MENU_ITEM_CANCEL, 0, R.string.wifi_ip_settings_menu_cancel)
    261                 .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
    262 
    263         return super.onCreateOptionsMenu(menu);
    264     }
    265 
    266     @Override
    267     public boolean onOptionsItemSelected(MenuItem item) {
    268 
    269         switch (item.getItemId()) {
    270 
    271             case MENU_ITEM_SAVE:
    272                 updateSettingsProvider();
    273                 finish();
    274                 return true;
    275 
    276             case MENU_ITEM_CANCEL:
    277                 finish();
    278                 return true;
    279         }
    280 
    281         return super.onOptionsItemSelected(item);
    282     }
    283 
    284     private void updateUi() {
    285         ContentResolver contentResolver = getContentResolver();
    286 
    287         mUseStaticIpCheckBox.setChecked(System.getInt(contentResolver,
    288                 System.WIFI_USE_STATIC_IP, 0) != 0);
    289 
    290         for (int i = 0; i < mSettingNames.length; i++) {
    291             EditTextPreference preference = (EditTextPreference) findPreference(mPreferenceKeys[i]);
    292             String settingValue = System.getString(contentResolver, mSettingNames[i]);
    293             preference.setText(settingValue);
    294             preference.setSummary(settingValue);
    295         }
    296     }
    297 
    298     private void updateSettingsProvider() {
    299         ContentResolver contentResolver = getContentResolver();
    300 
    301         System.putInt(contentResolver, System.WIFI_USE_STATIC_IP,
    302                 mUseStaticIpCheckBox.isChecked() ? 1 : 0);
    303 
    304         for (int i = 0; i < mSettingNames.length; i++) {
    305             EditTextPreference preference = (EditTextPreference) findPreference(mPreferenceKeys[i]);
    306             System.putString(contentResolver, mSettingNames[i], preference.getText());
    307         }
    308     }
    309 
    310     private void refreshMacAddress() {
    311         WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
    312         WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    313 
    314         Preference wifiMacAddressPref = findPreference(KEY_MAC_ADDRESS);
    315         String macAddress = wifiInfo == null ? null : wifiInfo.getMacAddress();
    316         wifiMacAddressPref.setSummary(!TextUtils.isEmpty(macAddress) ? macAddress
    317                 : getString(R.string.status_unavailable));
    318     }
    319 
    320 }
    321