• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
onPaymentAppsChanged()41         void onPaymentAppsChanged();
42     }
43 
44     public static class PaymentAppInfo {
45         public 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 
PaymentBackend(Context context)62     public PaymentBackend(Context context) {
63         mContext = context;
64 
65         mAdapter = NfcAdapter.getDefaultAdapter(context);
66         mCardEmuManager = CardEmulation.getInstance(mAdapter);
67         refresh();
68     }
69 
onPause()70     public void onPause() {
71         mSettingsPackageMonitor.unregister();
72     }
73 
onResume()74     public void onResume() {
75         mSettingsPackageMonitor.register(mContext, mContext.getMainLooper(), false);
76         refresh();
77     }
78 
refresh()79     public void refresh() {
80         PackageManager pm = mContext.getPackageManager();
81         List<ApduServiceInfo> serviceInfos =
82                 mCardEmuManager.getServices(CardEmulation.CATEGORY_PAYMENT);
83         ArrayList<PaymentAppInfo> appInfos = new ArrayList<PaymentAppInfo>();
84 
85         if (serviceInfos == null) {
86             makeCallbacks();
87             return;
88         }
89 
90         ComponentName defaultAppName = getDefaultPaymentApp();
91         PaymentAppInfo foundDefaultApp = null;
92         for (ApduServiceInfo service : serviceInfos) {
93             PaymentAppInfo appInfo = new PaymentAppInfo();
94             appInfo.label = service.loadLabel(pm);
95             if (appInfo.label == null) {
96                 appInfo.label = service.loadAppLabel(pm);
97             }
98             appInfo.isDefault = service.getComponent().equals(defaultAppName);
99             if (appInfo.isDefault) {
100                 foundDefaultApp = appInfo;
101             }
102             appInfo.componentName = service.getComponent();
103             String settingsActivity = service.getSettingsActivityName();
104             if (settingsActivity != null) {
105                 appInfo.settingsComponent = new ComponentName(appInfo.componentName.getPackageName(),
106                         settingsActivity);
107             } else {
108                 appInfo.settingsComponent = null;
109             }
110             appInfo.description = service.getDescription();
111             appInfo.banner = service.loadBanner(pm);
112             appInfos.add(appInfo);
113         }
114         mAppInfos = appInfos;
115         mDefaultAppInfo = foundDefaultApp;
116         makeCallbacks();
117     }
118 
registerCallback(Callback callback)119     public void registerCallback(Callback callback) {
120         mCallbacks.add(callback);
121     }
122 
unregisterCallback(Callback callback)123     public void unregisterCallback(Callback callback) {
124         mCallbacks.remove(callback);
125     }
126 
getPaymentAppInfos()127     public List<PaymentAppInfo> getPaymentAppInfos() {
128         return mAppInfos;
129     }
130 
getDefaultApp()131     public PaymentAppInfo getDefaultApp() {
132         return mDefaultAppInfo;
133     }
134 
makeCallbacks()135     void makeCallbacks() {
136         for (Callback callback : mCallbacks) {
137             callback.onPaymentAppsChanged();
138         }
139     }
140 
loadDrawableForPackage(String pkgName, int drawableResId)141     Drawable loadDrawableForPackage(String pkgName, int drawableResId) {
142         PackageManager pm = mContext.getPackageManager();
143         try {
144             Resources res = pm.getResourcesForApplication(pkgName);
145             Drawable banner = res.getDrawable(drawableResId);
146             return banner;
147         } catch (Resources.NotFoundException e) {
148             return null;
149         } catch (PackageManager.NameNotFoundException e) {
150             return null;
151         }
152     }
153 
isForegroundMode()154     boolean isForegroundMode() {
155         try {
156             return Settings.Secure.getInt(mContext.getContentResolver(),
157                     Settings.Secure.NFC_PAYMENT_FOREGROUND) != 0;
158         } catch (SettingNotFoundException e) {
159             return false;
160         }
161     }
162 
setForegroundMode(boolean foreground)163     void setForegroundMode(boolean foreground) {
164         Settings.Secure.putInt(mContext.getContentResolver(),
165                 Settings.Secure.NFC_PAYMENT_FOREGROUND, foreground ? 1 : 0) ;
166     }
167 
getDefaultPaymentApp()168     ComponentName getDefaultPaymentApp() {
169         String componentString = Settings.Secure.getString(mContext.getContentResolver(),
170                 Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT);
171         if (componentString != null) {
172             return ComponentName.unflattenFromString(componentString);
173         } else {
174             return null;
175         }
176     }
177 
setDefaultPaymentApp(ComponentName app)178     public void setDefaultPaymentApp(ComponentName app) {
179         Settings.Secure.putString(mContext.getContentResolver(),
180                 Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
181                 app != null ? app.flattenToString() : null);
182         refresh();
183     }
184 
185     private final Handler mHandler = new Handler() {
186         @Override
187         public void dispatchMessage(Message msg) {
188             refresh();
189         }
190     };
191 
192     private class SettingsPackageMonitor extends PackageMonitor {
193         @Override
onPackageAdded(String packageName, int uid)194         public void onPackageAdded(String packageName, int uid) {
195             mHandler.obtainMessage().sendToTarget();
196         }
197 
198         @Override
onPackageAppeared(String packageName, int reason)199         public void onPackageAppeared(String packageName, int reason) {
200             mHandler.obtainMessage().sendToTarget();
201         }
202 
203         @Override
onPackageDisappeared(String packageName, int reason)204         public void onPackageDisappeared(String packageName, int reason) {
205             mHandler.obtainMessage().sendToTarget();
206         }
207 
208         @Override
onPackageRemoved(String packageName, int uid)209         public void onPackageRemoved(String packageName, int uid) {
210             mHandler.obtainMessage().sendToTarget();
211         }
212     }
213 }
214