am a3b2c794: Latest HCE UX.

* commit 'a3b2c7944266cbd02afc08ce48ce8259d8a65019':
  Latest HCE UX.
diff --git a/res/layout/cardemu_resolver.xml b/res/layout/cardemu_resolver.xml
index 29ebf3b..34b141e 100644
--- a/res/layout/cardemu_resolver.xml
+++ b/res/layout/cardemu_resolver.xml
@@ -30,7 +30,6 @@
             android:layout_height="match_parent"
             android:id="@+id/resolver_list"
             android:clickable="true"
-            android:dividerHeight="16dp"
             android:paddingTop="16dp"
             android:paddingBottom="16dp"/>
     </FrameLayout>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1376d82..28687d7 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -57,4 +57,7 @@
     <string name="pay_with">Pay with</string>
     <!-- Label for a dialog showing a list of applications that can be used to complete the NFC action -->
     <string name="complete_with">Complete with</string>
+    <!-- String that is telling the user that his default app for tap and pay has been removed,
+         and asks him to pick another app as default.-->
+    <string name="default_pay_app_removed">Your preferred service for tap &amp; pay was removed. Choose another?"</string>
 </resources>
diff --git a/src/com/android/nfc/cardemulation/AppChooserActivity.java b/src/com/android/nfc/cardemulation/AppChooserActivity.java
index 2ae0a68..7bc0a7e 100644
--- a/src/com/android/nfc/cardemulation/AppChooserActivity.java
+++ b/src/com/android/nfc/cardemulation/AppChooserActivity.java
@@ -140,8 +140,9 @@
 
             mListView = (ListView) ap.mView.findViewById(com.android.nfc.R.id.resolver_list);
             if (isPayment) {
-                mListView.setDivider(null);
-                mListView.setDividerHeight(0);
+                mListView.setDivider(getResources().getDrawable(android.R.color.transparent));
+                int height = (int) (getResources().getDisplayMetrics().density * 16);
+                mListView.setDividerHeight(height);
             } else {
                 mListView.setPadding(0, 0, 0, 0);
             }
@@ -166,23 +167,23 @@
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         DisplayAppInfo info = (DisplayAppInfo) mListAdapter.getItem(position);
-        mCardEmuManager.setDefaultForNextTap(info.component);
+        mCardEmuManager.setDefaultForNextTap(info.serviceInfo.getComponent());
         Intent dialogIntent = new Intent(this, TapAgainDialog.class);
         dialogIntent.putExtra(TapAgainDialog.EXTRA_CATEGORY, mCategory);
