Merge "Use classnames instead of ints for NFC techs." into gingerbread

This commit is contained in:
Jeff Hamilton
2011-01-25 14:35:46 -08:00
committed by Android (Google) Code Review
11 changed files with 172 additions and 64 deletions

View File

@@ -100829,7 +100829,9 @@
</parameter> </parameter>
<parameter name="intent" type="android.app.PendingIntent"> <parameter name="intent" type="android.app.PendingIntent">
</parameter> </parameter>
<parameter name="filters" type="android.content.IntentFilter..."> <parameter name="filters" type="android.content.IntentFilter[]">
</parameter>
<parameter name="techLists" type="java.lang.String...">
</parameter> </parameter>
</method> </method>
<method name="enableForegroundNdefPush" <method name="enableForegroundNdefPush"
@@ -101018,8 +101020,8 @@
visibility="public" visibility="public"
> >
</method> </method>
<method name="getTechnologyList" <method name="getTechList"
return="int[]" return="java.lang.String[]"
abstract="false" abstract="false"
native="false" native="false"
synchronized="false" synchronized="false"
@@ -101130,17 +101132,6 @@
visibility="public" visibility="public"
> >
</method> </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" <method name="isConnected"
return="boolean" return="boolean"
abstract="false" abstract="false"

View File

@@ -21,6 +21,7 @@ import android.content.ComponentName;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.nfc.NdefMessage; import android.nfc.NdefMessage;
import android.nfc.Tag; import android.nfc.Tag;
import android.nfc.TechListParcel;
import android.nfc.ILlcpSocket; import android.nfc.ILlcpSocket;
import android.nfc.ILlcpServiceSocket; import android.nfc.ILlcpServiceSocket;
import android.nfc.ILlcpConnectionlessSocket; import android.nfc.ILlcpConnectionlessSocket;
@@ -48,7 +49,7 @@ interface INfcAdapter
void localSet(in NdefMessage message); void localSet(in NdefMessage message);
void openTagConnection(in Tag tag); void openTagConnection(in Tag tag);
void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent, void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
in IntentFilter[] filters); in IntentFilter[] filters, in TechListParcel techLists);
void disableForegroundDispatch(in ComponentName activity); void disableForegroundDispatch(in ComponentName activity);
void enableForegroundNdefPush(in ComponentName activity, in NdefMessage msg); void enableForegroundNdefPush(in ComponentName activity, in NdefMessage msg);
void disableForegroundNdefPush(in ComponentName activity); void disableForegroundNdefPush(in ComponentName activity);

View File

@@ -27,6 +27,7 @@ import android.content.IntentFilter;
import android.content.pm.IPackageManager; import android.content.pm.IPackageManager;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.IBinder; import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.util.Log; import android.util.Log;
@@ -54,7 +55,7 @@ public final class NfcAdapter {
/** /**
* Intent to started when a tag is discovered. The data URI is formated as * 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 * {@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 * This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before
* {@link #ACTION_TAG_DISCOVERED} * {@link #ACTION_TAG_DISCOVERED}
@@ -426,7 +427,7 @@ public final class NfcAdapter {
* @throws IllegalStateException * @throws IllegalStateException
*/ */
public void enableForegroundDispatch(Activity activity, PendingIntent intent, public void enableForegroundDispatch(Activity activity, PendingIntent intent,
IntentFilter... filters) { IntentFilter[] filters, String[][] techLists) {
if (activity == null || intent == null) { if (activity == null || intent == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
@@ -435,9 +436,14 @@ public final class NfcAdapter {
"when your activity is resumed"); "when your activity is resumed");
} }
try { try {
TechListParcel parcel = null;
if (techLists != null && techLists.length > 0) {
parcel = new TechListParcel(techLists);
}
ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity, ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity,
mForegroundDispatchListener); mForegroundDispatchListener);
sService.enableForegroundDispatch(activity.getComponentName(), intent, filters); sService.enableForegroundDispatch(activity.getComponentName(), intent, filters,
parcel);
} catch (RemoteException e) { } catch (RemoteException e) {
attemptDeadServiceRecovery(e); attemptDeadServiceRecovery(e);
} }

