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