PageRenderTime 102ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/android/settings/wifi/WriteWifiConfigToNfcDialog.java

https://gitlab.com/freedmpure/platform_packages_apps_settings
Java | 283 lines | 225 code | 43 blank | 15 comment | 18 complexity | dd27db54da91cc3138add45b3d456b38 MD5 | raw file
  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. package com.android.settings.wifi;
  17. import android.app.Activity;
  18. import android.app.AlertDialog;
  19. import android.content.Context;
  20. import android.content.DialogInterface;
  21. import android.net.wifi.WifiManager;
  22. import android.nfc.FormatException;
  23. import android.nfc.NdefMessage;
  24. import android.nfc.NdefRecord;
  25. import android.nfc.NfcAdapter;
  26. import android.nfc.Tag;
  27. import android.nfc.tech.Ndef;
  28. import android.os.Bundle;
  29. import android.os.Handler;
  30. import android.os.PowerManager;
  31. import android.text.Editable;
  32. import android.text.InputType;
  33. import android.text.TextWatcher;
  34. import android.util.Log;
  35. import android.view.Gravity;
  36. import android.view.View;
  37. import android.view.inputmethod.InputMethodManager;
  38. import android.widget.Button;
  39. import android.widget.CheckBox;
  40. import android.widget.CompoundButton;
  41. import android.widget.LinearLayout;
  42. import android.widget.ProgressBar;
  43. import android.widget.TextView;
  44. import com.android.settings.R;
  45. import java.io.IOException;
  46. class WriteWifiConfigToNfcDialog extends AlertDialog
  47. implements TextWatcher, View.OnClickListener, CompoundButton.OnCheckedChangeListener {
  48. private static final String NFC_TOKEN_MIME_TYPE = "application/vnd.wfa.wsc";
  49. private static final String TAG = WriteWifiConfigToNfcDialog.class.getName().toString();
  50. private static final String PASSWORD_FORMAT = "102700%s%s";
  51. private static final int HEX_RADIX = 16;
  52. private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
  53. private final PowerManager.WakeLock mWakeLock;
  54. private AccessPoint mAccessPoint;
  55. private View mView;
  56. private Button mSubmitButton;
  57. private Button mCancelButton;
  58. private Handler mOnTextChangedHandler;
  59. private TextView mPasswordView;
  60. private TextView mLabelView;
  61. private CheckBox mPasswordCheckBox;
  62. private ProgressBar mProgressBar;
  63. private WifiManager mWifiManager;
  64. private String mWpsNfcConfigurationToken;
  65. private Context mContext;
  66. WriteWifiConfigToNfcDialog(Context context, AccessPoint accessPoint,
  67. WifiManager wifiManager) {
  68. super(context);
  69. mContext = context;
  70. mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE))
  71. .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WriteWifiConfigToNfcDialog:wakeLock");
  72. mAccessPoint = accessPoint;
  73. mOnTextChangedHandler = new Handler();
  74. mWifiManager = wifiManager;
  75. }
  76. @Override
  77. public void onCreate(Bundle savedInstanceState) {
  78. mView = getLayoutInflater().inflate(R.layout.write_wifi_config_to_nfc, null);
  79. setView(mView);
  80. setInverseBackgroundForced(true);
  81. setTitle(R.string.setup_wifi_nfc_tag);
  82. setCancelable(true);
  83. setButton(DialogInterface.BUTTON_NEUTRAL,
  84. mContext.getResources().getString(R.string.write_tag), (OnClickListener) null);
  85. setButton(DialogInterface.BUTTON_NEGATIVE,
  86. mContext.getResources().getString(com.android.internal.R.string.cancel),
  87. (OnClickListener) null);
  88. mPasswordView = (TextView) mView.findViewById(R.id.password);
  89. mLabelView = (TextView) mView.findViewById(R.id.password_label);
  90. mPasswordView.addTextChangedListener(this);
  91. mPasswordCheckBox = (CheckBox) mView.findViewById(R.id.show_password);
  92. mPasswordCheckBox.setOnCheckedChangeListener(this);
  93. mProgressBar = (ProgressBar) mView.findViewById(R.id.progress_bar);
  94. super.onCreate(savedInstanceState);
  95. mSubmitButton = getButton(DialogInterface.BUTTON_NEUTRAL);
  96. mSubmitButton.setOnClickListener(this);
  97. mSubmitButton.setEnabled(false);
  98. mCancelButton = getButton(DialogInterface.BUTTON_NEGATIVE);
  99. }
  100. @Override
  101. public void onClick(View v) {
  102. mWakeLock.acquire();
  103. String password = mPasswordView.getText().toString();
  104. String wpsNfcConfigurationToken
  105. = mWifiManager.getWpsNfcConfigurationToken(mAccessPoint.networkId);
  106. String passwordHex = byteArrayToHexString(password.getBytes());
  107. String passwordLength = password.length() >= HEX_RADIX
  108. ? Integer.toString(password.length(), HEX_RADIX)
  109. : "0" + Character.forDigit(password.length(), HEX_RADIX);
  110. passwordHex = String.format(PASSWORD_FORMAT, passwordLength, passwordHex).toUpperCase();
  111. if (wpsNfcConfigurationToken.contains(passwordHex)) {
  112. mWpsNfcConfigurationToken = wpsNfcConfigurationToken;
  113. Activity activity = getOwnerActivity();
  114. NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(activity);
  115. nfcAdapter.enableReaderMode(activity, new NfcAdapter.ReaderCallback() {
  116. @Override
  117. public void onTagDiscovered(Tag tag) {
  118. handleWriteNfcEvent(tag);
  119. }
  120. }, NfcAdapter.FLAG_READER_NFC_A |
  121. NfcAdapter.FLAG_READER_NFC_B |
  122. NfcAdapter.FLAG_READER_NFC_BARCODE |
  123. NfcAdapter.FLAG_READER_NFC_F |
  124. NfcAdapter.FLAG_READER_NFC_V,
  125. null);
  126. mPasswordView.setVisibility(View.GONE);
  127. mPasswordCheckBox.setVisibility(View.GONE);
  128. mSubmitButton.setVisibility(View.GONE);
  129. InputMethodManager imm = (InputMethodManager)
  130. getOwnerActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
  131. imm.hideSoftInputFromWindow(mPasswordView.getWindowToken(), 0);
  132. mLabelView.setText(R.string.status_awaiting_tap);
  133. mView.findViewById(R.id.password_layout).setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
  134. mProgressBar.setVisibility(View.VISIBLE);
  135. } else {
  136. mLabelView.setText(R.string.status_invalid_password);
  137. }
  138. }
  139. private void handleWriteNfcEvent(Tag tag) {
  140. Ndef ndef = Ndef.get(tag);
  141. if (ndef != null) {
  142. if (ndef.isWritable()) {
  143. NdefRecord record = NdefRecord.createMime(
  144. NFC_TOKEN_MIME_TYPE,
  145. hexStringToByteArray(mWpsNfcConfigurationToken));
  146. try {
  147. ndef.connect();
  148. ndef.writeNdefMessage(new NdefMessage(record));
  149. getOwnerActivity().runOnUiThread(new Runnable() {
  150. @Override
  151. public void run() {
  152. mProgressBar.setVisibility(View.GONE);
  153. }
  154. });
  155. setViewText(mLabelView, R.string.status_write_success);
  156. setViewText(mCancelButton, com.android.internal.R.string.done_label);
  157. } catch (IOException e) {
  158. setViewText(mLabelView, R.string.status_failed_to_write);
  159. Log.e(TAG, "Unable to write Wi-Fi config to NFC tag.", e);
  160. return;
  161. } catch (FormatException e) {
  162. setViewText(mLabelView, R.string.status_failed_to_write);
  163. Log.e(TAG, "Unable to write Wi-Fi config to NFC tag.", e);
  164. return;
  165. }
  166. } else {
  167. setViewText(mLabelView, R.string.status_tag_not_writable);
  168. Log.e(TAG, "Tag is not writable");
  169. }
  170. } else {
  171. setViewText(mLabelView, R.string.status_tag_not_writable);
  172. Log.e(TAG, "Tag does not support NDEF");
  173. }
  174. }
  175. @Override
  176. public void dismiss() {
  177. if (mWakeLock.isHeld()) {
  178. mWakeLock.release();
  179. }
  180. super.dismiss();
  181. }
  182. @Override
  183. public void onTextChanged(CharSequence s, int start, int before, int count) {
  184. mOnTextChangedHandler.post(new Runnable() {
  185. @Override
  186. public void run() {
  187. enableSubmitIfAppropriate();
  188. }
  189. });
  190. }
  191. private void enableSubmitIfAppropriate() {
  192. if (mPasswordView != null) {
  193. if (mAccessPoint.security == AccessPoint.SECURITY_WEP) {
  194. mSubmitButton.setEnabled(mPasswordView.length() > 0);
  195. } else if (mAccessPoint.security == AccessPoint.SECURITY_PSK) {
  196. mSubmitButton.setEnabled(mPasswordView.length() >= 8);
  197. }
  198. } else {
  199. mSubmitButton.setEnabled(false);
  200. }
  201. }
  202. private void setViewText(final TextView view, final int resid) {
  203. getOwnerActivity().runOnUiThread(new Runnable() {
  204. @Override
  205. public void run() {
  206. view.setText(resid);
  207. }
  208. });
  209. }
  210. @Override
  211. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  212. mPasswordView.setInputType(
  213. InputType.TYPE_CLASS_TEXT |
  214. (isChecked
  215. ? InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
  216. : InputType.TYPE_TEXT_VARIATION_PASSWORD));
  217. }
  218. private static byte[] hexStringToByteArray(String s) {
  219. int len = s.length();
  220. byte[] data = new byte[len / 2];
  221. for (int i = 0; i < len; i += 2) {
  222. data[i / 2] = (byte) ((Character.digit(s.charAt(i), HEX_RADIX) << 4)
  223. + Character.digit(s.charAt(i + 1), HEX_RADIX));
  224. }
  225. return data;
  226. }
  227. private static String byteArrayToHexString(byte[] bytes) {
  228. char[] hexChars = new char[bytes.length * 2];
  229. for ( int j = 0; j < bytes.length; j++ ) {
  230. int v = bytes[j] & 0xFF;
  231. hexChars[j * 2] = hexArray[v >>> 4];
  232. hexChars[j * 2 + 1] = hexArray[v & 0x0F];
  233. }
  234. return new String(hexChars);
  235. }
  236. @Override
  237. public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
  238. @Override
  239. public void afterTextChanged(Editable s) {}
  240. }