Merge "partially fix [3306150] HTML5 video with H/W acceleration blackout (DO NOT MERGE)" into gingerbread
diff --git a/api/current.xml b/api/current.xml
index 66113d1d..aaae1ad 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -100829,7 +100829,9 @@
 </parameter>
 <parameter name="intent" type="android.app.PendingIntent">
 </parameter>
-<parameter name="filters" type="android.content.IntentFilter...">
+<parameter name="filters" type="android.content.IntentFilter[]">
+</parameter>
+<parameter name="techLists" type="java.lang.String...">
 </parameter>
 </method>
 <method name="enableForegroundNdefPush"
@@ -101018,8 +101020,8 @@
  visibility="public"
 >
 </method>
-<method name="getTechnologyList"
- return="int[]"
+<method name="getTechList"
+ return="java.lang.String[]"
  abstract="false"
  native="false"
  synchronized="false"
@@ -101130,17 +101132,6 @@
  visibility="public"
 >
 </method>
-<method name="getTechnologyId"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="isConnected"
  return="boolean"
  abstract="false"
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index cfeff52..d439a48 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -21,6 +21,7 @@
 import android.content.IntentFilter;
 import android.nfc.NdefMessage;
 import android.nfc.Tag;
+import android.nfc.TechListParcel;
 import android.nfc.ILlcpSocket;
 import android.nfc.ILlcpServiceSocket;
 import android.nfc.ILlcpConnectionlessSocket;
@@ -48,7 +49,7 @@
     void localSet(in NdefMessage message);
     void openTagConnection(in Tag tag);
     void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
-        in IntentFilter[] filters);
+            in IntentFilter[] filters, in TechListParcel techLists);
     void disableForegroundDispatch(in ComponentName activity);
     void enableForegroundNdefPush(in ComponentName activity, in NdefMessage msg);
     void disableForegroundNdefPush(in ComponentName activity);
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index f38bed9..4808032 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -27,6 +27,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.os.IBinder;
+import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Log;
@@ -54,7 +55,7 @@
     /**
      * Intent to started when a tag is discovered. The data URI is formated as
      * {@code vnd.android.nfc://tag/} with the path having a directory entry for each technology
-     * in the {@link Tag#getTechnologyList()} is ascending order.
+     * in the {@link Tag#getTechList()} is sorted ascending order.
      *
      * This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before
      * {@link #ACTION_TAG_DISCOVERED}
@@ -426,7 +427,7 @@
      * @throws IllegalStateException
      */
     public void enableForegroundDispatch(Activity activity, PendingIntent intent,
-            IntentFilter... filters) {
+            IntentFilter[] filters, String[][] techLists) {
         if (activity == null || intent == null) {
             throw new NullPointerException();
         }
@@ -435,9 +436,14 @@
                     "when your activity is resumed");
         }
         try {
+            TechListParcel parcel = null;
+            if (techLists != null && techLists.length > 0) {
+                parcel = new TechListParcel(techLists);
+            }
             ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity,
                     mForegroundDispatchListener);
-            sService.enableForegroundDispatch(activity.getComponentName(), intent, filters);
+            sService.enableForegroundDispatch(activity.getComponentName(), intent, filters,
+                    parcel);
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
         }
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 946ac24..aae75c9 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -16,6 +16,15 @@
 
 package android.nfc;
 
+import android.nfc.tech.IsoDep;
+import android.nfc.tech.MifareClassic;
+import android.nfc.tech.MifareUltralight;
+import android.nfc.tech.Ndef;
+import android.nfc.tech.NdefFormatable;
+import android.nfc.tech.NfcA;
+import android.nfc.tech.NfcB;
+import android.nfc.tech.NfcF;
+import android.nfc.tech.NfcV;
 import android.nfc.tech.TagTechnology;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -49,6 +58,7 @@
 public class Tag implements Parcelable {
     /*package*/ final byte[] mId;
     /*package*/ final int[] mTechList;
+    /*package*/ final String[] mTechStringList;
     /*package*/ final Bundle[] mTechExtras;
     /*package*/ final int mServiceHandle;  // for use by NFC service, 0 indicates a mock
     /*package*/ final INfcTag mTagService;
@@ -66,6 +76,7 @@
         }
         mId = id;
         mTechList = Arrays.copyOf(techList, techList.length);
+        mTechStringList = generateTechStringList(techList);
         // Ensure mTechExtras is as long as mTechList
         mTechExtras = Arrays.copyOf(techListExtras, techList.length);
         mServiceHandle = serviceHandle;
@@ -88,6 +99,45 @@
         return new Tag(id, techList, techListExtras, 0, null);
     }
 
