175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen/* 275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * Copyright (C) 2013 The Android Open Source Project 375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * 475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * Licensed under the Apache License, Version 2.0 (the "License"); 575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * you may not use this file except in compliance with the License. 675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * You may obtain a copy of the License at 775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * 875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * http://www.apache.org/licenses/LICENSE-2.0 975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * 1075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * Unless required by applicable law or agreed to in writing, software 1175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * distributed under the License is distributed on an "AS IS" BASIS, 1275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * See the License for the specific language governing permissions and 1475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen * limitations under the License. 1575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen */ 1675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 1775f63db568f953e935e62cb3046d167b881979c8Martijn Coenenpackage com.android.nfc.cardemulation; 1875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 1975f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport com.android.internal.R; 2075f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport com.android.internal.app.AlertActivity; 2175f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport com.android.internal.app.AlertController; 2275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 2375f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport java.util.ArrayList; 2475f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport java.util.List; 2575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 2675f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.app.ActivityManager; 27dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenenimport android.content.BroadcastReceiver; 2875f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.content.ComponentName; 2975f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.content.Context; 3075f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.content.Intent; 31dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenenimport android.content.IntentFilter; 3275f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.content.pm.ApplicationInfo; 3375f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.content.pm.PackageManager; 3475f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.content.pm.PackageManager.NameNotFoundException; 3575f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.graphics.drawable.Drawable; 3675f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.nfc.NfcAdapter; 37dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenenimport android.nfc.cardemulation.ApduServiceInfo; 38f5cd84c3a7ffb66196ab3c0745569da937d7533bMartijn Coenenimport android.nfc.cardemulation.CardEmulation; 3975f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.os.Bundle; 4075f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.util.Log; 4175f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.view.LayoutInflater; 4275f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.view.View; 4375f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.view.ViewGroup; 44451ba48faa87d78bfbec0597ff06af1747cf6acbMartijn Coenenimport android.view.Window; 45451ba48faa87d78bfbec0597ff06af1747cf6acbMartijn Coenenimport android.view.WindowManager; 4675f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.widget.AdapterView; 4775f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.widget.BaseAdapter; 4875f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.widget.ImageView; 4975f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.widget.ListView; 5075f63db568f953e935e62cb3046d167b881979c8Martijn Coenenimport android.widget.TextView; 5175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 5275f63db568f953e935e62cb3046d167b881979c8Martijn Coenenpublic class AppChooserActivity extends AlertActivity 5375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen implements AdapterView.OnItemClickListener { 5475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 5575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen static final String TAG = "AppChooserActivity"; 5675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 57dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen public static final String EXTRA_APDU_SERVICES = "services"; 5875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen public static final String EXTRA_CATEGORY = "category"; 5978976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen public static final String EXTRA_FAILED_COMPONENT = "failed_component"; 6075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 6175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen private int mIconSize; 6275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen private ListView mListView; 6375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen private ListAdapter mListAdapter; 64f5cd84c3a7ffb66196ab3c0745569da937d7533bMartijn Coenen private CardEmulation mCardEmuManager; 6575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen private String mCategory; 6675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 67dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen final BroadcastReceiver mReceiver = new BroadcastReceiver() { 68dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen @Override 69dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen public void onReceive(Context context, Intent intent) { 70dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen finish(); 71dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen } 72dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen }; 73dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen 74dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen @Override 75dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen protected void onDestroy() { 76dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen super.onDestroy(); 77dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen unregisterReceiver(mReceiver); 78dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen } 79dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen 8075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen protected void onCreate(Bundle savedInstanceState, String category, 81dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen ArrayList<ApduServiceInfo> options, ComponentName failedComponent) { 8275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen super.onCreate(savedInstanceState); 83451ba48faa87d78bfbec0597ff06af1747cf6acbMartijn Coenen setTheme(R.style.Theme_DeviceDefault_Light_Dialog_Alert); 8475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 85dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); 86dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen registerReceiver(mReceiver, filter); 87dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen 8878976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen if ((options == null || options.size() == 0) && failedComponent == null) { 8975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen Log.e(TAG, "No components passed in."); 9075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen finish(); 9175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen return; 9275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 9375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 9475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen mCategory = category; 95dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen boolean isPayment = CardEmulation.CATEGORY_PAYMENT.equals(mCategory); 9675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 9775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); 98f5cd84c3a7ffb66196ab3c0745569da937d7533bMartijn Coenen mCardEmuManager = CardEmulation.getInstance(adapter); 9975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen AlertController.AlertParams ap = mAlertParams; 10075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 10175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); 10275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen mIconSize = am.getLauncherLargeIconSize(); 10375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 10478976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen // Three cases: 10578976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen // 1. Failed component and no alternatives: just an OK box 10678976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen // 2. Failed component and alternatives: pick alternative 10778976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen // 3. No failed component and alternatives: pick alternative 10878976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen PackageManager pm = getPackageManager(); 10975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 11078976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen CharSequence applicationLabel = "unknown"; 11178976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen if (failedComponent != null) { 11278976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen try { 11378976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen ApplicationInfo info = pm.getApplicationInfo(failedComponent.getPackageName(), 0); 11478976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen applicationLabel = info.loadLabel(pm); 11578976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen } catch (NameNotFoundException e) { 11678976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen } 11778976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen 11878976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen } 11978976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen if (options.size() == 0 && failedComponent != null) { 120dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen String formatString = getString(com.android.nfc.R.string.transaction_failure); 12178976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen ap.mTitle = ""; 122dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen ap.mMessage = String.format(formatString, applicationLabel); 123dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen ap.mPositiveButtonText = getString(R.string.ok); 12478976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen setupAlert(); 12575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } else { 12678976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen mListAdapter = new ListAdapter(this, options); 12778976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen if (failedComponent != null) { 128dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen String formatString = getString(com.android.nfc.R.string.could_not_use_app); 129dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen ap.mTitle = String.format(formatString, applicationLabel); 130dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen ap.mNegativeButtonText = getString(R.string.cancel); 13178976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen } else { 132f5cd84c3a7ffb66196ab3c0745569da937d7533bMartijn Coenen if (CardEmulation.CATEGORY_PAYMENT.equals(category)) { 133dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen ap.mTitle = getString(com.android.nfc.R.string.pay_with); 13478976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen } else { 135dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen ap.mTitle = getString(com.android.nfc.R.string.complete_with); 13678976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen } 13778976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen } 13878976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen ap.mView = getLayoutInflater().inflate(com.android.nfc.R.layout.cardemu_resolver, null); 13978976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen 14078976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen mListView = (ListView) ap.mView.findViewById(com.android.nfc.R.id.resolver_list); 141dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen if (isPayment) { 142a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen mListView.setDivider(getResources().getDrawable(android.R.color.transparent)); 143a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen int height = (int) (getResources().getDisplayMetrics().density * 16); 144a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen mListView.setDividerHeight(height); 145dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen } else { 146dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen mListView.setPadding(0, 0, 0, 0); 147dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen } 14878976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen mListView.setAdapter(mListAdapter); 14978976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen mListView.setOnItemClickListener(this); 15078976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen 15178976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen setupAlert(); 15275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 153451ba48faa87d78bfbec0597ff06af1747cf6acbMartijn Coenen Window window = getWindow(); 154451ba48faa87d78bfbec0597ff06af1747cf6acbMartijn Coenen window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); 15575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 15675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 15775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen @Override 15875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen protected void onCreate(Bundle savedInstanceState) { 15975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen Intent intent = getIntent(); 160dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen ArrayList<ApduServiceInfo> services = intent.getParcelableArrayListExtra(EXTRA_APDU_SERVICES); 16175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen String category = intent.getStringExtra(EXTRA_CATEGORY); 16278976de08ad5d5f9d5fcba28f3ea82350907a782Martijn Coenen ComponentName failedComponent = intent.getParcelableExtra(EXTRA_FAILED_COMPONENT); 163dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen onCreate(savedInstanceState, category, services, failedComponent); 16475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 16575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 16675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen @Override 16775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 16875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen DisplayAppInfo info = (DisplayAppInfo) mListAdapter.getItem(position); 169a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen mCardEmuManager.setDefaultForNextTap(info.serviceInfo.getComponent()); 17075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen Intent dialogIntent = new Intent(this, TapAgainDialog.class); 17175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen dialogIntent.putExtra(TapAgainDialog.EXTRA_CATEGORY, mCategory); 172a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen dialogIntent.putExtra(TapAgainDialog.EXTRA_APDU_SERVICE, info.serviceInfo); 17375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen startActivity(dialogIntent); 17475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen finish(); 17575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 17675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 17775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen final class DisplayAppInfo { 178a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen ApduServiceInfo serviceInfo; 17975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen CharSequence displayLabel; 18075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen Drawable displayIcon; 181dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen Drawable displayBanner; 18275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 183a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen public DisplayAppInfo(ApduServiceInfo serviceInfo, CharSequence label, Drawable icon, 184dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen Drawable banner) { 185a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen this.serviceInfo = serviceInfo; 18675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen displayIcon = icon; 18775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen displayLabel = label; 188dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen displayBanner = banner; 18975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 19075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 19175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 19275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen final class ListAdapter extends BaseAdapter { 19375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen private final LayoutInflater mInflater; 194dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen private final boolean mIsPayment; 19575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen private List<DisplayAppInfo> mList; 19675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 197dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen public ListAdapter(Context context, ArrayList<ApduServiceInfo> services) { 19875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 19975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen // For each component, get the corresponding app name and icon 20075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen PackageManager pm = getPackageManager(); 20175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen mList = new ArrayList<DisplayAppInfo>(); 202dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen mIsPayment = CardEmulation.CATEGORY_PAYMENT.equals(mCategory); 203dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen for (ApduServiceInfo service : services) { 204a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen CharSequence label = service.getDescription(); 205a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen if (label == null) label = service.loadLabel(pm); 206dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen Drawable icon = service.loadIcon(pm); 207dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen Drawable banner = null; 208dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen if (mIsPayment) { 209dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen banner = service.loadBanner(pm); 210dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen if (banner == null) { 211dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen Log.e(TAG, "Not showing " + label + " because no banner specified."); 212dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen continue; 213dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen } 21475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 215a3b2c7944266cbd02afc08ce48ce8259d8a65019Martijn Coenen DisplayAppInfo info = new DisplayAppInfo(service, label, icon, banner); 216dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen mList.add(info); 21775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 21875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 21975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 22075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen @Override 22175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen public int getCount() { 22275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen return mList.size(); 22375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 22475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 22575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen @Override 22675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen public Object getItem(int position) { 22775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen return mList.get(position); 22875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 22975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 23075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen @Override 23175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen public long getItemId(int position) { 23275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen return position; 23375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 23475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 23575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen @Override 23675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen public View getView(int position, View convertView, ViewGroup parent) { 23775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen View view; 23875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen if (convertView == null) { 239dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen if (mIsPayment) { 240dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen view = mInflater.inflate( 241dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen com.android.nfc.R.layout.cardemu_payment_item, parent, false); 242dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen } else { 243dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen view = mInflater.inflate( 244dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen com.android.nfc.R.layout.cardemu_item, parent, false); 245dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen } 24675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen final ViewHolder holder = new ViewHolder(view); 24775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen view.setTag(holder); 24875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 24975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } else { 25075f63db568f953e935e62cb3046d167b881979c8Martijn Coenen view = convertView; 25175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 25275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 25375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen final ViewHolder holder = (ViewHolder) view.getTag(); 25475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen DisplayAppInfo appInfo = mList.get(position); 255dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen if (mIsPayment) { 256dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen holder.banner.setImageDrawable(appInfo.displayBanner); 257dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen } else { 258dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen ViewGroup.LayoutParams lp = holder.icon.getLayoutParams(); 259dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen lp.width = lp.height = mIconSize; 260dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen holder.icon.setImageDrawable(appInfo.displayIcon); 261dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen holder.text.setText(appInfo.displayLabel); 262dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen } 26375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen return view; 26475f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 26575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 26675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen 26775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen static class ViewHolder { 26875f63db568f953e935e62cb3046d167b881979c8Martijn Coenen public TextView text; 26975f63db568f953e935e62cb3046d167b881979c8Martijn Coenen public ImageView icon; 270dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen public ImageView banner; 27175f63db568f953e935e62cb3046d167b881979c8Martijn Coenen public ViewHolder(View view) { 27275f63db568f953e935e62cb3046d167b881979c8Martijn Coenen text = (TextView) view.findViewById(com.android.nfc.R.id.applabel); 27375f63db568f953e935e62cb3046d167b881979c8Martijn Coenen icon = (ImageView) view.findViewById(com.android.nfc.R.id.appicon); 274dc304dadda013e383fdd1348b2a24bc6b3c9acacMartijn Coenen banner = (ImageView) view.findViewById(com.android.nfc.R.id.banner); 27575f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 27675f63db568f953e935e62cb3046d167b881979c8Martijn Coenen } 27775f63db568f953e935e62cb3046d167b881979c8Martijn Coenen}