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 17 package com.android.settings.wifi; 18 19 import android.app.AlertDialog; 20 import android.content.Context; 21 import android.content.DialogInterface; 22 import android.net.wifi.WifiConfiguration; 23 import android.net.wifi.WifiConfiguration.AuthAlgorithm; 24 import android.net.wifi.WifiConfiguration.KeyMgmt; 25 import android.net.wifi.WifiManager; 26 import android.os.Bundle; 27 import android.text.Editable; 28 import android.text.InputType; 29 import android.text.TextWatcher; 30 import android.util.Log; 31 import android.view.View; 32 import android.widget.AdapterView; 33 import android.widget.ArrayAdapter; 34 import android.widget.CheckBox; 35 import android.widget.EditText; 36 import android.widget.Spinner; 37 import android.widget.TextView; 38 39 import com.android.settings.R; 40 41 import java.nio.charset.Charset; 42 43 /** 44 * Dialog to configure the SSID and security settings 45 * for Access Point operation 46 */ 47 public class WifiApDialog extends AlertDialog implements View.OnClickListener, 48 TextWatcher, AdapterView.OnItemSelectedListener { 49 50 static final int BUTTON_SUBMIT = DialogInterface.BUTTON_POSITIVE; 51 52 private final DialogInterface.OnClickListener mListener; 53 54 public static final int OPEN_INDEX = 0; 55 public static final int WPA2_INDEX = 1; 56 57 private View mView; 58 private TextView mSsid; 59 private int mSecurityTypeIndex = OPEN_INDEX; 60 private EditText mPassword; 61 private int mBandIndex = OPEN_INDEX; 62 63 WifiConfiguration mWifiConfig; 64 WifiManager mWifiManager; 65 private Context mContext; 66 67 private static final String TAG = "WifiApDialog"; 68 WifiApDialog(Context context, DialogInterface.OnClickListener listener, WifiConfiguration wifiConfig)69 public WifiApDialog(Context context, DialogInterface.OnClickListener listener, 70 WifiConfiguration wifiConfig) { 71 super(context); 72 mListener = listener; 73 mWifiConfig = wifiConfig; 74 if (wifiConfig != null) { 75 mSecurityTypeIndex = getSecurityTypeIndex(wifiConfig); 76 } 77 mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 78 mContext = context; 79 } 80 getSecurityTypeIndex(WifiConfiguration wifiConfig)81 public static int getSecurityTypeIndex(WifiConfiguration wifiConfig) { 82 if (wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) { 83 return WPA2_INDEX; 84 } 85 return OPEN_INDEX; 86 } 87 getConfig()88 public WifiConfiguration getConfig() { 89 90 WifiConfiguration config = new WifiConfiguration(); 91 92 /** 93 * TODO: SSID in WifiConfiguration for soft ap 94 * is being stored as a raw string without quotes. 95 * This is not the case on the client side. We need to 96 * make things consistent and clean it up 97 */ 98 config.SSID = mSsid.getText().toString(); 99 100 config.apBand = mBandIndex; 101 102 switch (mSecurityTypeIndex) { 103 case OPEN_INDEX: 104 config.allowedKeyManagement.set(KeyMgmt.NONE); 105 return config; 106 107 case WPA2_INDEX: 108 config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK); 109 config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN); 110 if (mPassword.length() != 0) { 111 String password = mPassword.getText().toString(); 112 config.preSharedKey = password; 113 } 114 return config; 115 } 116 return null; 117 } 118 119 @Override onCreate(Bundle savedInstanceState)120 protected void onCreate(Bundle savedInstanceState) { 121 boolean mInit = true; 122 mView = getLayoutInflater().inflate(R.layout.wifi_ap_dialog, null); 123 Spinner mSecurity = ((Spinner) mView.findViewById(R.id.security)); 124 final Spinner mChannel = (Spinner) mView.findViewById(R.id.choose_channel); 125 126 setView(mView); 127 setInverseBackgroundForced(true); 128 129 Context context = getContext(); 130 131 setTitle(R.string.wifi_tether_configure_ap_text); 132 mView.findViewById(R.id.type).setVisibility(View.VISIBLE); 133 mSsid = (TextView) mView.findViewById(R.id.ssid); 134 mPassword = (EditText) mView.findViewById(R.id.password); 135 136 ArrayAdapter <CharSequence> channelAdapter; 137 String countryCode = mWifiManager.getCountryCode(); 138 if (!mWifiManager.isDualBandSupported() || countryCode == null) { 139 //If no country code, 5GHz AP is forbidden 140 Log.i(TAG,(!mWifiManager.isDualBandSupported() ? "Device do not support 5GHz " :"") 141 + (countryCode == null ? " NO country code" :"") + " forbid 5GHz"); 142 channelAdapter = ArrayAdapter.createFromResource(mContext, 143 R.array.wifi_ap_band_config_2G_only, android.R.layout.simple_spinner_item); 144 mWifiConfig.apBand = 0; 145 } else { 146 channelAdapter = ArrayAdapter.createFromResource(mContext, 147 R.array.wifi_ap_band_config_full, android.R.layout.simple_spinner_item); 148 } 149 150 channelAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 151 152 setButton(BUTTON_SUBMIT, context.getString(R.string.wifi_save), mListener); 153 setButton(DialogInterface.BUTTON_NEGATIVE, 154 context.getString(R.string.wifi_cancel), mListener); 155 156 if (mWifiConfig != null) { 157 mSsid.setText(mWifiConfig.SSID); 158 if (mWifiConfig.apBand == 0) { 159 mBandIndex = 0; 160 } else { 161 mBandIndex = 1; 162 } 163 164 mSecurity.setSelection(mSecurityTypeIndex); 165 if (mSecurityTypeIndex == WPA2_INDEX) { 166 mPassword.setText(mWifiConfig.preSharedKey); 167 } 168 } 169 170 mChannel.setAdapter(channelAdapter); 171 mChannel.setOnItemSelectedListener( 172 new AdapterView.OnItemSelectedListener() { 173 boolean mInit = true; 174 @Override 175 public void onItemSelected(AdapterView<?> adapterView, View view, int position, 176 long id) { 177 if (!mInit) { 178 mBandIndex = position; 179 mWifiConfig.apBand = mBandIndex; 180 Log.i(TAG, "config on channelIndex : " + mBandIndex + " Band: " + 181 mWifiConfig.apBand); 182 } else { 183 mInit = false; 184 mChannel.setSelection(mBandIndex); 185 } 186 187 } 188 189 @Override 190 public void onNothingSelected(AdapterView<?> adapterView) { 191 192 } 193 } 194 ); 195 196 mSsid.addTextChangedListener(this); 197 mPassword.addTextChangedListener(this); 198 ((CheckBox) mView.findViewById(R.id.show_password)).setOnClickListener(this); 199 mSecurity.setOnItemSelectedListener(this); 200 201 super.onCreate(savedInstanceState); 202 203 showSecurityFields(); 204 validate(); 205 } 206 onRestoreInstanceState(Bundle savedInstanceState)207 public void onRestoreInstanceState(Bundle savedInstanceState) { 208 super.onRestoreInstanceState(savedInstanceState); 209 mPassword.setInputType( 210 InputType.TYPE_CLASS_TEXT | 211 (((CheckBox) mView.findViewById(R.id.show_password)).isChecked() ? 212 InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD : 213 InputType.TYPE_TEXT_VARIATION_PASSWORD)); 214 } 215 validate()216 private void validate() { 217 String mSsidString = mSsid.getText().toString(); 218 if ((mSsid != null && mSsid.length() == 0) 219 || ((mSecurityTypeIndex == WPA2_INDEX) && mPassword.length() < 8) 220 || (mSsid != null && 221 Charset.forName("UTF-8").encode(mSsidString).limit() > 32)) { 222 getButton(BUTTON_SUBMIT).setEnabled(false); 223 } else { 224 getButton(BUTTON_SUBMIT).setEnabled(true); 225 } 226 } 227 onClick(View view)228 public void onClick(View view) { 229 mPassword.setInputType( 230 InputType.TYPE_CLASS_TEXT | (((CheckBox) view).isChecked() ? 231 InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD : 232 InputType.TYPE_TEXT_VARIATION_PASSWORD)); 233 } 234 onTextChanged(CharSequence s, int start, int before, int count)235 public void onTextChanged(CharSequence s, int start, int before, int count) { 236 } 237 beforeTextChanged(CharSequence s, int start, int count, int after)238 public void beforeTextChanged(CharSequence s, int start, int count, int after) { 239 } 240 afterTextChanged(Editable editable)241 public void afterTextChanged(Editable editable) { 242 validate(); 243 } 244 245 @Override onItemSelected(AdapterView<?> parent, View view, int position, long id)246 public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { 247 mSecurityTypeIndex = position; 248 showSecurityFields(); 249 validate(); 250 } 251 252 @Override onNothingSelected(AdapterView<?> parent)253 public void onNothingSelected(AdapterView<?> parent) { 254 } 255 showSecurityFields()256 private void showSecurityFields() { 257 if (mSecurityTypeIndex == OPEN_INDEX) { 258 mView.findViewById(R.id.fields).setVisibility(View.GONE); 259 return; 260 } 261 mView.findViewById(R.id.fields).setVisibility(View.VISIBLE); 262 } 263 } 264