+    private String[] generateTechStringList(int[] techList) {
+        final int size = techList.length;
+        String[] strings = new String[size];
+        for (int i = 0; i < size; i++) {
+            switch (techList[i]) {
+                case TagTechnology.ISO_DEP:
+                    strings[i] = IsoDep.class.getName();
+                    break;
+                case TagTechnology.MIFARE_CLASSIC:
+                    strings[i] = MifareClassic.class.getName();
+                    break;
+                case TagTechnology.MIFARE_ULTRALIGHT:
+                    strings[i] = MifareUltralight.class.getName();
+                    break;
+                case TagTechnology.NDEF:
+                    strings[i] = Ndef.class.getName();
+                    break;
+                case TagTechnology.NDEF_FORMATABLE:
+                    strings[i] = NdefFormatable.class.getName();
+                    break;
+                case TagTechnology.NFC_A:
+                    strings[i] = NfcA.class.getName();
+                    break;
+                case TagTechnology.NFC_B:
+                    strings[i] = NfcB.class.getName();
+                    break;
+                case TagTechnology.NFC_F:
+                    strings[i] = NfcF.class.getName();
+                    break;
+                case TagTechnology.NFC_V:
+                    strings[i] = NfcV.class.getName();
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown tech type " + techList[i]);
+            }
+        }
+        return strings;
+    }
+
     /**
      * For use by NfcService only.
      * @hide
@@ -110,13 +160,12 @@
      * Returns technologies present in the tag that this implementation understands,
      * or a zero length array if there are no supported technologies on this tag.
      *
-     * The elements of the list are guaranteed be one of the constants defined in
-     * {@link TagTechnology}. 
+     * The elements of the list are the names of the classes implementing the technology. 
      *
      * The ordering of the returned array is undefined and should not be relied upon.
      */