-        dialogIntent.putExtra(TapAgainDialog.EXTRA_COMPONENT, info.component);
+        dialogIntent.putExtra(TapAgainDialog.EXTRA_APDU_SERVICE, info.serviceInfo);
         startActivity(dialogIntent);
         finish();
     }
 
     final class DisplayAppInfo {
-        ComponentName component;
+        ApduServiceInfo serviceInfo;
         CharSequence displayLabel;
         Drawable displayIcon;
         Drawable displayBanner;
 
-        public DisplayAppInfo(ComponentName component, CharSequence label, Drawable icon,
+        public DisplayAppInfo(ApduServiceInfo serviceInfo, CharSequence label, Drawable icon,
                 Drawable banner) {
-            this.component = component;
+            this.serviceInfo = serviceInfo;
             displayIcon = icon;
             displayLabel = label;
             displayBanner = banner;
@@ -201,7 +202,8 @@
             mList = new ArrayList<DisplayAppInfo>();
             mIsPayment = CardEmulation.CATEGORY_PAYMENT.equals(mCategory);
             for (ApduServiceInfo service : services) {
-                CharSequence label = service.loadLabel(pm);
+                CharSequence label = service.getDescription();
+                if (label == null) label = service.loadLabel(pm);
                 Drawable icon = service.loadIcon(pm);
                 Drawable banner = null;
                 if (mIsPayment) {
@@ -211,7 +213,7 @@
                         continue;
                     }
                 }
-                DisplayAppInfo info = new DisplayAppInfo(service.getComponent(), label, icon, banner);
+                DisplayAppInfo info = new DisplayAppInfo(service, label, icon, banner);
                 mList.add(info);
             }
         }
diff --git a/src/com/android/nfc/cardemulation/DefaultRemovedActivity.java b/src/com/android/nfc/cardemulation/DefaultRemovedActivity.java
index 67ca19e..9e3aa75 100644
--- a/src/com/android/nfc/cardemulation/DefaultRemovedActivity.java
+++ b/src/com/android/nfc/cardemulation/DefaultRemovedActivity.java
@@ -18,7 +18,7 @@
 
         AlertController.AlertParams ap = mAlertParams;
 
-        ap.mMessage = "Your preferred service for tap and pay was removed. Choose another?";
+        ap.mMessage = getString(com.android.nfc.R.string.default_pay_app_removed);
         ap.mNegativeButtonText = getString(R.string.no);
         ap.mPositiveButtonText = getString(R.string.yes);
         ap.mPositiveButtonListener = this;
diff --git a/src/com/android/nfc/cardemulation/HostEmulationManager.java b/src/com/android/nfc/cardemulation/HostEmulationManager.java
index 2fe45ec..0dc75b5 100644
--- a/src/com/android/nfc/cardemulation/HostEmulationManager.java
+++ b/src/com/android/nfc/cardemulation/HostEmulationManager.java
@@ -170,18 +170,25 @@
                 mLastSelectedAid = resolveInfo.aid;
                 if (resolveInfo.defaultService != null) {
                     // Resolve to default
-                    resolvedService = resolveInfo.defaultService.getComponent();
                     // Check if resolvedService requires unlock
                     if (resolveInfo.defaultService.requiresUnlock() &&
                             mKeyguard.isKeyguardLocked() && mKeyguard.isKeyguardSecure()) {
                         String category = mAidCache.getCategoryForAid(resolveInfo.aid);
                         // Just ignore all future APDUs until next tap
                         mState = STATE_W4_DEACTIVATE;
-                        launchTapAgain(resolvedService, category);
+                        launchTapAgain(resolveInfo.defaultService, category);
                         return;
                     }
-                    // TODO also handle case where we prefer the bound service?
-                } else {
+                    resolvedService = resolveInfo.defaultService.getComponent();
+                } else if (mActiveServiceName != null) {
+                    for (ApduServiceInfo service : resolveInfo.services) {
+                        if (mActiveServiceName.equals(service.getComponent())) {
+                            resolvedService = mActiveServiceName;
+                            break;
+                        }
+                    }
+                }
+                if (resolvedService == null) {
                     // We have no default, and either one or more services.
                     // Ask the user to confirm.
                     // Get corresponding category
@@ -380,10 +387,10 @@
         }
     }
 
