Home | History | Annotate | Download | only in nfc
      1 /*
      2  * Copyright (C) 2013 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.nfc;
     18 
     19 import android.content.ComponentName;
     20 import android.content.Context;
     21 import android.content.pm.PackageManager;
     22 import android.content.res.Resources;
     23 import android.graphics.drawable.Drawable;
     24 import android.nfc.NfcAdapter;
     25 import android.nfc.cardemulation.ApduServiceInfo;
     26 import android.nfc.cardemulation.CardEmulation;
     27 import android.os.Handler;
     28 import android.os.Message;
     29 import android.provider.Settings;
     30 import android.provider.Settings.SettingNotFoundException;
     31 
     32 import com.android.internal.content.PackageMonitor;
     33 
     34 import java.util.ArrayList;
     35 import java.util.List;
     36 
     37 public class PaymentBackend {
     38     public static final String TAG = "Settings.PaymentBackend";
     39 
     40     public interface Callback {
     41         void onPaymentAppsChanged();
     42     }
     43 
     44     public static class PaymentAppInfo {
     45         CharSequence label;
     46         CharSequence description;
     47         Drawable banner;
     48         boolean isDefault;
     49         public ComponentName componentName;
     50         public ComponentName settingsComponent;
     51     }
     52 
     53     private final Context mContext;
     54     private final NfcAdapter mAdapter;
     55     private final CardEmulation mCardEmuManager;
     56     private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
     57     // Fields below only modified on UI thread
     58     private ArrayList<PaymentAppInfo> mAppInfos;
     59     private PaymentAppInfo mDefaultAppInfo;
     60     private ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
     61 
     62     public PaymentBackend(Context context) {
     63         mContext = context;
     64 
     65         mAdapter = NfcAdapter.getDefaultAdapter(context);
     66         mCardEmuManager = CardEmulation.getInstance(mAdapter);
     67         refresh();
     68     }
     69 
     70     public void onPause() {
     71         mSettingsPackageMonitor.unregister();
     72     }
     73 
     74     public void onResume() {
     75         mSettingsPackageMonitor.register(mContext, mContext.getMainLooper(), false);
     76     }
     77 
     78     public void refresh() {
     79         PackageManager pm = mContext.getPackageManager();
     80         List<ApduServiceInfo> serviceInfos =
     81                 mCardEmuManager.getServices(CardEmulation.CATEGORY_PAYMENT);
     82         ArrayList<PaymentAppInfo> appInfos = new ArrayList<PaymentAppInfo>();
     83 
     84         if (serviceInfos == null) {
     85             makeCallbacks();
     86             return;
     87         }
     88 
     89         ComponentName defaultAppName = getDefaultPaymentApp();
     90         PaymentAppInfo foundDefaultApp = null;
     91         for (ApduServiceInfo service : serviceInfos) {
     92             PaymentAppInfo appInfo = new PaymentAppInfo();
     93             appInfo.label = service.loadLabel(pm);
     94             if (appInfo.label == null) {
     95                 appInfo.label = service.loadAppLabel(pm);
     96             }
     97             appInfo.isDefault = service.getComponent().equals(defaultAppName);
     98             if (appInfo.isDefault) {
     99                 foundDefaultApp = appInfo;
    100             }
    101             appInfo.componentName = service.getComponent();
    102             String settingsActivity = service.getSettingsActivityName();
    103             if (settingsActivity != null) {
    104                 appInfo.settingsComponent = new ComponentName(appInfo.componentName.getPackageName(),
    105                         settingsActivity);
    106             } else {
    107                 appInfo.settingsComponent = null;
    108             }
    109             appInfo.description = service.getDescription();
    110             appInfo.banner = service.loadBanner(pm);
    111             appInfos.add(appInfo);
    112         }
    113         mAppInfos = appInfos;
    114         mDefaultAppInfo = foundDefaultApp;
    115         makeCallbacks();
    116     }
    117 
    118     public void registerCallback(Callback callback) {
    119         mCallbacks.add(callback);
    120     }
    121 
    122     public void unregisterCallback(Callback callback) {
    123         mCallbacks.remove(callback);
    124     }
    125 
    126     public List<PaymentAppInfo> getPaymentAppInfos() {
    127         return mAppInfos;
    128     }
    129 
    130     public PaymentAppInfo getDefaultApp() {
    131         return mDefaultAppInfo;
    132     }
    133 
    134     void makeCallbacks() {
    135         for (Callback callback : mCallbacks) {
    136             callback.onPaymentAppsChanged();
    137         }
    138     }
    139 
    140     Drawable loadDrawableForPackage(String pkgName, int drawableResId) {
    141         PackageManager pm = mContext.getPackageManager();
    142         try {
    143             Resources res = pm.getResourcesForApplication(pkgName);
    144             Drawable banner = res.getDrawable(drawableResId);
    145             return banner;
    146         } catch (Resources.NotFoundException e) {
    147             return null;
    148         } catch (PackageManager.NameNotFoundException e) {
    149             return null;
    150         }
    151     }
    152 
    153     boolean isForegroundMode() {
    154         try {
    155             return Settings.Secure.getInt(mContext.getContentResolver(),
    156                     Settings.Secure.NFC_PAYMENT_FOREGROUND) != 0;
    157         } catch (SettingNotFoundException e) {
    158             return false;
    159         }
    160     }
    161 
    162     void setForegroundMode(boolean foreground) {
    163         Settings.Secure.putInt(mContext.getContentResolver(),
    164                 Settings.Secure.NFC_PAYMENT_FOREGROUND, foreground ? 1 : 0) ;
    165     }
    166 
    167     ComponentName getDefaultPaymentApp() {
    168         String componentString = Settings.Secure.getString(mContext.getContentResolver(),
    169                 Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
    170         if (componentString != null) {
    171             return ComponentName.unflattenFromString(componentString);
    172         } else {
    173             return null;
    174         }
    175     }
    176 
    177     public void setDefaultPaymentApp(ComponentName app) {
    178         Settings.Secure.putString(mContext.getContentResolver(),
    179                 Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
    180                 app != null ? app.flattenToString() : null);
    181         refresh();
    182     }
    183 
    184     private final Handler mHandler = new Handler() {
    185         @Override
    186         public void dispatchMessage(Message msg) {
    187             refresh();
    188         }
    189     };
    190 
    191     private class SettingsPackageMonitor extends PackageMonitor {
    192         @Override
    193         public void onPackageAdded(String packageName, int uid) {
    194             mHandler.obtainMessage().sendToTarget();
    195         }
    196 
    197         @Override
    198         public void onPackageAppeared(String packageName, int reason) {
    199             mHandler.obtainMessage().sendToTarget();
    200         }
    201 
    202         @Override
    203         public void onPackageDisappeared(String packageName, int reason) {
    204             mHandler.obtainMessage().sendToTarget();
    205         }
    206 
    207         @Override
    208         public void onPackageRemoved(String packageName, int uid) {
    209             mHandler.obtainMessage().sendToTarget();
    210         }
    211     }
    212 }
    213