View File

@@ -16,6 +16,15 @@
package android.nfc; 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.nfc.tech.TagTechnology;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
@@ -49,6 +58,7 @@ import java.util.Arrays;
public class Tag implements Parcelable { public class Tag implements Parcelable {
/*package*/ final byte[] mId; /*package*/ final byte[] mId;
/*package*/ final int[] mTechList; /*package*/ final int[] mTechList;
/*package*/ final String[] mTechStringList;
/*package*/ final Bundle[] mTechExtras; /*package*/ final Bundle[] mTechExtras;
/*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock /*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock
/*package*/ final INfcTag mTagService; /*package*/ final INfcTag mTagService;
@@ -66,6 +76,7 @@ public class Tag implements Parcelable {
} }
mId = id; mId = id;
mTechList = Arrays.copyOf(techList, techList.length); mTechList = Arrays.copyOf(techList, techList.length);
mTechStringList = generateTechStringList(techList);
// Ensure mTechExtras is as long as mTechList // Ensure mTechExtras is as long as mTechList
mTechExtras = Arrays.copyOf(techListExtras, techList.length); mTechExtras = Arrays.copyOf(techListExtras, techList.length);
mServiceHandle = serviceHandle; mServiceHandle = serviceHandle;
@@ -88,6 +99,45 @@ public class Tag implements Parcelable {
return new Tag(id, techList, techListExtras, 0, null); 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. * For use by NfcService only.
* @hide * @hide
@@ -110,13 +160,12 @@ public class Tag implements Parcelable {
* Returns technologies present in the tag that this implementation understands, * Returns technologies present in the tag that this implementation understands,
* or a zero length array if there are no supported technologies on this tag. * 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 * The elements of the list are the names of the classes implementing the technology.
* {@link TagTechnology}.
* *
* The ordering of the returned array is undefined and should not be relied upon. * The ordering of the returned array is undefined and should not be relied upon.
*/ */
public int[] getTechnologyList() { public String[] getTechList() {
return Arrays.copyOf(mTechList, mTechList.length); return mTechStringList;
} }
/** @hide */ /** @hide */

View File

@@ -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;

View File

@@ -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];
}
};
}

View File

@@ -36,28 +36,10 @@ import java.io.IOException;
/*package*/ int mSelectedTechnology; /*package*/ int mSelectedTechnology;
BasicTagTechnology(Tag tag, int tech) throws RemoteException { 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; mTag = tag;
mSelectedTechnology = tech; mSelectedTechnology = tech;
} }
BasicTagTechnology(Tag tag) throws RemoteException {
this(tag, tag.getTechnologyList()[0]);
}
@Override @Override
public Tag getTag() { public Tag getTag() {
return mTag; return mTag;
@@ -65,17 +47,12 @@ import java.io.IOException;
/** Internal helper to throw IllegalStateException if the technology isn't connected */ /** Internal helper to throw IllegalStateException if the technology isn't connected */
void checkConnected() { void checkConnected() {
if ((mTag.getConnectedTechnology() != getTechnologyId()) || if ((mTag.getConnectedTechnology() != mSelectedTechnology) ||
(mTag.getConnectedTechnology() == -1)) { (mTag.getConnectedTechnology() == -1)) {
throw new IllegalStateException("Call connect() first!"); throw new IllegalStateException("Call connect() first!");
} }
} }
@Override
public int getTechnologyId() {
return mSelectedTechnology;
}
/** /**
* Helper to indicate if {@link #connect} has succeeded. * Helper to indicate if {@link #connect} has succeeded.
* <p> * <p>
@@ -101,11 +78,12 @@ import java.io.IOException;
@Override @Override
public void connect() throws IOException { public void connect() throws IOException {
try { try {
int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(), getTechnologyId()); int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(),
mSelectedTechnology);
if (errorCode == ErrorCodes.SUCCESS) { if (errorCode == ErrorCodes.SUCCESS) {
// Store this in the tag object // Store this in the tag object
mTag.setConnectedTechnology(getTechnologyId()); mTag.setConnectedTechnology(mSelectedTechnology);
mIsConnected = true; mIsConnected = true;
} else { } else {
throw new IOException(); throw new IOException();
@@ -158,7 +136,8 @@ import java.io.IOException;
checkConnected(); checkConnected();
try { try {
TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(), data, raw); TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(),
data, raw);
if (result == null) { if (result == null) {
throw new IOException("transceive failed"); throw new IOException("transceive failed");
} else { } else {

View File

@@ -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 * 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 * 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}. * <p>You can acquire this kind of connection with {@link #get}.
* *

View File

@@ -88,12 +88,6 @@ public interface TagTechnology {
*/ */
public static final int MIFARE_ULTRALIGHT = 9; 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. * Get the {@link Tag} object this technology came from.
*/ */

View File

@@ -51,6 +51,6 @@ public class ChooserActivity extends ResolverActivity {
initialIntents[i] = (Intent)pa[i]; initialIntents[i] = (Intent)pa[i];
} }
} }
super.onCreate(savedInstanceState, target, title, initialIntents, false); super.onCreate(savedInstanceState, target, title, initialIntents, null, false);
} }
} }

