blob: 5ed96c0d80b839ce15f7cd00254ad1c2a54fdb79 [file] [log] [blame]
nxpandroid64fd68c2015-09-23 16:45:15 +05301/*
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
17package com.android.nfc.cardemulation;
18
19import com.android.internal.R;
20import com.android.internal.app.AlertActivity;
21import com.android.internal.app.AlertController;
22
23import java.util.ArrayList;
24import java.util.List;
25
26import android.app.ActivityManager;
27import android.content.BroadcastReceiver;
28import android.content.ComponentName;
29import android.content.Context;
30import android.content.Intent;
31import android.content.IntentFilter;
32import android.content.pm.ApplicationInfo;
33import android.content.pm.PackageManager;
34import android.content.pm.PackageManager.NameNotFoundException;
35import android.graphics.drawable.Drawable;
36import android.nfc.NfcAdapter;
37import android.nfc.cardemulation.ApduServiceInfo;
38import android.nfc.cardemulation.CardEmulation;
39import android.os.Bundle;
40import android.util.Log;
41import android.view.LayoutInflater;
42import android.view.View;
43import android.view.ViewGroup;
44import android.view.Window;
45import android.view.WindowManager;
46import android.widget.AdapterView;
47import android.widget.BaseAdapter;
48import android.widget.ImageView;
49import android.widget.ListView;
50import android.widget.TextView;
51
52public class AppChooserActivity extends AlertActivity
53 implements AdapterView.OnItemClickListener {
54
55 static final String TAG = "AppChooserActivity";
56
57 public static final String EXTRA_APDU_SERVICES = "services";
58 public static final String EXTRA_CATEGORY = "category";
59 public static final String EXTRA_FAILED_COMPONENT = "failed_component";
60
61 private int mIconSize;
62 private ListView mListView;
63 private ListAdapter mListAdapter;
64 private CardEmulation mCardEmuManager;
65 private String mCategory;
66
67 final BroadcastReceiver mReceiver = new BroadcastReceiver() {
68 @Override
69 public void onReceive(Context context, Intent intent) {
70 finish();
71 }
72 };
73
74 @Override
75 protected void onDestroy() {
76 super.onDestroy();
77 unregisterReceiver(mReceiver);
78 }
79
80 protected void onCreate(Bundle savedInstanceState, String category,
81 ArrayList<ApduServiceInfo> options, ComponentName failedComponent) {
82 super.onCreate(savedInstanceState);
83 setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert);
84
85 IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
86 registerReceiver(mReceiver, filter);
87
88 if ((options == null || options.size() == 0) && failedComponent == null) {
89 Log.e(TAG, "No components passed in.");
90 finish();
91 return;
92 }
93
94 mCategory = category;
95 boolean isPayment = CardEmulation.CATEGORY_PAYMENT.equals(mCategory);
96
97 final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
98 mCardEmuManager = CardEmulation.getInstance(adapter);
99 AlertController.AlertParams ap = mAlertParams;
100
101 final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
102 mIconSize = am.getLauncherLargeIconSize();
103
104 // Three cases:
105 // 1. Failed component and no alternatives: just an OK box
106 // 2. Failed component and alternatives: pick alternative
107 // 3. No failed component and alternatives: pick alternative
108 PackageManager pm = getPackageManager();
109
110 CharSequence applicationLabel = "unknown";
111 if (failedComponent != null) {
112 try {
113 ApplicationInfo info = pm.getApplicationInfo(failedComponent.getPackageName(), 0);
114 applicationLabel = info.loadLabel(pm);
115 } catch (NameNotFoundException e) {
116 }
117
118 }
119 if (options.size() == 0 && failedComponent != null) {
120 String formatString = getString(com.android.nfc.R.string.transaction_failure);
121 ap.mTitle = "";
122 ap.mMessage = String.format(formatString, applicationLabel);
123 ap.mPositiveButtonText = getString(R.string.ok);
124 setupAlert();
125 } else {
126 mListAdapter = new ListAdapter(this, options);
127 if (failedComponent != null) {
128 String formatString = getString(com.android.nfc.R.string.could_not_use_app);
129 ap.mTitle = String.format(formatString, applicationLabel);
130 ap.mNegativeButtonText = getString(R.string.cancel);
131 } else {
132 if (CardEmulation.CATEGORY_PAYMENT.equals(category)) {
133 ap.mTitle = getString(com.android.nfc.R.string.pay_with);
134 } else {
135 ap.mTitle = getString(com.android.nfc.R.string.complete_with);
136 }
137 }
138 ap.mView = getLayoutInflater().inflate(com.android.nfc.R.layout.cardemu_resolver, null);
139
140 mListView = (ListView) ap.mView.findViewById(com.android.nfc.R.id.resolver_list);
141 if (isPayment) {
142 mListView.setDivider(getResources().getDrawable(android.R.color.transparent));
143 int height = (int) (getResources().getDisplayMetrics().density * 16);
144 mListView.setDividerHeight(height);
145 } else {
146 mListView.setPadding(0, 0, 0, 0);
147 }
148 mListView.setAdapter(mListAdapter);
149 mListView.setOnItemClickListener(this);
150
151 setupAlert();
152 }
153 Window window = getWindow();
154 window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
155 }
156
157 @Override
158 protected void onCreate(Bundle savedInstanceState) {
159 Intent intent = getIntent();
160 ArrayList<ApduServiceInfo> services = intent.getParcelableArrayListExtra(EXTRA_APDU_SERVICES);
161 String category = intent.getStringExtra(EXTRA_CATEGORY);
162 ComponentName failedComponent = intent.getParcelableExtra(EXTRA_FAILED_COMPONENT);
163 onCreate(savedInstanceState, category, services, failedComponent);
164 }
165
166 @Override
167 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
168 DisplayAppInfo info = (DisplayAppInfo) mListAdapter.getItem(position);
169 mCardEmuManager.setDefaultForNextTap(info.serviceInfo.getComponent());
170 Intent dialogIntent = new Intent(this, TapAgainDialog.class);
171 dialogIntent.putExtra(TapAgainDialog.EXTRA_CATEGORY, mCategory);
172 dialogIntent.putExtra(TapAgainDialog.EXTRA_APDU_SERVICE, info.serviceInfo);
173 startActivity(dialogIntent);
174 finish();
175 }
176
177 final class DisplayAppInfo {
178 ApduServiceInfo serviceInfo;
179 CharSequence displayLabel;
180 Drawable displayIcon;
181 Drawable displayBanner;
182
183 public DisplayAppInfo(ApduServiceInfo serviceInfo, CharSequence label, Drawable icon,
184 Drawable banner) {
185 this.serviceInfo = serviceInfo;
186 displayIcon = icon;
187 displayLabel = label;
188 displayBanner = banner;
189 }
190 }
191
192 final class ListAdapter extends BaseAdapter {
193 private final LayoutInflater mInflater;
194 private final boolean mIsPayment;
195 private List<DisplayAppInfo> mList;
196
197 public ListAdapter(Context context, ArrayList<ApduServiceInfo> services) {
198 mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
199 // For each component, get the corresponding app name and icon
200 PackageManager pm = getPackageManager();
201 mList = new ArrayList<DisplayAppInfo>();
202 mIsPayment = CardEmulation.CATEGORY_PAYMENT.equals(mCategory);
203 for (ApduServiceInfo service : services) {
204 CharSequence label = service.getDescription();
205 if (label == null) label = service.loadLabel(pm);
206 Drawable icon = service.loadIcon(pm);
207 Drawable banner = null;
208 if (mIsPayment) {
209 banner = service.loadBanner(pm);
210 if (banner == null) {
211 Log.e(TAG, "Not showing " + label + " because no banner specified.");
212 continue;
213 }
214 }
215 DisplayAppInfo info = new DisplayAppInfo(service, label, icon, banner);
216 mList.add(info);
217 }
218 }
219
220 @Override
221 public int getCount() {
222 return mList.size();
223 }
224
225 @Override
226 public Object getItem(int position) {
227 return mList.get(position);
228 }
229
230 @Override
231 public long getItemId(int position) {
232 return position;
233 }
234
235 @Override
236 public View getView(int position, View convertView, ViewGroup parent) {
237 View view;
238 if (convertView == null) {
239 if (mIsPayment) {
240 view = mInflater.inflate(
241 com.android.nfc.R.layout.cardemu_payment_item, parent, false);
242 } else {
243 view = mInflater.inflate(
244 com.android.nfc.R.layout.cardemu_item, parent, false);
245 }
246 final ViewHolder holder = new ViewHolder(view);
247 view.setTag(holder);
248
249 } else {
250 view = convertView;
251 }
252
253 final ViewHolder holder = (ViewHolder) view.getTag();
254 DisplayAppInfo appInfo = mList.get(position);
255 if (mIsPayment) {
256 holder.banner.setImageDrawable(appInfo.displayBanner);
257 } else {
258 ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
259 lp.width = lp.height = mIconSize;
260 holder.icon.setImageDrawable(appInfo.displayIcon);
261 holder.text.setText(appInfo.displayLabel);
262 }
263 return view;
264 }
265 }
266
267 static class ViewHolder {
268 public TextView text;
269 public ImageView icon;
270 public ImageView banner;
271 public ViewHolder(View view) {
272 text = (TextView) view.findViewById(com.android.nfc.R.id.applabel);
273 icon = (ImageView) view.findViewById(com.android.nfc.R.id.appicon);
274 banner = (ImageView) view.findViewById(com.android.nfc.R.id.banner);
275 }
276 }
nxpandroid8aecbf82016-09-16 20:21:47 +0530277}