| /* |
| * Copyright (C) 2015 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.example.android.nfcprovisioning; |
| |
| import android.app.Activity; |
| import android.app.admin.DevicePolicyManager; |
| import android.nfc.NdefMessage; |
| import android.nfc.NdefRecord; |
| import android.nfc.NfcAdapter; |
| import android.nfc.NfcEvent; |
| import android.os.Bundle; |
| import android.support.annotation.Nullable; |
| import android.support.v4.app.Fragment; |
| import android.support.v4.app.LoaderManager; |
| import android.support.v4.content.Loader; |
| import android.text.TextUtils; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.EditText; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.util.Map; |
| import java.util.Properties; |
| |
| /** |
| * Provides UI and logic for NFC provisioning. |
| * <p> |
| * This fragment creates an intent, which sends parameters to a second device via an Nfc bump. If |
| * the second device is factory reset, this will start provisioning the second device to set it up |
| * as an owned device. |
| * </p> |
| */ |
| public class NfcProvisioningFragment extends Fragment implements |
| NfcAdapter.CreateNdefMessageCallback, |
| TextWatcherWrapper.OnTextChangedListener, |
| LoaderManager.LoaderCallbacks<Map<String, String>> { |
| |
| private static final int LOADER_PROVISIONING_VALUES = 1; |
| |
| // View references |
| private EditText mEditPackageName; |
| private EditText mEditLocale; |
| private EditText mEditTimezone; |
| private EditText mEditWifiSsid; |
| private EditText mEditWifiSecurityType; |
| private EditText mEditWifiPassword; |
| |
| // Values to be set via NFC bump |
| private Map<String, String> mProvisioningValues; |
| |
| @Override |
| public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, |
| @Nullable Bundle savedInstanceState) { |
| return inflater.inflate(R.layout.fragment_nfc_provisioning, container, false); |
| } |
| |
| @Override |
| public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { |
| // Retrieve view references |
| mEditPackageName = (EditText) view.findViewById(R.id.package_name); |
| mEditLocale = (EditText) view.findViewById(R.id.locale); |
| mEditTimezone = (EditText) view.findViewById(R.id.timezone); |
| mEditWifiSsid = (EditText) view.findViewById(R.id.wifi_ssid); |
| mEditWifiSecurityType = (EditText) view.findViewById(R.id.wifi_security_type); |
| mEditWifiPassword = (EditText) view.findViewById(R.id.wifi_password); |
| // Bind event handlers |
| mEditPackageName.addTextChangedListener(new TextWatcherWrapper(R.id.package_name, this)); |
| mEditLocale.addTextChangedListener(new TextWatcherWrapper(R.id.locale, this)); |
| mEditTimezone.addTextChangedListener(new TextWatcherWrapper(R.id.timezone, this)); |
| mEditWifiSsid.addTextChangedListener(new TextWatcherWrapper(R.id.wifi_ssid, this)); |
| mEditWifiSecurityType.addTextChangedListener( |
| new TextWatcherWrapper(R.id.wifi_security_type, this)); |
| mEditWifiPassword.addTextChangedListener(new TextWatcherWrapper(R.id.wifi_password, this)); |
| } |
| |
| @Override |
| public void onStart() { |
| super.onStart(); |
| Activity activity = getActivity(); |
| NfcAdapter adapter = NfcAdapter.getDefaultAdapter(activity); |
| if (adapter != null) { |
| adapter.setNdefPushMessageCallback(this, activity); |
| } |
| getLoaderManager().initLoader(LOADER_PROVISIONING_VALUES, null, this); |
| } |
| |
| @Override |
| public NdefMessage createNdefMessage(NfcEvent event) { |
| if (mProvisioningValues == null) { |
| return null; |
| } |
| ByteArrayOutputStream stream = new ByteArrayOutputStream(); |
| Properties properties = new Properties(); |
| // Store all the values into the Properties object |
| for (Map.Entry<String, String> e : mProvisioningValues.entrySet()) { |
| if (!TextUtils.isEmpty(e.getValue())) { |
| String value; |
| if (e.getKey().equals(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID)) { |
| // Make sure to surround SSID with double quotes |
| value = e.getValue(); |
| if (!value.startsWith("\"") || !value.endsWith("\"")) { |
| value = "\"" + value + "\""; |
| } |
| } else { |
| value = e.getValue(); |
| } |
| properties.put(e.getKey(), value); |
| } |
| } |
| try { |
| properties.store(stream, getString(R.string.nfc_comment)); |
| NdefRecord record = NdefRecord.createMime( |
| DevicePolicyManager.MIME_TYPE_PROVISIONING_NFC, stream.toByteArray()); |
| return new NdefMessage(new NdefRecord[]{record}); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| return null; |
| } |
| |
| @Override |
| public void onTextChanged(int id, String s) { |
| if (mProvisioningValues == null) { |
| return; |
| } |
| switch (id) { |
| case R.id.package_name: |
| mProvisioningValues.put( |
| DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME, s); |
| break; |
| case R.id.locale: |
| mProvisioningValues.put(DevicePolicyManager.EXTRA_PROVISIONING_LOCALE, s); |
| break; |
| case R.id.timezone: |
| mProvisioningValues.put(DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE, s); |
| break; |
| case R.id.wifi_ssid: |
| mProvisioningValues.put(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID, s); |
| break; |
| case R.id.wifi_security_type: |
| mProvisioningValues.put( |
| DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE, s); |
| break; |
| case R.id.wifi_password: |
| mProvisioningValues.put(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_PASSWORD, s); |
| break; |
| } |
| } |
| |
| @Override |
| public Loader<Map<String, String>> onCreateLoader(int id, Bundle args) { |
| if (id == LOADER_PROVISIONING_VALUES) { |
| return new ProvisioningValuesLoader(getActivity()); |
| } |
| return null; |
| } |
| |
| @Override |
| public void onLoadFinished(Loader<Map<String, String>> loader, Map<String, String> values) { |
| if (loader.getId() == LOADER_PROVISIONING_VALUES) { |
| mProvisioningValues = values; |
| mEditPackageName.setText(values.get( |
| DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME)); |
| mEditLocale.setText(values.get(DevicePolicyManager.EXTRA_PROVISIONING_LOCALE)); |
| mEditTimezone.setText(values.get(DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE)); |
| mEditWifiSsid.setText(values.get(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID)); |
| mEditWifiSecurityType.setText(values.get( |
| DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SECURITY_TYPE)); |
| mEditWifiPassword.setText(null); |
| } |
| } |
| |
| @Override |
| public void onLoaderReset(Loader<Map<String, String>> loader) { |
| // Do nothing |
| } |
| |
| } |