View File

@@ -63,11 +63,12 @@ public class ResolverActivity extends AlertActivity implements
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState, new Intent(getIntent()), onCreate(savedInstanceState, new Intent(getIntent()),
getResources().getText(com.android.internal.R.string.whichApplication), getResources().getText(com.android.internal.R.string.whichApplication),
null, true); null, null, true);
} }
protected void onCreate(Bundle savedInstanceState, Intent intent, 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); super.onCreate(savedInstanceState);
mPm = getPackageManager(); mPm = getPackageManager();
intent.setComponent(null); intent.setComponent(null);
@@ -88,7 +89,7 @@ public class ResolverActivity extends AlertActivity implements
com.android.internal.R.id.clearDefaultHint); com.android.internal.R.id.clearDefaultHint);
mClearDefaultHint.setVisibility(View.GONE); mClearDefaultHint.setVisibility(View.GONE);
} }
mAdapter = new ResolveListAdapter(this, intent, initialIntents); mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList);
if (mAdapter.getCount() > 1) { if (mAdapter.getCount() > 1) {
ap.mAdapter = mAdapter; ap.mAdapter = mAdapter;
} else if (mAdapter.getCount() == 1) { } else if (mAdapter.getCount() == 1) {
@@ -215,14 +216,16 @@ public class ResolverActivity extends AlertActivity implements
private List<DisplayResolveInfo> mList; private List<DisplayResolveInfo> mList;
public ResolveListAdapter(Context context, Intent intent, public ResolveListAdapter(Context context, Intent intent,
Intent[] initialIntents) { Intent[] initialIntents, List<ResolveInfo> rList) {
mIntent = new Intent(intent); mIntent = new Intent(intent);
mIntent.setComponent(null); mIntent.setComponent(null);
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
List<ResolveInfo> rList = mPm.queryIntentActivities( if (rList == null) {
intent, PackageManager.MATCH_DEFAULT_ONLY rList = mPm.queryIntentActivities(
| (mAlwaysCheck != null ? PackageManager.GET_RESOLVED_FILTER : 0)); intent, PackageManager.MATCH_DEFAULT_ONLY
| (mAlwaysCheck != null ? PackageManager.GET_RESOLVED_FILTER : 0));
}
int N; int N;
if ((rList != null) && ((N = rList.size()) > 0)) { if ((rList != null) && ((N = rList.size()) > 0)) {
// Only display the first matches that are either of equal // Only display the first matches that are either of equal