-    void launchTapAgain(ComponentName service, String category) {
+    void launchTapAgain(ApduServiceInfo service, String category) {
         Intent dialogIntent = new Intent(mContext, TapAgainDialog.class);
         dialogIntent.putExtra(TapAgainDialog.EXTRA_CATEGORY, category);
-        dialogIntent.putExtra(TapAgainDialog.EXTRA_COMPONENT, service);
+        dialogIntent.putExtra(TapAgainDialog.EXTRA_APDU_SERVICE, service);
         dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         mContext.startActivityAsUser(dialogIntent, UserHandle.CURRENT);
     }
diff --git a/src/com/android/nfc/cardemulation/RegisteredAidCache.java b/src/com/android/nfc/cardemulation/RegisteredAidCache.java
index 3ae4b4c..ffa3b03 100644
--- a/src/com/android/nfc/cardemulation/RegisteredAidCache.java
+++ b/src/com/android/nfc/cardemulation/RegisteredAidCache.java
@@ -142,11 +142,10 @@
 
         if (resolveInfo.services == null || resolveInfo.services.size() == 0) return false;
 
-        if (service.equals(resolveInfo.defaultService)) {
-            return true;
+        if (resolveInfo.defaultService != null) {
+            return service.equals(resolveInfo.defaultService.getComponent());
         } else if (resolveInfo.services.size() == 1) {
-            ApduServiceInfo serviceInfo = resolveInfo.services.get(0);
-            return service.equals(serviceInfo);
+            return service.equals(resolveInfo.services.get(0).getComponent());
         } else {
             // More than one service, not the default
             return false;
@@ -246,7 +245,8 @@
                 ApduServiceInfo resolvedService = resolvedServices.get(0);
                 Log.d(TAG, "resolveAidLocked: resolved single service " +
                         resolvedService.getComponent());
-                if (resolvedService.equals(defaultComponent)) {
+                if (defaultComponent != null &&
+                        defaultComponent.equals(resolvedService.getComponent())) {
                     if (DBG) Log.d(TAG, "resolveAidLocked: DECISION: routing to (default) " +
                         resolvedService.getComponent());
                     resolveInfo.defaultService = resolvedService;
diff --git a/src/com/android/nfc/cardemulation/TapAgainDialog.java b/src/com/android/nfc/cardemulation/TapAgainDialog.java
index a70f5d3..b0b7ada 100644
--- a/src/com/android/nfc/cardemulation/TapAgainDialog.java
+++ b/src/com/android/nfc/cardemulation/TapAgainDialog.java
@@ -26,6 +26,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.nfc.NfcAdapter;
+import android.nfc.cardemulation.ApduServiceInfo;
 import android.nfc.cardemulation.CardEmulation;
 import android.os.Bundle;
 import android.view.Window;
@@ -38,7 +39,8 @@
 
 public class TapAgainDialog extends AlertActivity implements DialogInterface.OnClickListener {
     public static final String ACTION_CLOSE = "com.android.nfc.cardmeulation.close_tap_dialog";
-    public static final String EXTRA_COMPONENT = "component";
+    public static final String EXTRA_APDU_SERVICE = "apdu_service";
+
     public static final String EXTRA_CATEGORY = "category";
 
     // Variables below only accessed on the main thread
@@ -62,7 +64,7 @@
         mCardEmuManager = CardEmulation.getInstance(adapter);
         Intent intent = getIntent();
         String category = intent.getStringExtra(EXTRA_CATEGORY);
-        ComponentName component = (ComponentName) intent.getParcelableExtra(EXTRA_COMPONENT);
+        ApduServiceInfo serviceInfo = intent.getParcelableExtra(EXTRA_APDU_SERVICE);
         IntentFilter filter = new IntentFilter(ACTION_CLOSE);
         filter.addAction(Intent.ACTION_SCREEN_OFF);
         registerReceiver(mReceiver, filter);
@@ -72,21 +74,25 @@
         ap.mView = getLayoutInflater().inflate(com.android.nfc.R.layout.tapagain, null);
 
         PackageManager pm = getPackageManager();
-        try {
-            ApplicationInfo appInfo = pm.getApplicationInfo(component.getPackageName(), 0);
-            TextView tv = (TextView) ap.mView.findViewById(com.android.nfc.R.id.textview);
-            if (CardEmulation.CATEGORY_PAYMENT.equals(category)) {
-                String formatString = getString(com.android.nfc.R.string.tap_again_to_pay);
-                tv.setText(String.format(formatString, appInfo.loadLabel(pm)));
+        TextView tv = (TextView) ap.mView.findViewById(com.android.nfc.R.id.textview);
+        String description = serviceInfo.getDescription();
+        if (description == null) {
+            CharSequence label = serviceInfo.loadLabel(pm);
+            if (label == null) {
+                finish();
             } else {
-                String formatString = getString(com.android.nfc.R.string.tap_again_to_complete);
-                tv.setText(String.format(formatString, appInfo.loadLabel(pm)));
+                description = label.toString();
             }
-            ap.mNegativeButtonText = getString(R.string.cancel);
-            setupAlert();
-        } catch (NameNotFoundException e) {
-            finish();
         }
+        if (CardEmulation.CATEGORY_PAYMENT.equals(category)) {
+            String formatString = getString(com.android.nfc.R.string.tap_again_to_pay);
+            tv.setText(String.format(formatString, description));
+        } else {
+            String formatString = getString(com.android.nfc.R.string.tap_again_to_complete);
+            tv.setText(String.format(formatString, description));
+        }
+        ap.mNegativeButtonText = getString(R.string.cancel);
+        setupAlert();
         Window window = getWindow();
         window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
     }