-    public int[] getTechnologyList() { 
-        return Arrays.copyOf(mTechList, mTechList.length);
+    public String[] getTechList() {
+        return mTechStringList;
     }
 
     /** @hide */
diff --git a/core/java/android/nfc/TechListParcel.aidl b/core/java/android/nfc/TechListParcel.aidl
new file mode 100644
index 0000000..92e646f
--- /dev/null
+++ b/core/java/android/nfc/TechListParcel.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+package android.nfc;
+
+parcelable TechListParcel;
\ No newline at end of file
diff --git a/core/java/android/nfc/TechListParcel.java b/core/java/android/nfc/TechListParcel.java
new file mode 100644
index 0000000..396f0f1
--- /dev/null
+++ b/core/java/android/nfc/TechListParcel.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 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
+ */
+
+package android.nfc;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/** @hide */
+public class TechListParcel implements Parcelable {
+
+    private String[][] mTechLists;
+
+    public TechListParcel(String[]... strings) {
+        mTechLists = strings;
+    }
+
+    public String[][] getTechLists() {
+        return mTechLists;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        int count = mTechLists.length;
+        dest.writeInt(count);
+        for (int i = 0; i < count; i++) {
+            String[] techList = mTechLists[i];
+            dest.writeStringArray(techList);
+        }
+    }
+
+    public static final Creator<TechListParcel> CREATOR = new Creator<TechListParcel>() {
+        @Override
+        public TechListParcel createFromParcel(Parcel source) {
+            int count = source.readInt();
+            String[][] techLists = new String[count][];
+            for (int i = 0; i < count; i++) {
+                techLists[i] = source.readStringArray();
+            }
+            return new TechListParcel(techLists);
+        }
+
+        @Override
+        public TechListParcel[] newArray(int size) {
+            return new TechListParcel[size];
+        }
+    };
+}
diff --git a/core/java/android/nfc/tech/BasicTagTechnology.java b/core/java/android/nfc/tech/BasicTagTechnology.java
index a909631..e635f21 100644
--- a/core/java/android/nfc/tech/BasicTagTechnology.java
+++ b/core/java/android/nfc/tech/BasicTagTechnology.java
@@ -36,28 +36,10 @@
     /*package*/ int mSelectedTechnology;
 
     BasicTagTechnology(Tag tag, int tech) throws RemoteException {
-        int[] techList = tag.getTechnologyList();
-        int i;
-
-        // Check target validity
-        for (i = 0; i < techList.length; i++) {
-            if (tech == techList[i]) {
-                break;
-            }
-        }
-        if (i >= techList.length) {
-            // Technology not found
-            throw new IllegalArgumentException("Technology " + tech + " not present on tag " + tag);
-        }
-
         mTag = tag;
         mSelectedTechnology = tech;
     }
 
-    BasicTagTechnology(Tag tag) throws RemoteException {
-        this(tag, tag.getTechnologyList()[0]);
-    }
-
     @Override
     public Tag getTag() {
         return mTag;
@@ -65,17 +47,12 @@
 
     /** Internal helper to throw IllegalStateException if the technology isn't connected */
     void checkConnected() {
-       if ((mTag.getConnectedTechnology() != getTechnologyId()) ||
+       if ((mTag.getConnectedTechnology() != mSelectedTechnology) ||
                (mTag.getConnectedTechnology() == -1)) {
            throw new IllegalStateException("Call connect() first!");
        }
     }
 
-    @Override
-    public int getTechnologyId() {
-        return mSelectedTechnology;
-    }
-
     /**
      * Helper to indicate if {@link #connect} has succeeded.
      * <p>
@@ -101,11 +78,12 @@
     @Override
     public void connect() throws IOException {
         try {
-            int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(), getTechnologyId());
+            int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(),
+                    mSelectedTechnology);
 
             if (errorCode == ErrorCodes.SUCCESS) {
                 // Store this in the tag object
-                mTag.setConnectedTechnology(getTechnologyId());
+                mTag.setConnectedTechnology(mSelectedTechnology);
                 mIsConnected = true;
             } else {
                 throw new IOException();
@@ -158,7 +136,8 @@
         checkConnected();
 
         try {
-            TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(), data, raw);
+            TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(),
+                    data, raw);
             if (result == null) {
                 throw new IOException("transceive failed");
             } else {
diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java
index 03f2184..c6804f9 100644
--- a/core/java/android/nfc/tech/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -31,7 +31,7 @@
 /**
  * A high-level connection to a {@link Tag} using one of the NFC type 1, 2, 3, or 4 technologies
  * to interact with NDEF data. MiFare Classic cards that present NDEF data may also be used
- * via this class. To determine the exact technology being used call {@link #getTechnologyId()}
+ * via this class. To determine the exact technology being used call {@link #getType()}
  *
  * <p>You can acquire this kind of connection with {@link #get}.
  *
diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java
index 1331bae..aebb3e8 100644
--- a/core/java/android/nfc/tech/TagTechnology.java
+++ b/core/java/android/nfc/tech/TagTechnology.java
@@ -89,12 +89,6 @@
     public static final int MIFARE_ULTRALIGHT = 9;
 
     /**
-     * Returns the technology type for this tag connection.
-     * @hide
-     */
-    public int getTechnologyId();
-
-    /**
      * Get the {@link Tag} object this technology came from.
      */
     public Tag getTag();
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 9ed4dd8..7c40ab5 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -51,6 +51,6 @@
                 initialIntents[i] = (Intent)pa[i];
             }
         }
-        super.onCreate(savedInstanceState, target, title, initialIntents, false);
+        super.onCreate(savedInstanceState, target, title, initialIntents, null, false);
     }
 }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 215e9ae..841de06 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -63,11 +63,12 @@
     protected void onCreate(Bundle savedInstanceState) {
         onCreate(savedInstanceState, new Intent(getIntent()),
                 getResources().getText(com.android.internal.R.string.whichApplication),
-                null, true);
+                null, null, true);
     }
 
     protected void onCreate(Bundle savedInstanceState, Intent intent,
-            CharSequence title, Intent[] initialIntents, boolean alwaysUseOption) {
+            CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
+            boolean alwaysUseOption) {
         super.onCreate(savedInstanceState);
         mPm = getPackageManager();
         intent.setComponent(null);
@@ -88,7 +89,7 @@
                                                         com.android.internal.R.id.clearDefaultHint);
             mClearDefaultHint.setVisibility(View.GONE);
         }
-        mAdapter = new ResolveListAdapter(this, intent, initialIntents);
+        mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList);
         if (mAdapter.getCount() > 1) {
             ap.mAdapter = mAdapter;
         } else if (mAdapter.getCount() == 1) {
@@ -215,14 +216,16 @@
         private List<DisplayResolveInfo> mList;
 
         public ResolveListAdapter(Context context, Intent intent,
-                Intent[] initialIntents) {
+                Intent[] initialIntents, List<ResolveInfo> rList) {
             mIntent = new Intent(intent);
             mIntent.setComponent(null);
             mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
-            List<ResolveInfo> rList = mPm.queryIntentActivities(
-                    intent, PackageManager.MATCH_DEFAULT_ONLY
-                    | (mAlwaysCheck != null ? PackageManager.GET_RESOLVED_FILTER : 0));
+            if (rList == null) {
+                rList = mPm.queryIntentActivities(
+                        intent, PackageManager.MATCH_DEFAULT_ONLY
+                        | (mAlwaysCheck != null ? PackageManager.GET_RESOLVED_FILTER : 0));
+            }
             int N;
             if ((rList != null) && ((N = rList.size()) > 0)) {
                 // Only display the first matches that are either of equal