From d88e9aa575eb3a9d20cdb0e8918d54993e1ce1e0 Mon Sep 17 00:00:00 2001 From: Jeff Hamilton Date: Mon, 24 Jan 2011 14:53:00 -0600 Subject: [PATCH] Use classnames instead of ints for NFC techs. This makes the system more flexible and allows adding new technology types without having to update the API. Change-Id: Iaee6b633965e501a70e8afc3f1d54d9d94a4d05a --- api/current.xml | 19 ++---- core/java/android/nfc/INfcAdapter.aidl | 3 +- core/java/android/nfc/NfcAdapter.java | 12 +++- core/java/android/nfc/Tag.java | 57 ++++++++++++++-- core/java/android/nfc/TechListParcel.aidl | 19 ++++++ core/java/android/nfc/TechListParcel.java | 66 +++++++++++++++++++ .../android/nfc/tech/BasicTagTechnology.java | 33 ++-------- core/java/android/nfc/tech/Ndef.java | 2 +- core/java/android/nfc/tech/TagTechnology.java | 6 -- .../android/internal/app/ChooserActivity.java | 2 +- .../internal/app/ResolverActivity.java | 17 +++-- 11 files changed, 172 insertions(+), 64 deletions(-) create mode 100644 core/java/android/nfc/TechListParcel.aidl create mode 100644 core/java/android/nfc/TechListParcel.java diff --git a/api/current.xml b/api/current.xml index 66113d1da7366..aaae1ad62e2f9 100644 --- a/api/current.xml +++ b/api/current.xml @@ -100829,7 +100829,9 @@ - + + + - - - 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 946ac24ac2b94..aae75c97c67f6 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 @@ import java.util.Arrays; 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 @@ public class Tag implements Parcelable { } 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 @@ public class Tag implements Parcelable { 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 @@ public class Tag implements Parcelable { * 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 0000000000000..92e646f220f02 --- /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 0000000000000..396f0f12b7cfd --- /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 CREATOR = new Creator() { + @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 a9096312b919a..e635f21598c56 100644 --- a/core/java/android/nfc/tech/BasicTagTechnology.java +++ b/core/java/android/nfc/tech/BasicTagTechnology.java @@ -36,28 +36,10 @@ import java.io.IOException; /*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 @@ import java.io.IOException; /** 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. *

@@ -101,11 +78,12 @@ import java.io.IOException; @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 @@ import java.io.IOException; 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 03f2184666166..c6804f933bc67 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/core/java/android/nfc/tech/Ndef.java @@ -31,7 +31,7 @@ import java.io.IOException; /** * 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()} * *

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 1331bae7e758b..aebb3e8fd5369 100644 --- a/core/java/android/nfc/tech/TagTechnology.java +++ b/core/java/android/nfc/tech/TagTechnology.java @@ -88,12 +88,6 @@ public interface TagTechnology { */ 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. */ diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 9ed4dd826bd6f..7c40ab5d1945e 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -51,6 +51,6 @@ public class ChooserActivity extends ResolverActivity { 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 215e9aebc273d..841de062ddbf2 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -63,11 +63,12 @@ public class ResolverActivity extends AlertActivity implements 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 rList, + boolean alwaysUseOption) { super.onCreate(savedInstanceState); mPm = getPackageManager(); intent.setComponent(null); @@ -88,7 +89,7 @@ public class ResolverActivity extends AlertActivity implements 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 @@ public class ResolverActivity extends AlertActivity implements private List mList; public ResolveListAdapter(Context context, Intent intent, - Intent[] initialIntents) { + Intent[] initialIntents, List rList) { mIntent = new Intent(intent); mIntent.setComponent(null); mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - List 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