Home | History | Annotate | Download | only in nfcprovisioning
      1 /*
      2  * Copyright (C) 2015 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.example.android.nfcprovisioning;
     18 
     19 import android.app.Activity;
     20 import android.app.admin.DevicePolicyManager;
     21 import android.content.Context;
     22 import android.net.wifi.WifiInfo;
     23 import android.net.wifi.WifiManager;
     24 import android.os.Environment;
     25 import android.support.v4.content.AsyncTaskLoader;
     26 
     27 import com.example.android.common.logger.Log;
     28 
     29 import java.io.BufferedReader;
     30 import java.io.File;
     31 import java.io.FileReader;
     32 import java.io.IOException;
     33 import java.util.HashMap;
     34 import java.util.Map;
     35 import java.util.TimeZone;
     36 
     37 /**
     38  * Loads default values for NFC provisioning.
     39  * <p/>
     40  * This loader first tries to load values from a config file in SD card. Then it fills in missing
     41  * values using constants and settings on the programming device.
     42  */
     43 public class ProvisioningValuesLoader extends AsyncTaskLoader<Map<String, String>> {
     44 
     45     private static final String FILENAME = "nfcprovisioning.txt";
     46     private static final String TAG = "LoadProvisioningValuesTask";
     47 
     48     private Map<String, String> mValues;
     49 
     50     public ProvisioningValuesLoader(Context context) {
     51         super(context);
     52     }
     53 
     54     @Override
     55     public Map<String, String> loadInBackground() {
     56         HashMap<String, String> values = new HashMap<>();
     57         loadFromDisk(values);
     58         loadSystemValues(values);
     59         return values;
     60     }
     61 
     62     @Override
     63     public void deliverResult(Map<String, String> values) {
     64         if (isReset()) {
     65             return;
     66         }
     67         mValues = values;
     68         super.deliverResult(values);
     69     }
     70 
     71     @Override
     72     protected void onStartLoading() {
     73         if (mValues != null) {
     74             deliverResult(mValues);
     75         }
     76         if (takeContentChanged() || mValues == null) {
     77             forceLoad();
     78         }
     79     }
     80 
     81     @Override
     82     protected void onStopLoading() {
     83         cancelLoad();
     84     }
     85 
     86     @Override
     87     protected void onReset() {
     88         super.onReset();
     89         onStopLoading();
     90         mValues = null;
     91     }
     92 
     93     private void loadFromDisk(HashMap<String, String> values) {
     94         File directory = Environment.getExternalStorageDirectory();
     95         File file = new File(directory, FILENAME);
     96         if (!file.exists()) {
     97             return;
     98         }
     99         Log.d(TAG, "Loading the config file...");
    100         try {
    101             loadFromFile(values, file);
    102         } catch (IOException e) {
    103             e.printStackTrace();
    104             Log.e(TAG, "Error loading data from " + file, e);
    105         }
    106     }
    107 
    108     private void loadFromFile(HashMap<String, String> values, File file) throws IOException {
    109         BufferedReader reader = null;
    110         try {
    111             reader = new BufferedReader(new FileReader(file));
    112             String line;
    113             while (null != (line = reader.readLine())) {
    114                 if (line.startsWith("#")) {
    115                     continue;
    116                 }
    117                 int position = line.indexOf("=");
    118                 if (position < 0) { // Not found
    119                     continue;
    120                 }
    121                 String key = line.substring(0, position);
    122                 String value = line.substring(position + 1);
    123                 values.put(key, value);
    124                 Log.d(TAG, key + "=" + value);
    125             }
    126         } finally {
    127             if (reader != null) {
    128                 reader.close();
    129             }
    130         }
    131     }
    132 
    133     private void loadSystemValues(HashMap<String, String> values) {
    134         Context context = getContext();
    135         putIfMissing(values, DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
    136                 "com.example.android.deviceowner");
    137         putIfMissing(values, DevicePolicyManager.EXTRA_PROVISIONING_LOCALE,
    138                 context.getResources().getConfiguration().locale.toString());
    139         putIfMissing(values, DevicePolicyManager.EXTRA_PROVISIONING_TIME_ZONE,
    140                 TimeZone.getDefault().getID());
    141         if (!values.containsKey(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID)) {
    142             WifiManager wifiManager = (WifiManager) context
    143                     .getSystemService(Activity.WIFI_SERVICE);
    144             WifiInfo info = wifiManager.getConnectionInfo();
    145             values.put(DevicePolicyManager.EXTRA_PROVISIONING_WIFI_SSID, trimSsid(info.getSSID()));
    146         }
    147     }
    148 
    149     /**
    150      * {@link WifiInfo#getSSID} returns the WiFi SSID surrounded by double quotation marks. This
    151      * method removes them if wifiSsid contains them.
    152      */
    153     private static String trimSsid(String wifiSsid) {
    154         int head = wifiSsid.startsWith("\"") ? 1 : 0;
    155         int tail = wifiSsid.endsWith("\"") ? 1 : 0;
    156         return wifiSsid.substring(head, wifiSsid.length() - tail);
    157     }
    158 
    159     private static <Key, Value> void putIfMissing(HashMap<Key, Value> map, Key key, Value value) {
    160         if (!map.containsKey(key)) {
    161             map.put(key, value);
    162         }
    163     }
    164 
    165 }
    166