Merge "Latest UX for Tap & pay." into klp-dev
diff --git a/res/drawable-hdpi/nfc_payment_empty_state.png b/res/drawable-hdpi/nfc_payment_empty_state.png
index 69b22f2..300a053 100644
--- a/res/drawable-hdpi/nfc_payment_empty_state.png
+++ b/res/drawable-hdpi/nfc_payment_empty_state.png
Binary files differ
diff --git a/res/drawable-mdpi/nfc_payment_empty_state.png b/res/drawable-mdpi/nfc_payment_empty_state.png
index 1ab7187..28a1e31 100644
--- a/res/drawable-mdpi/nfc_payment_empty_state.png
+++ b/res/drawable-mdpi/nfc_payment_empty_state.png
Binary files differ
diff --git a/res/drawable-xhdpi/nfc_payment_empty_state.png b/res/drawable-xhdpi/nfc_payment_empty_state.png
index 3951c82..e664090 100644
--- a/res/drawable-xhdpi/nfc_payment_empty_state.png
+++ b/res/drawable-xhdpi/nfc_payment_empty_state.png
Binary files differ
diff --git a/res/drawable-xxhdpi/nfc_payment_empty_state.png b/res/drawable-xxhdpi/nfc_payment_empty_state.png
index 914021a..a861b79 100644
--- a/res/drawable-xxhdpi/nfc_payment_empty_state.png
+++ b/res/drawable-xxhdpi/nfc_payment_empty_state.png
Binary files differ
diff --git a/res/layout/nfc_payment.xml b/res/layout/nfc_payment.xml
index 92fe86f..54ac403 100644
--- a/res/layout/nfc_payment.xml
+++ b/res/layout/nfc_payment.xml
@@ -7,15 +7,6 @@
         android:layout_height="match_parent"
         android:gravity="center_vertical"
         android:orientation="vertical" >
-        <TextView
-            android:id="@+id/nfc_payment_empty_text"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:gravity="center"
-            android:textSize="24sp"
-            android:visibility="gone"
-            android:paddingBottom="16dp"
-            android:text="@string/nfc_payment_no_apps"/>
         <ImageView
             android:id="@+id/nfc_payment_tap_image"
             android:layout_width="fill_parent"
@@ -23,6 +14,15 @@
             android:gravity="center"
             android:visibility="gone"
             android:src="@drawable/nfc_payment_empty_state"/>
+        <TextView
+            android:id="@+id/nfc_payment_empty_text"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:textSize="24sp"
+            android:visibility="gone"
+            android:paddingTop="16dp"
+            android:text="@string/nfc_payment_no_apps"/>
     </LinearLayout>
     <ListView
         android:id="@android:id/list"
diff --git a/res/menu/nfc_payment_settings.xml b/res/menu/nfc_payment_settings.xml
new file mode 100644
index 0000000..f35374e
--- /dev/null
+++ b/res/menu/nfc_payment_settings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/nfc_payment_menu_item_add_service"
+        android:title="@string/nfc_payment_menu_item_add_service"
+        android:showAsAction="ifRoom">
+    </item>
+</menu>
diff --git a/res/values/donottranslate.xml b/res/values/donottranslate.xml
index 12697ce..3d12d7c 100644
--- a/res/values/donottranslate.xml
+++ b/res/values/donottranslate.xml
@@ -35,5 +35,7 @@
     </string-array>
     <!-- Default query string to search for a print service. -->
     <string name="download_print_service_query">market://search?q=print service</string>
+    <!-- Default query string to search for a NFC payment service. -->
+    <string name="download_nfc_payment_service_query">market://search?q=nfc payment</string>
 
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 370a811..099d787 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4755,14 +4755,15 @@
     <string name="global_font_change_title">Change font size</string>
 
     <!-- NFC payment settings --><skip/>
-    <string name="nfc_payment_settings_title">Payments</string>
+    <string name="nfc_payment_settings_title">Tap &amp; pay</string>
     <!-- String shown when there are no NFC payment applications installed -->
-    <string name="nfc_payment_no_apps">DO NOT TRANSLATE ME</string>
+    <string name="nfc_payment_no_apps">You have no apps configured for tap &amp; pay with NFC.</string>
+    <string name="nfc_payment_menu_item_add_service">Find apps</string>
     <!-- Label for the dialog that is shown when the user is asked to set a
          preferred payment application -->
     <string name="nfc_payment_set_default_label">Set as your preference?</string>
-    <string name="nfc_payment_set_default">Always use <xliff:g id="app">%1$s</xliff:g> when you tap and pay?</string>
-    <string name="nfc_payment_set_default_instead_of">Always use <xliff:g id="app">%1$s</xliff:g> instead of <xliff:g id="app">%2$s</xliff:g> when you tap and pay?</string>
+    <string name="nfc_payment_set_default">Always use <xliff:g id="app">%1$s</xliff:g> when you tap &amp; pay?</string>
+    <string name="nfc_payment_set_default_instead_of">Always use <xliff:g id="app">%1$s</xliff:g> instead of <xliff:g id="app">%2$s</xliff:g> when you tap &amp; pay?</string>
     <!-- Restrictions settings --><skip/>
 
     <!-- Restriction settings title [CHAR LIMIT=35] -->
diff --git a/src/com/android/settings/nfc/PaymentBackend.java b/src/com/android/settings/nfc/PaymentBackend.java
index 59f4ddf..f84bc74 100644
--- a/src/com/android/settings/nfc/PaymentBackend.java
+++ b/src/com/android/settings/nfc/PaymentBackend.java
@@ -61,8 +61,11 @@
 
         for (ApduServiceInfo service : serviceInfos) {
             PaymentAppInfo appInfo = new PaymentAppInfo();
-            appInfo.caption = service.loadLabel(pm);
             appInfo.banner = service.loadBanner(pm);
+            appInfo.caption = service.getDescription();
+            if (appInfo.caption == null) {
+                appInfo.caption = service.loadLabel(pm);
+            }
             appInfo.isDefault = service.getComponent().equals(defaultApp);
             appInfo.componentName = service.getComponent();
             appInfos.add(appInfo);
diff --git a/src/com/android/settings/nfc/PaymentDefaultDialog.java b/src/com/android/settings/nfc/PaymentDefaultDialog.java
index 538af2e..61c6fdb 100644
--- a/src/com/android/settings/nfc/PaymentDefaultDialog.java
+++ b/src/com/android/settings/nfc/PaymentDefaultDialog.java
@@ -21,8 +21,12 @@
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.nfc.cardemulation.ApduServiceInfo;
 import android.nfc.cardemulation.CardEmulation;
+import android.nfc.cardemulation.HostApduService;
+import android.nfc.cardemulation.OffHostApduService;
 import android.os.Bundle;
 import android.util.Log;
 
@@ -31,8 +35,11 @@
 import com.android.settings.R;
 import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
 
+import java.io.IOException;
 import java.util.List;
 
+import org.xmlpull.v1.XmlPullParserException;
+
 public final class PaymentDefaultDialog extends AlertActivity implements
         DialogInterface.OnClickListener {
 
@@ -81,17 +88,20 @@
         }
 
         // Check if passed in service exists
-        boolean found = false;
+        PaymentAppInfo requestedPaymentApp = null;
+        PaymentAppInfo defaultPaymentApp = null;
 
         List<PaymentAppInfo> services = mBackend.getPaymentAppInfos();
         for (PaymentAppInfo service : services) {
             if (component.equals(service.componentName)) {
-                found = true;
-                break;
+                requestedPaymentApp = service;
+            }
+            if (service.isDefault) {
+                defaultPaymentApp = service;
             }
         }
 
-        if (!found) {
+        if (requestedPaymentApp == null) {
             Log.e(TAG, "Component " + component + " is not a registered payment service.");
             return false;
         }
@@ -103,36 +113,18 @@
             return false;
         }
 
-        PackageManager pm = getPackageManager();
-        ApplicationInfo newAppInfo;
-        try {
-            newAppInfo = pm.getApplicationInfo(component.getPackageName(), 0);
-        } catch (NameNotFoundException e) {
-            Log.e(TAG, "PM could not load app info for " + component);
-            return false;
-        }
-        ApplicationInfo defaultAppInfo = null;
-        try {
-            if (defaultComponent != null) {
-                defaultAppInfo = pm.getApplicationInfo(defaultComponent.getPackageName(), 0);
-            }
-        } catch (NameNotFoundException e) {
-            Log.e(TAG, "PM could not load app info for " + defaultComponent);
-            // Continue intentionally
-        }
-
         mNewDefault = component;
-
         // Compose dialog; get
         final AlertController.AlertParams p = mAlertParams;
         p.mTitle = getString(R.string.nfc_payment_set_default_label);
-        if (defaultAppInfo == null) {
+        if (defaultPaymentApp == null) {
             String formatString = getString(R.string.nfc_payment_set_default);
-            String msg = String.format(formatString, newAppInfo.loadLabel(pm));
+            String msg = String.format(formatString, requestedPaymentApp.caption);
             p.mMessage = msg;
         } else {
             String formatString = getString(R.string.nfc_payment_set_default_instead_of);
-            String msg = String.format(formatString, newAppInfo.loadLabel(pm), defaultAppInfo.loadLabel(pm));
+            String msg = String.format(formatString, requestedPaymentApp.caption,
+                    defaultPaymentApp.caption);
             p.mMessage = msg;
         }
         p.mPositiveButtonText = getString(R.string.yes);
diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java
index d3ccbaf..f839b24 100644
--- a/src/com/android/settings/nfc/PaymentSettings.java
+++ b/src/com/android/settings/nfc/PaymentSettings.java
@@ -17,12 +17,19 @@
 package com.android.settings.nfc;
 
 import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
 import android.preference.Preference;
 import android.preference.PreferenceManager;
 import android.preference.PreferenceScreen;
 import android.util.Log;
 import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
@@ -30,6 +37,7 @@
 import android.widget.RadioButton;
 import android.widget.TextView;
 
+import com.android.internal.content.PackageMonitor;
 import com.android.settings.R;
 import com.android.settings.SettingsPreferenceFragment;
 import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
@@ -42,6 +50,8 @@
     private LayoutInflater mInflater;
     private PaymentBackend mPaymentBackend;
 
+    private final PackageMonitor mSettingsPackageMonitor = new SettingsPackageMonitor();
+
 
     @Override
     public void onCreate(Bundle icicle) {
@@ -50,12 +60,12 @@
         setHasOptionsMenu(false);
         mPaymentBackend = new PaymentBackend(getActivity());
         mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        setHasOptionsMenu(true);
     }
 
     public void refresh() {
         PreferenceManager manager = getPreferenceManager();
         PreferenceScreen screen = manager.createPreferenceScreen(getActivity());
-
         // Get all payment services
         List<PaymentAppInfo> appInfos = mPaymentBackend.getPaymentAppInfos();
         if (appInfos != null && appInfos.size() > 0) {
@@ -80,17 +90,15 @@
         } else {
             emptyText.setVisibility(View.GONE);
             emptyImage.setVisibility(View.GONE);
-            setPreferenceScreen(screen);
         }
+        setPreferenceScreen(screen);
     }
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
         super.onCreateView(inflater, container, savedInstanceState);
-
         View v = mInflater.inflate(R.layout.nfc_payment, container, false);
-
         return v;
     }
 
@@ -108,9 +116,54 @@
     @Override
     public void onResume() {
         super.onResume();
+        mSettingsPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
         refresh();
     }
 
+    @Override
+    public void onPause() {
+        mSettingsPackageMonitor.unregister();
+        super.onPause();
+    }
+
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.nfc_payment_settings, menu);
+        MenuItem menuItem = menu.findItem(R.id.nfc_payment_menu_item_add_service);
+        menuItem.setIntent(new Intent(Intent.ACTION_VIEW,
+                Uri.parse(getString(R.string.download_nfc_payment_service_query))));
+    }
+
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void dispatchMessage(Message msg) {
+            refresh();
+        }
+    };
+
+    private class SettingsPackageMonitor extends PackageMonitor {
+        @Override
+        public void onPackageAdded(String packageName, int uid) {
+           mHandler.obtainMessage().sendToTarget();
+        }
+
+        @Override
+        public void onPackageAppeared(String packageName, int reason) {
+            mHandler.obtainMessage().sendToTarget();
+        }
+
+        @Override
+        public void onPackageDisappeared(String packageName, int reason) {
+            mHandler.obtainMessage().sendToTarget();
+        }
+
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            mHandler.obtainMessage().sendToTarget();
+        }
+    }
+
     public static class PaymentAppPreference extends Preference {
         private final OnClickListener listener;
         private final PaymentAppInfo appInfo;