diff options
87 files changed, 1384 insertions, 602 deletions
@@ -119,11 +119,11 @@ LOCAL_SRC_FILES += \ core/java/android/nfc/ILlcpConnectionlessSocket.aidl \ core/java/android/nfc/ILlcpServiceSocket.aidl \ core/java/android/nfc/ILlcpSocket.aidl \ - core/java/android/nfc/INdefTag.aidl \ core/java/android/nfc/INfcAdapter.aidl \ core/java/android/nfc/INfcTag.aidl \ core/java/android/nfc/IP2pInitiator.aidl \ core/java/android/nfc/IP2pTarget.aidl \ + core/java/android/nfc/INfcSecureElement.aidl \ core/java/android/os/IHardwareService.aidl \ core/java/android/os/IMessenger.aidl \ core/java/android/os/INetworkManagementService.aidl \ @@ -252,7 +252,6 @@ aidl_files := \ frameworks/base/core/java/android/nfc/NdefMessage.aidl \ frameworks/base/core/java/android/nfc/NdefRecord.aidl \ frameworks/base/core/java/android/nfc/Tag.aidl \ - frameworks/base/core/java/android/nfc/NdefTag.aidl \ frameworks/base/core/java/android/os/Bundle.aidl \ frameworks/base/core/java/android/os/DropBoxManager.aidl \ frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \ diff --git a/CleanSpec.mk b/CleanSpec.mk index d19f3f8..2ee8f31 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -72,6 +72,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framew $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/trustedlogic) $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic) +$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/INdefTag.java) # ************************************************ # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java index 1b799ae..4a75514 100644 --- a/core/java/android/hardware/SensorManager.java +++ b/core/java/android/hardware/SensorManager.java @@ -1532,7 +1532,7 @@ public class SensorManager * </ul> * * <p> - * <center><img src="../../../images/axis_device_inverted.png" + * <center><img src="../../../images/axis_globe_inverted.png" * alt="Inverted world coordinate-system diagram." border="0" /></center> * </p> * <p> diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl index cd08e33..a663fb8 100644 --- a/core/java/android/nfc/INfcAdapter.aidl +++ b/core/java/android/nfc/INfcAdapter.aidl @@ -24,6 +24,7 @@ import android.nfc.ILlcpConnectionlessSocket; import android.nfc.INfcTag; import android.nfc.IP2pTarget; import android.nfc.IP2pInitiator; +import android.nfc.INfcSecureElement; /** * @hide @@ -36,9 +37,12 @@ interface INfcAdapter INfcTag getNfcTagInterface(); IP2pTarget getP2pTargetInterface(); IP2pInitiator getP2pInitiatorInterface(); + INfcSecureElement getNfcSecureElementInterface(); // NfcAdapter-class related methods boolean isEnabled(); + NdefMessage localGet(); + void localSet(in NdefMessage message); void openTagConnection(in Tag tag); // Non-public methods diff --git a/core/java/android/nfc/INdefTag.aidl b/core/java/android/nfc/INfcSecureElement.aidl index d131ebe..aa98dd2 100644..100755 --- a/core/java/android/nfc/INdefTag.aidl +++ b/core/java/android/nfc/INfcSecureElement.aidl @@ -16,13 +16,13 @@ package android.nfc; -import android.nfc.NdefMessage; - /** - * @hide + * {@hide} */ -interface INdefTag -{ - NdefMessage read(int nativeHandle); - boolean write(int nativeHandle, in NdefMessage msg); +interface INfcSecureElement { + int openSecureElementConnection(); + int closeSecureElementConnection(int nativeHandle); + byte[] exchangeAPDU(int nativeHandle, in byte[] data); + int[] getSecureElementTechList(int nativeHandle); + byte[] getSecureElementUid(int nativeHandle); }
\ No newline at end of file diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl index 13b97d6..ad3c1bb 100644 --- a/core/java/android/nfc/INfcTag.aidl +++ b/core/java/android/nfc/INfcTag.aidl @@ -25,7 +25,7 @@ interface INfcTag { int close(int nativeHandle); int connect(int nativeHandle); - String getType(int nativeHandle); + int[] getTechList(int nativeHandle); byte[] getUid(int nativeHandle); boolean isNdef(int nativeHandle); boolean isPresent(int nativeHandle); diff --git a/core/java/android/nfc/NdefTag.aidl b/core/java/android/nfc/NdefTag.aidl deleted file mode 100644 index 288f667..0000000 --- a/core/java/android/nfc/NdefTag.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2010 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 NdefTag;
\ No newline at end of file diff --git a/core/java/android/nfc/NdefTag.java b/core/java/android/nfc/NdefTag.java deleted file mode 100644 index eb9d0dc..0000000 --- a/core/java/android/nfc/NdefTag.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2010 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; - -/** - * Represents a discovered tag that contains {@link NdefMessage}s (or a tag that can store them). - * In practice, a tag is a thing that an NFC-enabled device can communicate with. This - * class is a representation of such a tag and can contain the NDEF messages shared by the tag. - * <p>An NDEF tag can contain zero or more NDEF messages (represented by {@link NdefMessage} - * objects) in addition to the basic tag properties of UID and Type. - * <p> - * {@link NdefTag}s that have been initialized will usually contain a single {@link NdefMessage} - * (and that Message can contain multiple {@link NdefRecord}s). However it - * is possible for {@link NdefTag}s to contain multiple {@link NdefMessage}s. - * <p>{@link NfcAdapter#createNdefTagConnection createNdefTagConnection()} can be used to modify the - * contents of some tags. - * <p>This is an immutable data class. All properties are set at Tag discovery - * time and calls on this class will retrieve those read-only properties, and - * not cause any further RF activity or block. Note however that arrays passed to and - * returned by this class are *not* cloned, so be careful not to modify them. - * @hide - */ -public class NdefTag extends Tag implements Parcelable { - /** - * Target for NFC Forum Type 1 compliant tag. - * <p>This is based on Jewel/Topaz technology - */ - public static final String TARGET_TYPE_1 = "type_1"; - - /** - * Target for NFC Forum Type 2 compliant tag. - * <p>This is based on Mifare Ultralight technology. - */ - public static final String TARGET_TYPE_2 = "type_2"; - - /** - * Target for NFC Forum Type 3 compliant tag. - * <p>This is based on Felica technology. - */ - public static final String TARGET_TYPE_3 = "type_3"; - - /** - * Target for NFC Forum Type 4 compliant tag. - * <p>This is based on Mifare Desfire technology. - */ - public static final String TARGET_TYPE_4 = "type_4"; - - /** - * Target for NFC Forum Enabled: Mifare Classic tag. - * <p>This is not strictly a NFC Forum tag type, but is a common - * NDEF message container. - */ - public static final String TARGET_MIFARE_CLASSIC = "type_mifare_classic"; - - /** - * Any other target. - */ - public static final String TARGET_OTHER = "other"; - - private final String[] mNdefTargets; - private final NdefMessage[][] mMessages; // one NdefMessage[] per NDEF target - private NdefMessage[] mFlatMessages; // collapsed mMessages, built lazily, protected by (this) - - /** - * Hidden constructor to be used by NFC service only. - * @hide - */ - public NdefTag(byte[] id, String[] rawTargets, byte[] pollBytes, byte[] activationBytes, - int serviceHandle, String[] ndefTargets, NdefMessage[][] messages) { - super(id, true, rawTargets, pollBytes, activationBytes, serviceHandle); - if (ndefTargets == null || messages == null) { - throw new IllegalArgumentException("ndefTargets or messages cannot be null"); - } - if (ndefTargets.length != messages.length){ - throw new IllegalArgumentException("ndefTargets and messages arrays must match"); - } - for (NdefMessage[] ms : messages) { - if (ms == null) { - throw new IllegalArgumentException("messages elements cannot be null"); - } - } - mNdefTargets = ndefTargets; - mMessages = messages; - } - - /** - * Construct a mock NdefTag. - * <p>This is an application constructed tag, so NfcAdapter methods on this - * Tag such as {@link NfcAdapter#createRawTagConnection} will fail with - * {@link IllegalArgumentException} since it does not represent a physical Tag. - * <p>This constructor might be useful for mock testing. - * @param id The tag identifier, can be null - * @param rawTargets must not be null - * @param pollBytes can be null - * @param activationBytes can be null - * @param ndefTargets NDEF target array, such as {TARGET_TYPE_2}, cannot be null - * @param messages messages, one array per NDEF target, cannot be null - * @return freshly constructed NdefTag - */ - public static NdefTag createMockNdefTag(byte[] id, String[] rawTargets, byte[] pollBytes, - byte[] activationBytes, String[] ndefTargets, NdefMessage[][] messages) { - // set serviceHandle to 0 to indicate mock tag - return new NdefTag(id, rawTargets, pollBytes, activationBytes, 0, ndefTargets, messages); - } - - /** - * Get all NDEF Messages. - * <p> - * This retrieves the NDEF Messages that were found on the Tag at discovery - * time. It does not cause any further RF activity, and does not block. - * <p> - * Most tags only contain a single NDEF message. - * - * @return NDEF Messages found at Tag discovery - */ - public NdefMessage[] getNdefMessages() { - // common-case optimization - if (mMessages.length == 1) { - return mMessages[0]; - } - - // return cached flat array - synchronized(this) { - if (mFlatMessages != null) { - return mFlatMessages; - } - // not cached - build a flat array - int sz = 0; - for (NdefMessage[] ms : mMessages) { - sz += ms.length; - } - mFlatMessages = new NdefMessage[sz]; - int i = 0; - for (NdefMessage[] ms : mMessages) { - System.arraycopy(ms, 0, mFlatMessages, i, ms.length); - i += ms.length; - } - return mFlatMessages; - } - } - - /** - * Get only the NDEF Messages from a single NDEF target on a tag. - * <p> - * This retrieves the NDEF Messages that were found on the Tag at discovery - * time. It does not cause any further RF activity, and does not block. - * <p> - * Most tags only contain a single NDEF message. - * - * @param target one of targets strings provided by getNdefTargets() - * @return NDEF Messages found at Tag discovery - */ - public NdefMessage[] getNdefMessages(String target) { - for (int i=0; i<mNdefTargets.length; i++) { - if (target.equals(mNdefTargets[i])) { - return mMessages[i]; - } - } - throw new IllegalArgumentException("target (" + target + ") not found"); - } - - /** - * Return the NDEF targets on this Tag that support NDEF messages. - * - * @return - */ - public String[] getNdefTargets() { - return mNdefTargets; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - // Tag fields - dest.writeInt(mIsNdef ? 1 : 0); - writeBytesWithNull(dest, mId); - dest.writeInt(mRawTargets.length); - dest.writeStringArray(mRawTargets); - writeBytesWithNull(dest, mPollBytes); - writeBytesWithNull(dest, mActivationBytes); - dest.writeInt(mServiceHandle); - - // NdefTag fields - dest.writeInt(mNdefTargets.length); - dest.writeStringArray(mNdefTargets); - dest.writeInt(mMessages.length); - for (NdefMessage[] ms : mMessages) { - dest.writeInt(ms.length); - dest.writeTypedArray(ms, flags); - } - } - - public static final Parcelable.Creator<NdefTag> CREATOR = - new Parcelable.Creator<NdefTag>() { - public NdefTag createFromParcel(Parcel in) { - boolean isNdef = (in.readInt() == 1); - if (!isNdef) { - throw new IllegalArgumentException("Creating NdefTag from Tag parcel"); - } - - // Tag fields - byte[] id = readBytesWithNull(in); - String[] rawTargets = new String[in.readInt()]; - in.readStringArray(rawTargets); - byte[] pollBytes = readBytesWithNull(in); - byte[] activationBytes = readBytesWithNull(in); - int serviceHandle = in.readInt(); - - // NdefTag fields - String[] ndefTargets = new String[in.readInt()]; - in.readStringArray(ndefTargets); - NdefMessage[][] messages = new NdefMessage[in.readInt()][]; - for (int i=0; i<messages.length; i++) { - messages[i] = new NdefMessage[in.readInt()]; - in.readTypedArray(messages[i], NdefMessage.CREATOR); - } - return new NdefTag(id, rawTargets, pollBytes, activationBytes, serviceHandle, - ndefTargets, messages); - } - public NdefTag[] newArray(int size) { - return new NdefTag[size]; - } - }; -}
\ No newline at end of file diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index 88b6ea4..a1c22bf 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -1,25 +1,26 @@ /* - * Copyright (C) 2010 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. + * Copyright (C) 2010 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 java.lang.UnsupportedOperationException; - import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.ActivityThread; -import android.content.Context; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; -import android.nfc.INfcAdapter; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; @@ -40,6 +41,12 @@ public final class NfcAdapter { public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED"; /** + * Broadcast to only the activity that handles ACTION_TAG_DISCOVERED + * @hide + */ + public static final String ACTION_TAG_LEFT_FIELD = "android.nfc.action.TAG_LOST"; + + /** * Mandatory Tag extra for the ACTION_TAG intents. * @hide */ @@ -170,6 +177,14 @@ public final class NfcAdapter { } /** + * Returns the binder interface to the service. + * @hide + */ + public INfcAdapter getService() { + return mService; + } + + /** * Helper to check if this device has FEATURE_NFC, but without using * a context. * Equivalent to @@ -230,8 +245,11 @@ public final class NfcAdapter { } } - /** NFC service dead - attempt best effort recovery */ - /*package*/ void attemptDeadServiceRecovery(Exception e) { + /** + * NFC service dead - attempt best effort recovery + * @hide + */ + public void attemptDeadServiceRecovery(Exception e) { Log.e(TAG, "NFC service dead - attempting to recover", e); INfcAdapter service = getServiceInterface(); if (service == null) { @@ -301,50 +319,41 @@ public final class NfcAdapter { } /** - * Create a raw tag connection to the default Target - * <p>Requires {@link android.Manifest.permission#NFC} permission. - * @hide - */ - public RawTagConnection createRawTagConnection(Tag tag) { - if (tag.mServiceHandle == 0) { - throw new IllegalArgumentException("mock tag cannot be used for connections"); - } - try { - return new RawTagConnection(this, tag); - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - return null; - } - } - - /** - * Create a raw tag connection to the specified Target + * Set the NDEF Message that this NFC adapter should appear as to Tag + * readers. + * <p> + * Any Tag reader can read the contents of the local tag when it is in + * proximity, without any further user confirmation. + * <p> + * The implementation of this method must either + * <ul> + * <li>act as a passive tag containing this NDEF message + * <li>provide the NDEF message on over LLCP to peer NFC adapters + * </ul> + * The NDEF message is preserved across reboot. * <p>Requires {@link android.Manifest.permission#NFC} permission. + * + * @param message NDEF message to make public * @hide */ - public RawTagConnection createRawTagConnection(Tag tag, String target) { - if (tag.mServiceHandle == 0) { - throw new IllegalArgumentException("mock tag cannot be used for connections"); - } + public void setLocalNdefMessage(NdefMessage message) { try { - return new RawTagConnection(this, tag, target); + mService.localSet(message); } catch (RemoteException e) { attemptDeadServiceRecovery(e); - return null; } } /** - * Create an NDEF tag connection to the default Target + * Get the NDEF Message that this adapter appears as to Tag readers. * <p>Requires {@link android.Manifest.permission#NFC} permission. + * + * @return NDEF Message that is publicly readable * @hide */ - public NdefTagConnection createNdefTagConnection(NdefTag tag) { - if (tag.mServiceHandle == 0) { - throw new IllegalArgumentException("mock tag cannot be used for connections"); - } + public NdefMessage getLocalNdefMessage() { try { - return new NdefTagConnection(this, tag); + return mService.localGet(); } catch (RemoteException e) { attemptDeadServiceRecovery(e); return null; @@ -352,18 +361,14 @@ public final class NfcAdapter { } /** - * Create an NDEF tag connection to the specified Target - * <p>Requires {@link android.Manifest.permission#NFC} permission. + * Create an Nfc Secure Element Connection * @hide */ - public NdefTagConnection createNdefTagConnection(NdefTag tag, String target) { - if (tag.mServiceHandle == 0) { - throw new IllegalArgumentException("mock tag cannot be used for connections"); - } + public NfcSecureElement createNfcSecureElementConnection() { try { - return new NdefTagConnection(this, tag, target); + return new NfcSecureElement(mService.getNfcSecureElementInterface()); } catch (RemoteException e) { - attemptDeadServiceRecovery(e); + Log.e(TAG, "createNfcSecureElementConnection failed", e); return null; } } diff --git a/core/java/android/nfc/NfcSecureElement.java b/core/java/android/nfc/NfcSecureElement.java new file mode 100755 index 0000000..5f4c066 --- /dev/null +++ b/core/java/android/nfc/NfcSecureElement.java @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2010 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.nfc.technology.TagTechnology; +import android.os.RemoteException; +import android.util.Log; + +import java.io.IOException; + +//import android.util.Log; + +/** + * This class provides the primary API for managing all aspects Secure Element. + * Get an instance of this class by calling + * Context.getSystemService(Context.NFC_SERVICE). + * @hide + */ +public final class NfcSecureElement { + + private static final String TAG = "NfcSecureElement"; + + private INfcSecureElement mService; + + + /** + * @hide + */ + public NfcSecureElement(INfcSecureElement mSecureElementService) { + mService = mSecureElementService; + } + + public int openSecureElementConnection(String seType) throws IOException { + if (seType.equals("SmartMX")) { + try { + int handle = mService.openSecureElementConnection(); + // Handle potential errors + if (handle != 0) { + return handle; + } else { + throw new IOException("SmartMX connection not allowed"); + } + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in openSecureElementConnection(): ", e); + return 0; + } + + } else if (seType.equals("UICC")) { + return 0; + } else { + throw new IOException("Wrong Secure Element type"); + } + } + + + public byte [] exchangeAPDU(int handle,byte [] data) throws IOException { + + + // Perform exchange APDU + try { + byte[] response = mService.exchangeAPDU(handle, data); + // Handle potential errors + if (response == null) { + throw new IOException("Exchange APDU failed"); + } + return response; + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in exchangeAPDU(): ", e); + return null; + } + } + + public void closeSecureElementConnection(int handle) throws IOException { + + try { + int status = mService.closeSecureElementConnection(handle); + // Handle potential errors + if (ErrorCodes.isError(status)) { + throw new IOException("Error during the conection close"); + }; + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in closeSecureElement(): ", e); + } + } + + + /** + * Returns target type. constants. + * + * @return Secure Element technology type. The possible values are defined in + * {@link TagTechnology} + * + */ + public int[] getSecureElementTechList(int handle) throws IOException { + try { + return mService.getSecureElementTechList(handle); + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in getType(): ", e); + return null; + } + } + + /** + * Returns Secure Element UID. + * + * @return Secure Element UID. + */ + public byte[] getSecureElementUid(int handle) throws IOException { + + byte[] uid = null; + try { + uid = mService.getSecureElementUid(handle); + // Handle potential errors + if (uid == null) { + throw new IOException("Get Secure Element UID failed"); + } + return uid; + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in getType(): ", e); + return null; + } + } + +} diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index 5d0b04c..2f6b3a5 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -16,8 +16,21 @@ package android.nfc; +import android.nfc.technology.IsoDep; +import android.nfc.technology.MifareClassic; +import android.nfc.technology.MifareUltralight; +import android.nfc.technology.NfcV; +import android.nfc.technology.Ndef; +import android.nfc.technology.NfcA; +import android.nfc.technology.NfcB; +import android.nfc.technology.NfcF; +import android.nfc.technology.TagTechnology; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import android.os.RemoteException; + +import java.util.Arrays; /** * Represents a (generic) discovered tag. @@ -30,13 +43,13 @@ import android.os.Parcelable; * {@link Tag} objects are passed to applications via the {@link NfcAdapter#EXTRA_TAG} extra * in {@link NfcAdapter#ACTION_TAG_DISCOVERED} intents. A {@link Tag} object is immutable * and represents the state of the tag at the time of discovery. It can be - * directly queried for its UID and Type, or used to create a {@link RawTagConnection} - * (with {@link NfcAdapter#createRawTagConnection createRawTagConnection()}). + * directly queried for its UID and Type, or used to create a {@link TagTechnology} + * (with {@link Tag#getTechnology(int)}). * <p> - * A {@link Tag} can be used to create a {@link RawTagConnection} only while the tag is in + * A {@link Tag} can be used to create a {@link TagTechnology} only while the tag is in * range. If it is removed and then returned to range, then the most recent * {@link Tag} object (in {@link NfcAdapter#ACTION_TAG_DISCOVERED}) should be used to create a - * {@link RawTagConnection}. + * {@link TagTechnology}. * <p>This is an immutable data class. All properties are set at Tag discovery * time and calls on this class will retrieve those read-only properties, and * not cause any further RF activity or block. Note however that arrays passed to and @@ -44,78 +57,39 @@ import android.os.Parcelable; * @hide */ public class Tag implements Parcelable { - /** - * ISO 14443-3A technology. - * <p> - * Includes Topaz (which is -3A compatible) - */ - public static final String TARGET_ISO_14443_3A = "iso14443_3a"; - - /** - * ISO 14443-3B technology. - */ - public static final String TARGET_ISO_14443_3B = "iso14443_3b"; - - /** - * ISO 14443-4 technology. - */ - public static final String TARGET_ISO_14443_4 = "iso14443_4"; - - /** - * ISO 15693 technology, commonly known as RFID. - */ - public static final String TARGET_ISO_15693 = "iso15693"; - - /** - * JIS X-6319-4 technology, commonly known as Felica. - */ - public static final String TARGET_JIS_X_6319_4 = "jis_x_6319_4"; - - /** - * Any other technology. - */ - public static final String TARGET_OTHER = "other"; - - /*package*/ final boolean mIsNdef; /*package*/ final byte[] mId; - /*package*/ final String[] mRawTargets; - /*package*/ final byte[] mPollBytes; - /*package*/ final byte[] mActivationBytes; + /*package*/ final int[] mTechList; + /*package*/ final Bundle[] mTechExtras; /*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock /** * Hidden constructor to be used by NFC service and internal classes. * @hide */ - public Tag(byte[] id, boolean isNdef, String[] rawTargets, byte[] pollBytes, - byte[] activationBytes, int serviceHandle) { - if (rawTargets == null) { + public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle) { + if (techList == null) { throw new IllegalArgumentException("rawTargets cannot be null"); } - mIsNdef = isNdef; mId = id; - mRawTargets = rawTargets; - mPollBytes = pollBytes; - mActivationBytes = activationBytes; + mTechList = Arrays.copyOf(techList, techList.length); + // Ensure mTechExtras is as long as mTechList + mTechExtras = Arrays.copyOf(techListExtras, techList.length); mServiceHandle = serviceHandle; } /** * Construct a mock Tag. * <p>This is an application constructed tag, so NfcAdapter methods on this - * Tag such as {@link NfcAdapter#createRawTagConnection} will fail with + * Tag such as {@link #getTechnology} may fail with * {@link IllegalArgumentException} since it does not represent a physical Tag. * <p>This constructor might be useful for mock testing. * @param id The tag identifier, can be null - * @param rawTargets must not be null - * @param pollBytes can be null - * @param activationBytes can be null + * @param techList must not be null * @return freshly constructed tag */ - public static Tag createMockTag(byte[] id, String[] rawTargets, byte[] pollBytes, - byte[] activationBytes) { + public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) { // set serviceHandle to 0 to indicate mock tag - return new Tag(id, false, rawTargets, pollBytes, activationBytes, 0); + return new Tag(id, techList, techListExtras, 0); } /** @@ -127,16 +101,6 @@ public class Tag implements Parcelable { } /** - * Return the available targets that this NFC adapter can use to create - * a RawTagConnection. - * - * @return raw targets, will not be null - */ - public String[] getRawTargets() { - return mRawTargets; - } - - /** * Get the Tag Identifier (if it has one). * <p>Tag ID is usually a serial number for the tag. * @@ -147,37 +111,69 @@ public class Tag implements Parcelable { } /** - * Get the low-level bytes returned by this Tag at poll-time. - * <p>These can be used to help with advanced identification of a Tag. - * <p>The meaning of these bytes depends on the Tag technology. - * <p>ISO14443-3A: ATQA/SENS_RES - * <p>ISO14443-3B: Application data (4 bytes) and Protocol Info (3 bytes) from ATQB/SENSB_RES - * <p>JIS_X_6319_4: PAD0 (2 byte), PAD1 (2 byte), MRTI(2 byte), PAD2 (1 byte), RC (2 byte) - * <p>ISO15693: response flags (1 byte), DSFID (1 byte) - * from SENSF_RES + * Returns technologies present in the tag that this implementation understands, + * or a zero length array if there are no supported technologies on this tag. * - * @return poll bytes, or null if they do not exist for this Tag technology - * @hide + * The elements of the list are guaranteed be one of the constants defined in + * {@link TagTechnology}. + * + * The ordering of the returned array is undefined and should not be relied upon. */ - public byte[] getPollBytes() { - return mPollBytes; + public int[] getTechnologyList() { + return Arrays.copyOf(mTechList, mTechList.length); } /** - * Get the low-level bytes returned by this Tag at activation-time. - * <p>These can be used to help with advanced identification of a Tag. - * <p>The meaning of these bytes depends on the Tag technology. - * <p>ISO14443-3A: SAK/SEL_RES - * <p>ISO14443-3B: null - * <p>ISO14443-3A & ISO14443-4: SAK/SEL_RES, historical bytes from ATS <TODO: confirm> - * <p>ISO14443-3B & ISO14443-4: ATTRIB response - * <p>JIS_X_6319_4: null - * <p>ISO15693: response flags (1 byte), DSFID (1 byte): null - * @return activation bytes, or null if they do not exist for this Tag technology - * @hide + * Returns the technology, or null if not present */ - public byte[] getActivationBytes() { - return mActivationBytes; + public TagTechnology getTechnology(int tech) { + int pos = -1; + for (int idx = 0; idx < mTechList.length; idx++) { + if (mTechList[idx] == tech) { + pos = idx; + break; + } + } + if (pos < 0) { + return null; + } + + Bundle extras = mTechExtras[pos]; + NfcAdapter adapter = NfcAdapter.getDefaultAdapter(); + try { + switch (tech) { + case TagTechnology.NFC_A: { + return new NfcA(adapter, this, extras); + } + case TagTechnology.NFC_B: { + return new NfcB(adapter, this, extras); + } + case TagTechnology.ISO_DEP: { + return new IsoDep(adapter, this, extras); + } + case TagTechnology.NFC_V: { + return new NfcV(adapter, this, extras); + } + case TagTechnology.NDEF: { + return new Ndef(adapter, this, tech, extras); + } + case TagTechnology.NFC_F: { + return new NfcF(adapter, this, extras); + } + case TagTechnology.MIFARE_CLASSIC: { + return new MifareClassic(adapter, this, extras); + } + case TagTechnology.MIFARE_ULTRALIGHT: { + return new MifareUltralight(adapter, this, extras); + } + + default: { + throw new UnsupportedOperationException("Tech " + tech + " not supported"); + } + } + } catch (RemoteException e) { + return null; + } } @Override @@ -185,13 +181,9 @@ public class Tag implements Parcelable { StringBuilder sb = new StringBuilder("TAG ") .append("uid = ") .append(mId) - .append(" poll ") - .append(mPollBytes) - .append(" activation ") - .append(mActivationBytes) - .append(" Raw ["); - for (String s : mRawTargets) { - sb.append(s) + .append(" Tech ["); + for (int i : mTechList) { + sb.append(i) .append(", "); } return sb.toString(); @@ -221,37 +213,32 @@ public class Tag implements Parcelable { return 0; } - @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mIsNdef ? 1 : 0); writeBytesWithNull(dest, mId); - dest.writeInt(mRawTargets.length); - dest.writeStringArray(mRawTargets); - writeBytesWithNull(dest, mPollBytes); - writeBytesWithNull(dest, mActivationBytes); + dest.writeInt(mTechList.length); + dest.writeIntArray(mTechList); + dest.writeTypedArray(mTechExtras, 0); dest.writeInt(mServiceHandle); } public static final Parcelable.Creator<Tag> CREATOR = new Parcelable.Creator<Tag>() { + @Override public Tag createFromParcel(Parcel in) { - boolean isNdef = (in.readInt() == 1); - if (isNdef) { - throw new IllegalArgumentException("Creating Tag from NdefTag parcel"); - } // Tag fields byte[] id = Tag.readBytesWithNull(in); - String[] rawTargets = new String[in.readInt()]; - in.readStringArray(rawTargets); - byte[] pollBytes = Tag.readBytesWithNull(in); - byte[] activationBytes = Tag.readBytesWithNull(in); + int[] techList = new int[in.readInt()]; + in.readIntArray(techList); + Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR); int serviceHandle = in.readInt(); - return new Tag(id, isNdef, rawTargets, pollBytes, activationBytes, serviceHandle); + return new Tag(id, techList, techExtras, serviceHandle); } + + @Override public Tag[] newArray(int size) { return new Tag[size]; } }; -}
\ No newline at end of file +} diff --git a/core/java/android/nfc/RawTagConnection.java b/core/java/android/nfc/technology/BasicTagTechnology.java index bfdaa77..6b281b9 100644 --- a/core/java/android/nfc/RawTagConnection.java +++ b/core/java/android/nfc/technology/BasicTagTechnology.java @@ -14,31 +14,25 @@ * limitations under the License. */ -package android.nfc; +package android.nfc.technology; import java.io.IOException; +import android.nfc.INfcAdapter; +import android.nfc.INfcTag; +import android.nfc.NfcAdapter; +import android.nfc.Tag; import android.os.RemoteException; import android.util.Log; /** - * A low-level connection to a {@link Tag} target. - * <p>You can acquire this kind of connection with {@link NfcAdapter#createRawTagConnection - * createRawTagConnection()}. Use the connection to send and receive data with {@link #transceive - * transceive()}. - * <p> - * Applications must implement their own protocol stack on top of {@link #transceive transceive()}. - * - * <p class="note"><strong>Note:</strong> - * Use of this class requires the {@link android.Manifest.permission#NFC} - * permission. - * @hide + * A base class for tag technologies that are built on top of transceive(). */ -public class RawTagConnection { +/* package */ abstract class BasicTagTechnology implements TagTechnology { /*package*/ final Tag mTag; /*package*/ boolean mIsConnected; - /*package*/ String mSelectedTarget; + /*package*/ int mSelectedTechnology; private final NfcAdapter mAdapter; // Following fields are final after construction, except for @@ -49,30 +43,40 @@ public class RawTagConnection { private static final String TAG = "NFC"; - /*package*/ RawTagConnection(NfcAdapter adapter, Tag tag, String target) throws RemoteException { - String[] targets = tag.getRawTargets(); + /** + * @hide + */ + public BasicTagTechnology(NfcAdapter adapter, Tag tag, int tech) throws RemoteException { + int[] techList = tag.getTechnologyList(); int i; // Check target validity - for (i=0;i<targets.length;i++) { - if (target.equals(targets[i])) { + for (i = 0; i < techList.length; i++) { + if (tech == techList[i]) { break; } } - if (i >= targets.length) { - // Target not found - throw new IllegalArgumentException(); + if (i >= techList.length) { + // Technology not found + throw new IllegalArgumentException("Technology " + tech + " not present on tag " + tag); } mAdapter = adapter; - mService = mAdapter.mService; - mTagService = mService.getNfcTagInterface(); + mService = mAdapter.getService(); + try { + mTagService = mService.getNfcTagInterface(); + } catch (RemoteException e) { + attemptDeadServiceRecovery(e); + } mTag = tag; - mSelectedTarget = target; + mSelectedTechnology = tech; } - /*package*/ RawTagConnection(NfcAdapter adapter, Tag tag) throws RemoteException { - this(adapter, tag, tag.getRawTargets()[0]); + /** + * @hide + */ + public BasicTagTechnology(NfcAdapter adapter, Tag tag) throws RemoteException { + this(adapter, tag, tag.getTechnologyList()[0]); } /** NFC service dead - attempt best effort recovery */ @@ -80,7 +84,7 @@ public class RawTagConnection { mAdapter.attemptDeadServiceRecovery(e); /* assigning to mService is not thread-safe, but this is best-effort code * and on a well-behaved system should never happen */ - mService = mAdapter.mService; + mService = mAdapter.getService(); try { mTagService = mService.getNfcTagInterface(); } catch (RemoteException e2) { @@ -92,6 +96,7 @@ public class RawTagConnection { * Get the {@link Tag} this connection is associated with. * <p>Requires {@link android.Manifest.permission#NFC} permission. */ + @Override public Tag getTag() { return mTag; } @@ -99,8 +104,9 @@ public class RawTagConnection { /** * <p>Requires {@link android.Manifest.permission#NFC} permission. */ - public String getTagTarget() { - return mSelectedTarget; + @Override + public int getTechnologyId() { + return mSelectedTechnology; } /** @@ -119,7 +125,7 @@ public class RawTagConnection { } try { - return mTagService.isPresent(mTag.mServiceHandle); + return mTagService.isPresent(mTag.getServiceHandle()); } catch (RemoteException e) { attemptDeadServiceRecovery(e); return false; @@ -136,6 +142,7 @@ public class RawTagConnection { * <p>Requires {@link android.Manifest.permission#NFC} permission. * @throws IOException if the target is lost, or connect canceled */ + @Override public void connect() throws IOException { //TODO(nxp): enforce exclusivity mIsConnected = true; @@ -151,10 +158,11 @@ public class RawTagConnection { * calls to {@link #transceive transceive()} or {@link #connect} will fail. * <p>Requires {@link android.Manifest.permission#NFC} permission. */ + @Override public void close() { mIsConnected = false; try { - mTagService.close(mTag.mServiceHandle); + mTagService.close(mTag.getServiceHandle()); } catch (RemoteException e) { attemptDeadServiceRecovery(e); } @@ -173,7 +181,7 @@ public class RawTagConnection { */ public byte[] transceive(byte[] data) throws IOException { try { - byte[] response = mTagService.transceive(mTag.mServiceHandle, data); + byte[] response = mTagService.transceive(mTag.getServiceHandle(), data); if (response == null) { throw new IOException("transcieve failed"); } diff --git a/core/java/android/nfc/technology/IsoDep.java b/core/java/android/nfc/technology/IsoDep.java new file mode 100644 index 0000000..5346c67 --- /dev/null +++ b/core/java/android/nfc/technology/IsoDep.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010 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.technology; + +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +import java.io.IOException; + +/** + * A low-level connection to a {@link Tag} using the ISO-DEP technology, also known as + * ISO1443-4. + * + * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}. + * Use this class to send and receive data with {@link #transceive transceive()}. + * + * <p>Applications must implement their own protocol stack on top of + * {@link #transceive transceive()}. + * + * <p class="note"><strong>Note:</strong> + * Use of this class requires the {@link android.Manifest.permission#NFC} + * permission. + */ +public final class IsoDep extends BasicTagTechnology { + /** @hide */ + public static final String EXTRA_ATTRIB = "attrib"; + /** @hide */ + public static final String EXTRA_HIST_BYTES = "histbytes"; + + private byte[] mAttrib = null; + private byte[] mHistBytes = null; + + public IsoDep(NfcAdapter adapter, Tag tag, Bundle extras) + throws RemoteException { + super(adapter, tag, TagTechnology.ISO_DEP); + if (extras != null) { + mAttrib = extras.getByteArray(EXTRA_ATTRIB); + mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES); + } + } + + /** + * 3A only + */ + public byte[] getHistoricalBytes() { return mHistBytes; } + + /** + * 3B only + */ + public byte[] getAttrib() { return mAttrib; } + + /** + * Attempts to select the given application on the tag. Note that this only works + * if the tag supports ISO7816-4, which not all IsoDep tags support. If the tag doesn't + * support ISO7816-4 this will throw {@link UnsupportedOperationException}. + * + * This method requires that you call {@link #connect} before calling it. + * + * @throws IOException, UnsupportedOperationException + */ + public void selectAid(byte[] aid) throws IOException, UnsupportedOperationException { + throw new UnsupportedOperationException(); + } +} diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java new file mode 100644 index 0000000..ba3a425 --- /dev/null +++ b/core/java/android/nfc/technology/MifareClassic.java @@ -0,0 +1,289 @@ +/* + * Copyright (C) 2010 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.technology; + +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +import java.io.IOException; + +/** + * Concrete class for TagTechnology.MIFARE_CLASSIC + * + * Mifare classic has n sectors, with varying sizes, although + * they are at least the same pattern for any one mifare classic + * product. Each sector has two keys. Authentication with the correct + * key is needed before access to any sector. + * + * Each sector has k blocks. + * Block size is constant across the whole mifare classic family. + */ +public final class MifareClassic extends BasicTagTechnology { + /** + * The well-known, default MIFARE read key. + * Use this key to effectively make the payload in this sector + * public. + */ + public static final byte[] KEY_DEFAULT = + {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}; + /** + * The well-known, default Mifare Application Directory read key. + */ + public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY = + {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5}; + /** + * The well-known, default read key for NDEF data on a Mifare Classic + */ + public static final byte[] KEY_NFC_FORUM = + {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7}; + + public static final int TYPE_CLASSIC = 0; + public static final int TYPE_PLUS = 1; + public static final int TYPE_PRO = 2; + public static final int TYPE_DESFIRE = 3; + public static final int TYPE_ULTRALIGHT = 4; + public static final int TYPE_UNKNOWN = 5; + + public static final int SIZE_1K = 1024; + public static final int SIZE_2K = 2048; + public static final int SIZE_4K = 4096; + public static final int SIZE_MINI = 320; + public static final int SIZE_UNKNOWN = 0; + + private boolean mIsEmulated; + private int mType; + private int mSize; + + public MifareClassic(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { + super(adapter, tag, TagTechnology.MIFARE_CLASSIC); + + // Check if this could actually be a Mifare + NfcA a = (NfcA) tag.getTechnology(TagTechnology.NFC_A); + //short[] ATQA = getATQA(tag); + + mIsEmulated = false; + mType = TYPE_UNKNOWN; + mSize = SIZE_UNKNOWN; + + switch (a.getSak()) { + case 0x00: + // could be UL or UL-C + mType = TYPE_ULTRALIGHT; + break; + case 0x08: + // Type == classic + // Size = 1K + mType = TYPE_CLASSIC; + mSize = SIZE_1K; + break; + case 0x09: + // Type == classic mini + // Size == ? + mType = TYPE_CLASSIC; + mSize = SIZE_MINI; + break; + case 0x10: + // Type == MF+ + // Size == 2K + // SecLevel = SL2 + mType = TYPE_PLUS; + mSize = SIZE_2K; + break; + case 0x11: + // Type == MF+ + // Size == 4K + // Seclevel = SL2 + mType = TYPE_PLUS; + mSize = SIZE_4K; + break; + case 0x18: + // Type == classic + // Size == 4k + mType = TYPE_CLASSIC; + mSize = SIZE_4K; + break; + case 0x20: + // TODO this really should be a short, not byte + if (a.getAtqa()[0] == 0x03) { + // Type == DESFIRE + mType = TYPE_DESFIRE; + } else { + // Type == MF+ + // SL = SL3 + mType = TYPE_PLUS; + mSize = SIZE_UNKNOWN; + } + break; + case 0x28: + // Type == MF Classic + // Size == 1K + // Emulated == true + mType = TYPE_CLASSIC; + mSize = SIZE_1K; + mIsEmulated = true; + break; + case 0x38: + // Type == MF Classic + // Size == 4K + // Emulated == true + mType = TYPE_CLASSIC; + mSize = SIZE_4K; + mIsEmulated = true; + break; + case 0x88: + // Type == MF Classic + // Size == 1K + // NXP-tag: false + mType = TYPE_CLASSIC; + mSize = SIZE_1K; + break; + case 0x98: + case 0xB8: + // Type == MF Pro + // Size == 4K + mType = TYPE_PRO; + mSize = SIZE_4K; + break; + default: + // Unknown, not MIFARE + break; + } + } + + // Immutable data known at discovery time + public int getSize() { + return mSize; + } + + public int getType() { + return mType; + } + + public boolean isEmulated() { + return mIsEmulated; + } + + public int getSectorCount() { + switch (mSize) { + case SIZE_1K: { + return 16; + } + case SIZE_2K: { + return 32; + } + case SIZE_4K: { + return 40; + } + case SIZE_MINI: { + return 5; + } + default: { + return 0; + } + } + } + + public int getSectorSize(int sector) { + return getBlockCount(sector) * 16; + } + + public int getBlockCount(int sector) { + if (sector >= getSectorCount()) { + throw new IllegalArgumentException("this card only has " + getSectorCount() + + " sectors"); + } + + if (sector <= 32) { + return 4; + } else { + return 16; + } + } + + private byte firstBlockInSector(int sector) { + if (sector < 32) { + return (byte) ((sector * 4) & 0xff); + } else { + return (byte) ((32 * 4 + ((sector - 32) * 16)) & 0xff); + } + } + + // Methods that require connect() + /** + * Authenticate for a given sector. + */ + public boolean authenticateSector(int sector, byte[] key, boolean keyA) { + byte[] cmd = new byte[12]; + + // First byte is the command + if (keyA) { + cmd[0] = 0x60; // phHal_eMifareAuthentA + } else { + cmd[0] = 0x61; // phHal_eMifareAuthentB + } + + // Second byte is block address + cmd[1] = firstBlockInSector(sector); + + // Next 4 bytes are last 4 bytes of UID + byte[] uid = getTag().getId(); + System.arraycopy(uid, uid.length - 4, cmd, 2, 4); + + // Next 6 bytes are key + System.arraycopy(key, 0, cmd, 6, 6); + + try { + if ((transceive(cmd) != null)) { + return true; + } + } catch (IOException e) { + // No need to deal with, will return false anyway + } + return false; + } + + /** + * Sector indexing starts at 0. + * Block indexing starts at 0, and resets in each sector. + * @throws IOException + */ + public byte[] readBlock(int sector, int block) throws IOException { + byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff); + byte[] blockread_cmd = { 0x30, addr }; // phHal_eMifareRead + + // TODO deal with authentication problems + return transceive(blockread_cmd); + } + +// public byte[] readSector(int sector); + //TODO: define an enumeration for access control settings +// public int readSectorAccessControl(int sector); + + /** + * @throws IOException + * @throws NotAuthenticatedException + */ +/* + public void writeBlock(int block, byte[] data); + public void writeSector(int block, byte[] sector); + public void writeSectorAccessControl(int sector, int access); + public void increment(int block); + public void decrement(int block); +*/ +} diff --git a/core/java/android/nfc/technology/MifareUltralight.java b/core/java/android/nfc/technology/MifareUltralight.java new file mode 100644 index 0000000..dd1dae9 --- /dev/null +++ b/core/java/android/nfc/technology/MifareUltralight.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2010 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.technology; + +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +import java.io.IOException; + +/** + * Concrete class for TagTechnology.MIFARE_ULTRALIGHT + * + * Mifare classic has n sectors, with varying sizes, although + * they are at least the same pattern for any one mifare classic + * product. Each sector has two keys. Authentication with the correct + * key is needed before access to any sector. + * + * Each sector has k blocks. + * Block size is constant across the whole mifare classic family. + */ +public final class MifareUltralight extends BasicTagTechnology { + public static final int TYPE_ULTRALIGHT = 1; + public static final int TYPE_ULTRALIGHT_C = 2; + public static final int TYPE_UNKNOWN = 10; + + private static final int NXP_MANUFACTURER_ID = 0x04; + + private int mType; + + public MifareUltralight(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { + super(adapter, tag, TagTechnology.MIFARE_ULTRALIGHT); + + // Check if this could actually be a Mifare + NfcA a = (NfcA) tag.getTechnology(TagTechnology.NFC_A); + + mType = TYPE_UNKNOWN; + + if( a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID ) { + // could be UL or UL-C + mType = TYPE_ULTRALIGHT; + } + } + + public int getType() { + return mType; + } + + // Methods that require connect() + /** + * @throws IOException + */ + public byte[] readBlock(int block) throws IOException { + byte[] blockread_cmd = { 0x30, (byte)block }; // phHal_eMifareRead + return transceive(blockread_cmd); + } + + /** + * @throws IOException + */ +/* + public byte[] readOTP(); + public void writePage(int block, byte[] data); + public void writeBlock(int block, byte[] data); +*/ +} diff --git a/core/java/android/nfc/NdefTagConnection.java b/core/java/android/nfc/technology/Ndef.java index aafdbfd..1e3da2a 100644 --- a/core/java/android/nfc/NdefTagConnection.java +++ b/core/java/android/nfc/technology/Ndef.java @@ -14,115 +14,125 @@ * limitations under the License. */ -package android.nfc; - -import java.io.IOException; +package android.nfc.technology; +import android.nfc.ErrorCodes; +import android.nfc.FormatException; +import android.nfc.NdefMessage; +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.os.Bundle; import android.os.RemoteException; -import android.util.Log; + +import java.io.IOException; /** - * A connection to an NDEF target on an {@link NdefTag}. - * <p>You can acquire this kind of connection with {@link NfcAdapter#createNdefTagConnection - * createNdefTagConnection()}. Use the connection to read or write {@link NdefMessage}s. + * 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()} + * + * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}. + * * <p class="note"><strong>Note:</strong> * Use of this class requires the {@link android.Manifest.permission#NFC} * permission. - * @hide */ -public class NdefTagConnection extends RawTagConnection { +public final class Ndef extends BasicTagTechnology { public static final int NDEF_MODE_READ_ONCE = 1; public static final int NDEF_MODE_READ_ONLY = 2; public static final int NDEF_MODE_WRITE_ONCE = 3; public static final int NDEF_MODE_WRITE_MANY = 4; public static final int NDEF_MODE_UNKNOWN = 5; - private static final String TAG = "NFC"; + /** @hide */ + public static final String EXTRA_NDEF_MSG = "ndefmsg"; /** * Internal constructor, to be used by NfcAdapter * @hide */ - /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag, String target) throws RemoteException { - super(adapter, tag); - String[] targets = tag.getNdefTargets(); - int i; + public Ndef(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException { + super(adapter, tag, tech); + } - // Check target validity - for (i=0; i<targets.length; i++) { - if (target.equals(targets[i])) { - break; + /** + * Get the primary NDEF message on this tag. This data is read at discovery time + * and does not require a connection. + */ + public NdefMessage getNdefMessage() throws IOException, FormatException { + try { + int serviceHandle = mTag.getServiceHandle(); + NdefMessage msg = mTagService.read(serviceHandle); + if (msg == null) { + int errorCode = mTagService.getLastError(serviceHandle); + switch (errorCode) { + case ErrorCodes.ERROR_IO: + throw new IOException(); + case ErrorCodes.ERROR_INVALID_PARAM: + throw new FormatException(); + default: + // Should not happen + throw new IOException(); + } } - } - if (i >= targets.length) { - // Target not found - throw new IllegalArgumentException(); + return msg; + } catch (RemoteException e) { + attemptDeadServiceRecovery(e); + return null; } } /** - * Internal constructor, to be used by NfcAdapter - * @hide + * Get optional extra NDEF messages. + * Some tags may contain extra NDEF messages, but not all + * implementations will be able to read them. + */ + public NdefMessage[] getExtraNdefMessage() throws IOException, FormatException { + throw new UnsupportedOperationException(); + } + + /** + * Get maximum NDEF message size in bytes */ - /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag) throws RemoteException { - this(adapter, tag, tag.getNdefTargets()[0]); + public int getSize() { + throw new UnsupportedOperationException(); } /** - * Read NDEF message(s). - * This will always return the most up to date payload, and can block. - * It can be canceled with {@link RawTagConnection#close}. - * Most NDEF tags will contain just one NDEF message. + * Read/Write mode hint. + * Provides a hint if further reads or writes are likely to succeed. * <p>Requires {@link android.Manifest.permission#NFC} permission. - * @throws FormatException if the tag is not NDEF formatted + * @return one of NDEF_MODE * @throws IOException if the target is lost or connection closed - * @throws FormatException */ - public NdefMessage[] readNdefMessages() throws IOException, FormatException { - //TODO(nxp): do not use getLastError(), it is racy + public int getModeHint() throws IOException { try { - NdefMessage[] msgArray = new NdefMessage[1]; - NdefMessage msg = mTagService.read(mTag.mServiceHandle); - if (msg == null) { - int errorCode = mTagService.getLastError(mTag.mServiceHandle); - switch (errorCode) { + int result = mTagService.getModeHint(mTag.getServiceHandle()); + if (ErrorCodes.isError(result)) { + switch (result) { case ErrorCodes.ERROR_IO: throw new IOException(); - case ErrorCodes.ERROR_INVALID_PARAM: - throw new FormatException(); default: // Should not happen throw new IOException(); } } - msgArray[0] = msg; - return msgArray; + return result; + } catch (RemoteException e) { attemptDeadServiceRecovery(e); - return null; + return NDEF_MODE_UNKNOWN; } } + // Methods that require connect() /** - * Attempt to write an NDEF message to a tag. - * This method will block until the data is written. It can be canceled - * with {@link RawTagConnection#close}. - * Many tags are write-once, so use this method carefully. - * Specification allows for multiple NDEF messages per NDEF tag, but it is - * encourage to only write one message, this so API only takes a single - * message. Use {@link NdefRecord} to write several records to a single tag. - * For write-many tags, use {@link #makeReadOnly} after this method to attempt - * to prevent further modification. For write-once tags this is not - * necessary. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - * - * @throws FormatException if the tag is not suitable for NDEF messages - * @throws IOException if the target is lost or connection closed or the - * write failed + * Overwrite the primary NDEF message + * @throws IOException */ - public void writeNdefMessage(NdefMessage message) throws IOException, FormatException { + public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException { try { - int errorCode = mTagService.write(mTag.mServiceHandle, message); + int errorCode = mTagService.write(mTag.getServiceHandle(), msg); switch (errorCode) { case ErrorCodes.SUCCESS: break; @@ -140,16 +150,26 @@ public class NdefTagConnection extends RawTagConnection { } /** - * Attempts to make the NDEF data in this tag read-only. - * This method will block until the action is complete. It can be canceled - * with {@link RawTagConnection#close}. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - * @return true if the tag is now read-only - * @throws IOException if the target is lost, or connection closed + * Attempt to write extra NDEF messages. + * Implementations may be able to write extra NDEF + * message after the first primary message, but it is not + * guaranteed. Even if it can be written, other implementations + * may not be able to read NDEF messages after the primary message. + * It is recommended to use additional NDEF records instead. + * + * @throws IOException + */ + public void writeExtraNdefMessage(int i, NdefMessage msg) throws IOException, FormatException { + throw new UnsupportedOperationException(); + } + + /** + * Set the CC field to indicate this tag is read-only + * @throws IOException */ - public boolean makeReadOnly() throws IOException { + public boolean makeReadonly() throws IOException { try { - int errorCode = mTagService.makeReadOnly(mTag.mServiceHandle); + int errorCode = mTagService.makeReadOnly(mTag.getServiceHandle()); switch (errorCode) { case ErrorCodes.SUCCESS: return true; @@ -168,29 +188,11 @@ public class NdefTagConnection extends RawTagConnection { } /** - * Read/Write mode hint. - * Provides a hint if further reads or writes are likely to succeed. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - * @return one of NDEF_MODE - * @throws IOException if the target is lost or connection closed + * Attempt to use tag specific technology to really make + * the tag read-only + * For NFC Forum Type 1 and 2 only. */ - public int getModeHint() throws IOException { - try { - int result = mTagService.getModeHint(mTag.mServiceHandle); - if (ErrorCodes.isError(result)) { - switch (result) { - case ErrorCodes.ERROR_IO: - throw new IOException(); - default: - // Should not happen - throw new IOException(); - } - } - return result; - - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - return NDEF_MODE_UNKNOWN; - } + public void makeLowLevelReadonly() { + throw new UnsupportedOperationException(); } -}
\ No newline at end of file +} diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java new file mode 100644 index 0000000..7c4f9ab --- /dev/null +++ b/core/java/android/nfc/technology/NdefFormatable.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2010 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.technology; + +import android.nfc.ErrorCodes; +import android.nfc.FormatException; +import android.nfc.NdefMessage; +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +import java.io.IOException; + +/** + * An interface to a {@link Tag} allowing to format the tag as NDEF. + * + * <p>You can acquire this kind of interface with {@link Tag#getTechnology(int)}. + * + * <p class="note"><strong>Note:</strong> + * Use of this class requires the {@link android.Manifest.permission#NFC} + * permission. + */ +public final class NdefFormatable extends BasicTagTechnology { + /** + * Internal constructor, to be used by NfcAdapter + * @hide + */ + public NdefFormatable(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException { + super(adapter, tag, tech); + } + + /** + * Returns whether a tag can be formatted with {@link + * NdefFormatable#format(NdefMessage)} + */ + public boolean canBeFormatted() throws IOException { + throw new UnsupportedOperationException(); + } + + /** + * Formats a tag as NDEF, if possible. You may supply a first + * NdefMessage to be written on the tag. + */ + public void format(NdefMessage firstMessage) throws IOException { + throw new UnsupportedOperationException(); + } +} diff --git a/core/java/android/nfc/technology/NfcA.java b/core/java/android/nfc/technology/NfcA.java new file mode 100644 index 0000000..ef46762 --- /dev/null +++ b/core/java/android/nfc/technology/NfcA.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010 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.technology; + +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +/** + * A low-level connection to a {@link Tag} using the NFC-A technology, also known as + * ISO1443-3A. + * + * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}. + * Use this class to send and receive data with {@link #transceive transceive()}. + * + * <p>Applications must implement their own protocol stack on top of + * {@link #transceive transceive()}. + * + * <p class="note"><strong>Note:</strong> + * Use of this class requires the {@link android.Manifest.permission#NFC} + * permission. + */ +public final class NfcA extends BasicTagTechnology { + /** @hide */ + public static final String EXTRA_SAK = "sak"; + /** @hide */ + public static final String EXTRA_ATQA = "atqa"; + + private short mSak; + private byte[] mAtqa; + + public NfcA(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException { + super(adapter, tag, TagTechnology.NFC_A); + mSak = extras.getShort(EXTRA_SAK); + mAtqa = extras.getByteArray(EXTRA_ATQA); + } + + /** + * Returns the ATQA/SENS_RES bytes discovered at tag discovery. + */ + public byte[] getAtqa() { + return mAtqa; + } + + /** + * Returns the SAK/SEL_RES discovered at tag discovery. + */ + public short getSak() { + return mSak; + } +} diff --git a/core/java/android/nfc/technology/NfcB.java b/core/java/android/nfc/technology/NfcB.java new file mode 100644 index 0000000..64cb08a --- /dev/null +++ b/core/java/android/nfc/technology/NfcB.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2010 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.technology; + +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +/** + * A low-level connection to a {@link Tag} using the NFC-B technology, also known as + * ISO1443-3B. + * + * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}. + * Use this class to send and receive data with {@link #transceive transceive()}. + * + * <p>Applications must implement their own protocol stack on top of + * {@link #transceive transceive()}. + * + * <p class="note"><strong>Note:</strong> + * Use of this class requires the {@link android.Manifest.permission#NFC} + * permission. + */ +public final class NfcB extends BasicTagTechnology { + /** @hide */ + public static final String EXTRA_ATQB = "atqb"; + + private byte[] mAtqb; + + public NfcB(NfcAdapter adapter, Tag tag, Bundle extras) + throws RemoteException { + super(adapter, tag, TagTechnology.NFC_B); + } + + /** + * Returns the ATQB/SENSB_RES bytes discovered at tag discovery. + */ + public byte[] getAtqb() { + return mAtqb; + } +} diff --git a/core/java/android/nfc/technology/NfcF.java b/core/java/android/nfc/technology/NfcF.java new file mode 100644 index 0000000..6741ac8 --- /dev/null +++ b/core/java/android/nfc/technology/NfcF.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2010 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.technology; + +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +/** + * A low-level connection to a {@link Tag} using the NFC-F technology, also known as + * JIS6319-4. + * + * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}. + * Use this class to send and receive data with {@link #transceive transceive()}. + * + * <p>Applications must implement their own protocol stack on top of + * {@link #transceive transceive()}. + * + * <p class="note"><strong>Note:</strong> + * Use of this class requires the {@link android.Manifest.permission#NFC} + * permission. + */ +public final class NfcF extends BasicTagTechnology { + /** @hide */ + public static final String EXTRA_SC = "systemcode"; + /** @hide */ + public static final String EXTRA_PMM = "pmm"; + + private byte[] mSystemCode = null; + private byte[] mManufacturer = null; + + public NfcF(NfcAdapter adapter, Tag tag, Bundle extras) + throws RemoteException { + super(adapter, tag, TagTechnology.NFC_F); + if (extras != null) { + mSystemCode = extras.getByteArray(EXTRA_SC); + mManufacturer = extras.getByteArray(EXTRA_PMM); + } + } + + public byte[] getSystemCode() { + return mSystemCode; + } + + public byte[] getManufacturer() { + return mManufacturer; + } +} diff --git a/core/java/android/nfc/technology/NfcV.java b/core/java/android/nfc/technology/NfcV.java new file mode 100644 index 0000000..9b6a16a --- /dev/null +++ b/core/java/android/nfc/technology/NfcV.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010 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.technology; + +import android.nfc.NfcAdapter; +import android.nfc.Tag; +import android.os.Bundle; +import android.os.RemoteException; + +/** + * A low-level connection to a {@link Tag} using the NFC-V technology, also known as + * ISO15693. + * + * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}. + * Use this class to send and receive data with {@link #transceive transceive()}. + * + * <p>Applications must implement their own protocol stack on top of + * {@link #transceive transceive()}. + * + * <p class="note"><strong>Note:</strong> + * Use of this class requires the {@link android.Manifest.permission#NFC} + * permission. + */ +public final class NfcV extends BasicTagTechnology { + public NfcV(NfcAdapter adapter, Tag tag, Bundle extras) + throws RemoteException { + super(adapter, tag, TagTechnology.NFC_V); + } +} diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java new file mode 100644 index 0000000..4704f2b --- /dev/null +++ b/core/java/android/nfc/technology/TagTechnology.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2010 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.technology; + +import android.nfc.Tag; + +import java.io.IOException; + +public interface TagTechnology { + /** + * This object is an instance of {@link NfcA} + */ + public static final int NFC_A = 1; + + /** + * This object is an instance of {@link NfcB} + */ + public static final int NFC_B = 2; + + /** + * This object is an instance of {@link IsoDep} + */ + public static final int ISO_DEP = 3; + + /** + * This object is an instance of {@link NfcF} + */ + public static final int NFC_F = 11; + + /** + * This object is an instance of {@link NfcV} + */ + public static final int NFC_V = 21; + + /** + * This object is an instance of {@link Ndef} + */ + public static final int NDEF = 101; + + /** + * This object is an instance of {@link NdefFormatable} + */ + public static final int NDEF_FORMATABLE = 110; + + /** + * This object is an instance of {@link MifareClassic} + */ + public static final int MIFARE_CLASSIC = 200; + + /** + * A Mifare Classic tag with NDEF data + */ + public static final int MIFARE_CLASSIC_NDEF = 201; + + /** + * This object is an instance of {@link MifareUltralight} + */ + public static final int MIFARE_ULTRALIGHT = 202; + + /** + * A Mifare DESFire tag + */ + public static final int MIFARE_DESFIRE = 203; + + /** + * Returns the technology type for this tag connection. + */ + public int getTechnologyId(); + + /** + * Get the backing tag object. + */ + public Tag getTag(); + + /** + * @throws IOException + */ + public void connect() throws IOException; + + /** + * Non-blocking. Immediately causes all blocking calls + * to throw IOException. + */ + public void close(); +} diff --git a/core/java/android/nfc/technology/package.html b/core/java/android/nfc/technology/package.html new file mode 100644 index 0000000..26b8a32 --- /dev/null +++ b/core/java/android/nfc/technology/package.html @@ -0,0 +1,5 @@ +<HTML> +<BODY> +{@hide} +</BODY> +</HTML>
\ No newline at end of file diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 07a48e7..b83aea8 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -86,7 +86,6 @@ <protected-broadcast android:name="android.hardware.action.USB_DISCONNECTED" /> <protected-broadcast android:name="android.hardware.action.USB_STATE" /> - <protected-broadcast android:name="android.nfc.action.TAG_DISCOVERED" /> <protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" /> <protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" /> diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_0.png b/core/res/res/drawable-hdpi/stat_sys_battery_0.png Binary files differindex 82f2509..572e0d3 100644 --- a/core/res/res/drawable-hdpi/stat_sys_battery_0.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_0.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_10.png b/core/res/res/drawable-hdpi/stat_sys_battery_10.png Binary files differindex 4486553..c9d9436 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_10.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_10.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_100.png b/core/res/res/drawable-hdpi/stat_sys_battery_100.png Binary files differindex e49448d..754cdf6 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_100.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_100.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_15.png b/core/res/res/drawable-hdpi/stat_sys_battery_15.png Binary files differnew file mode 100644 index 0000000..0b9bed8 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_15.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_20.png b/core/res/res/drawable-hdpi/stat_sys_battery_20.png Binary files differindex c8f9c92..c22fead 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_20.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_20.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_25.png b/core/res/res/drawable-hdpi/stat_sys_battery_25.png Binary files differnew file mode 100644 index 0000000..7c7030a --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_25.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_30.png b/core/res/res/drawable-hdpi/stat_sys_battery_30.png Binary files differnew file mode 100644 index 0000000..d0342df --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_30.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_35.png b/core/res/res/drawable-hdpi/stat_sys_battery_35.png Binary files differnew file mode 100644 index 0000000..00190ab --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_35.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_40.png b/core/res/res/drawable-hdpi/stat_sys_battery_40.png Binary files differindex 441bbfb..ced08cd 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_40.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_40.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_45.png b/core/res/res/drawable-hdpi/stat_sys_battery_45.png Binary files differnew file mode 100644 index 0000000..8f60486 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_45.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_5.png b/core/res/res/drawable-hdpi/stat_sys_battery_5.png Binary files differnew file mode 100644 index 0000000..d9c6135 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_5.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_50.png b/core/res/res/drawable-hdpi/stat_sys_battery_50.png Binary files differnew file mode 100644 index 0000000..ff0ef0d --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_50.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_55.png b/core/res/res/drawable-hdpi/stat_sys_battery_55.png Binary files differnew file mode 100644 index 0000000..3f7581d --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_55.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_60.png b/core/res/res/drawable-hdpi/stat_sys_battery_60.png Binary files differindex d9467ed..359d65e 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_60.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_60.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_65.png b/core/res/res/drawable-hdpi/stat_sys_battery_65.png Binary files differnew file mode 100644 index 0000000..b3dc834 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_65.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_70.png b/core/res/res/drawable-hdpi/stat_sys_battery_70.png Binary files differnew file mode 100644 index 0000000..4995289 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_70.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_75.png b/core/res/res/drawable-hdpi/stat_sys_battery_75.png Binary files differnew file mode 100644 index 0000000..011f82e --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_75.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_80.png b/core/res/res/drawable-hdpi/stat_sys_battery_80.png Binary files differindex e3f4805..24b32c1 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_80.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_80.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_85.png b/core/res/res/drawable-hdpi/stat_sys_battery_85.png Binary files differnew file mode 100644 index 0000000..2be76e0 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_85.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_90.png b/core/res/res/drawable-hdpi/stat_sys_battery_90.png Binary files differnew file mode 100644 index 0000000..74c3e49 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_90.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_95.png b/core/res/res/drawable-hdpi/stat_sys_battery_95.png Binary files differnew file mode 100644 index 0000000..2cac442 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_battery_95.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png Binary files differindex c7464f7..061bd2a 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png Binary files differindex 997feb3..895ade2 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png Binary files differindex 426a66b..ba57679 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png Binary files differindex 21582ca..85f461a 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png Binary files differindex 8a94763..4766067 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png Binary files differindex fad0d65..8708473 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png b/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png Binary files differindex dadfe8d..9d65883 100755 --- a/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png +++ b/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_0.png b/core/res/res/drawable-mdpi/stat_sys_battery_0.png Binary files differindex a7068b2..aff0868 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_0.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_0.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_10.png b/core/res/res/drawable-mdpi/stat_sys_battery_10.png Binary files differindex 8fd88f3..eedc2b0 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_10.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_10.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_100.png b/core/res/res/drawable-mdpi/stat_sys_battery_100.png Binary files differindex 5267517..17a955d 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_100.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_100.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_15.png b/core/res/res/drawable-mdpi/stat_sys_battery_15.png Binary files differnew file mode 100644 index 0000000..eef8c92 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_15.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_20.png b/core/res/res/drawable-mdpi/stat_sys_battery_20.png Binary files differindex 8bc41f0..999299f 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_20.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_20.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_25.png b/core/res/res/drawable-mdpi/stat_sys_battery_25.png Binary files differnew file mode 100644 index 0000000..9f5f68d --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_25.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_30.png b/core/res/res/drawable-mdpi/stat_sys_battery_30.png Binary files differnew file mode 100644 index 0000000..b77c5e3 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_30.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_35.png b/core/res/res/drawable-mdpi/stat_sys_battery_35.png Binary files differnew file mode 100644 index 0000000..018f980 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_35.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_40.png b/core/res/res/drawable-mdpi/stat_sys_battery_40.png Binary files differindex d827ce9..42e556d 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_40.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_40.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_45.png b/core/res/res/drawable-mdpi/stat_sys_battery_45.png Binary files differnew file mode 100644 index 0000000..e6b6a6c --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_45.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_5.png b/core/res/res/drawable-mdpi/stat_sys_battery_5.png Binary files differnew file mode 100644 index 0000000..60636a5 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_5.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_50.png b/core/res/res/drawable-mdpi/stat_sys_battery_50.png Binary files differnew file mode 100644 index 0000000..eea9221 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_50.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_55.png b/core/res/res/drawable-mdpi/stat_sys_battery_55.png Binary files differnew file mode 100644 index 0000000..067cbf1 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_55.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_60.png b/core/res/res/drawable-mdpi/stat_sys_battery_60.png Binary files differindex 53399dc..0d4ea98 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_60.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_60.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_65.png b/core/res/res/drawable-mdpi/stat_sys_battery_65.png Binary files differnew file mode 100644 index 0000000..9e36b78 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_65.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_70.png b/core/res/res/drawable-mdpi/stat_sys_battery_70.png Binary files differnew file mode 100644 index 0000000..0d22fbc --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_70.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_75.png b/core/res/res/drawable-mdpi/stat_sys_battery_75.png Binary files differnew file mode 100644 index 0000000..409127b --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_75.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_80.png b/core/res/res/drawable-mdpi/stat_sys_battery_80.png Binary files differindex f38af5d..9bb5a4d 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_80.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_80.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_85.png b/core/res/res/drawable-mdpi/stat_sys_battery_85.png Binary files differnew file mode 100644 index 0000000..5d832cf --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_85.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_90.png b/core/res/res/drawable-mdpi/stat_sys_battery_90.png Binary files differnew file mode 100644 index 0000000..5245336 --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_90.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_95.png b/core/res/res/drawable-mdpi/stat_sys_battery_95.png Binary files differnew file mode 100644 index 0000000..2e72e4e --- /dev/null +++ b/core/res/res/drawable-mdpi/stat_sys_battery_95.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png Binary files differindex 9f3da11..59ee091 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png Binary files differindex 8f8c81e..5d9bd74 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png Binary files differindex 12fd03f..5f0e9bc 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png Binary files differindex 641896c..c0fd42c 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png Binary files differindex 6bd19b5..6d39d70 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png Binary files differindex f9353c0..e5e3ac5 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png b/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png Binary files differindex 506cb45..8c31cd1 100644 --- a/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png +++ b/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png diff --git a/core/res/res/drawable/stat_sys_battery.xml b/core/res/res/drawable/stat_sys_battery.xml index 968595d..8261243 100644 --- a/core/res/res/drawable/stat_sys_battery.xml +++ b/core/res/res/drawable/stat_sys_battery.xml @@ -19,12 +19,26 @@ --> <level-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:maxLevel="4" android:drawable="@android:drawable/stat_sys_battery_0" /> - <item android:maxLevel="14" android:drawable="@android:drawable/stat_sys_battery_10" /> - <item android:maxLevel="29" android:drawable="@android:drawable/stat_sys_battery_20" /> - <item android:maxLevel="49" android:drawable="@android:drawable/stat_sys_battery_40" /> - <item android:maxLevel="69" android:drawable="@android:drawable/stat_sys_battery_60" /> - <item android:maxLevel="89" android:drawable="@android:drawable/stat_sys_battery_80" /> + <item android:maxLevel="2" android:drawable="@android:drawable/stat_sys_battery_0" /> + <item android:maxLevel="7" android:drawable="@android:drawable/stat_sys_battery_5" /> + <item android:maxLevel="12" android:drawable="@android:drawable/stat_sys_battery_10" /> + <item android:maxLevel="17" android:drawable="@android:drawable/stat_sys_battery_15" /> + <item android:maxLevel="22" android:drawable="@android:drawable/stat_sys_battery_20" /> + <item android:maxLevel="27" android:drawable="@android:drawable/stat_sys_battery_25" /> + <item android:maxLevel="32" android:drawable="@android:drawable/stat_sys_battery_30" /> + <item android:maxLevel="37" android:drawable="@android:drawable/stat_sys_battery_35" /> + <item android:maxLevel="42" android:drawable="@android:drawable/stat_sys_battery_40" /> + <item android:maxLevel="47" android:drawable="@android:drawable/stat_sys_battery_45" /> + <item android:maxLevel="52" android:drawable="@android:drawable/stat_sys_battery_50" /> + <item android:maxLevel="57" android:drawable="@android:drawable/stat_sys_battery_55" /> + <item android:maxLevel="62" android:drawable="@android:drawable/stat_sys_battery_60" /> + <item android:maxLevel="67" android:drawable="@android:drawable/stat_sys_battery_65" /> + <item android:maxLevel="72" android:drawable="@android:drawable/stat_sys_battery_70" /> + <item android:maxLevel="77" android:drawable="@android:drawable/stat_sys_battery_75" /> + <item android:maxLevel="82" android:drawable="@android:drawable/stat_sys_battery_80" /> + <item android:maxLevel="87" android:drawable="@android:drawable/stat_sys_battery_85" /> + <item android:maxLevel="92" android:drawable="@android:drawable/stat_sys_battery_90" /> + <item android:maxLevel="97" android:drawable="@android:drawable/stat_sys_battery_95" /> <item android:maxLevel="100" android:drawable="@android:drawable/stat_sys_battery_100" /> </level-list> diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp index 7efc6d7..743fbb2 100644 --- a/libs/camera/Camera.cpp +++ b/libs/camera/Camera.cpp @@ -359,6 +359,9 @@ void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp< } if (listener != NULL) { listener->postDataTimestamp(timestamp, msgType, dataPtr); + } else { + LOGW("No listener was set. Drop a recording frame."); + releaseRecordingFrame(dataPtr); } } diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index ab260d5..29a5a96 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -40,6 +40,8 @@ #include <utils/KeyedVector.h> #include <utils/String8.h> +#include <ui/egl/android_natives.h> + #include "hooks.h" #include "egl_impl.h" #include "Loader.h" @@ -196,15 +198,16 @@ struct egl_surface_t : public egl_object_t { typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref; - egl_surface_t(EGLDisplay dpy, EGLSurface surface, EGLConfig config, - int impl, egl_connection_t const* cnx) - : dpy(dpy), surface(surface), config(config), impl(impl), cnx(cnx) { + egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, + EGLSurface surface, int impl, egl_connection_t const* cnx) + : dpy(dpy), surface(surface), config(config), win(win), impl(impl), cnx(cnx) { } ~egl_surface_t() { } EGLDisplay dpy; EGLSurface surface; EGLConfig config; + sp<ANativeWindow> win; int impl; egl_connection_t const* cnx; }; @@ -984,11 +987,22 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, egl_display_t const* dp = 0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (cnx) { + EGLDisplay iDpy = dp->disp[ dp->configs[intptr_t(config)].impl ].dpy; + EGLConfig iConfig = dp->configs[intptr_t(config)].config; + EGLint format; + + // set the native window's buffers format to match this config + if (cnx->egl.eglGetConfigAttrib(iDpy, + iConfig, EGL_NATIVE_VISUAL_ID, &format)) { + if (format != 0) { + native_window_set_buffers_geometry(window, 0, 0, format); + } + } + EGLSurface surface = cnx->egl.eglCreateWindowSurface( - dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, - dp->configs[intptr_t(config)].config, window, attrib_list); + iDpy, iConfig, window, attrib_list); if (surface != EGL_NO_SURFACE) { - egl_surface_t* s = new egl_surface_t(dpy, surface, config, + egl_surface_t* s = new egl_surface_t(dpy, config, window, surface, dp->configs[intptr_t(config)].impl, cnx); return s; } @@ -1007,7 +1021,7 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, dp->configs[intptr_t(config)].config, pixmap, attrib_list); if (surface != EGL_NO_SURFACE) { - egl_surface_t* s = new egl_surface_t(dpy, surface, config, + egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface, dp->configs[intptr_t(config)].impl, cnx); return s; } @@ -1025,7 +1039,7 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, dp->disp[ dp->configs[intptr_t(config)].impl ].dpy, dp->configs[intptr_t(config)].config, attrib_list); if (surface != EGL_NO_SURFACE) { - egl_surface_t* s = new egl_surface_t(dpy, surface, config, + egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface, dp->configs[intptr_t(config)].impl, cnx); return s; } @@ -1046,6 +1060,9 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) EGLBoolean result = s->cnx->egl.eglDestroySurface( dp->disp[s->impl].dpy, s->surface); if (result == EGL_TRUE) { + if (s->win != NULL) { + native_window_set_buffers_geometry(s->win.get(), 0, 0, 0); + } _s.terminate(); } return result; diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java index 5cf2531..a92ac1c 100755 --- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java +++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java @@ -383,7 +383,9 @@ public class SipPhone extends SipPhoneBase { Connection dial(String originalNumber) throws SipException { String calleeSipUri = originalNumber; if (!calleeSipUri.contains("@")) { - calleeSipUri += "@" + getSipDomain(mProfile); + calleeSipUri = mProfile.getUriString().replaceFirst( + mProfile.getUserName() + "@", + calleeSipUri + "@"); } try { SipProfile callee = diff --git a/voip/java/android/net/sip/SipProfile.java b/voip/java/android/net/sip/SipProfile.java index 6977e30..4029ed0 100644 --- a/voip/java/android/net/sip/SipProfile.java +++ b/voip/java/android/net/sip/SipProfile.java @@ -20,6 +20,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; +import java.io.ObjectStreamException; import java.io.Serializable; import java.text.ParseException; import javax.sip.InvalidArgumentException; @@ -40,12 +41,15 @@ import javax.sip.address.URI; public class SipProfile implements Parcelable, Serializable, Cloneable { private static final long serialVersionUID = 1L; private static final int DEFAULT_PORT = 5060; + private static final String TCP = "TCP"; + private static final String UDP = "UDP"; private Address mAddress; private String mProxyAddress; private String mPassword; private String mDomain; - private String mProtocol = ListeningPoint.UDP; + private String mProtocol = UDP; private String mProfileName; + private int mPort = DEFAULT_PORT; private boolean mSendKeepAlive = false; private boolean mAutoRegistration = true; private transient int mCallingUid = 0; @@ -95,6 +99,7 @@ public class SipProfile implements Parcelable, Serializable, Cloneable { mUri.setUserPassword(profile.getPassword()); mDisplayName = profile.getDisplayName(); mProxyAddress = profile.getProxyAddress(); + mProfile.mPort = profile.getPort(); } /** @@ -171,12 +176,11 @@ public class SipProfile implements Parcelable, Serializable, Cloneable { * @throws IllegalArgumentException if the port number is out of range */ public Builder setPort(int port) throws IllegalArgumentException { - try { - mUri.setPort(port); - return this; - } catch (InvalidArgumentException e) { - throw new IllegalArgumentException(e); + if ((port > 65535) || (port < 1000)) { + throw new IllegalArgumentException("incorrect port arugment"); } + mProfile.mPort = port; + return this; } /** @@ -193,7 +197,7 @@ public class SipProfile implements Parcelable, Serializable, Cloneable { throw new NullPointerException("protocol cannot be null"); } protocol = protocol.toUpperCase(); - if (!protocol.equals("UDP") && !protocol.equals("TCP")) { + if (!protocol.equals(UDP) && !protocol.equals(TCP)) { throw new IllegalArgumentException( "unsupported protocol: " + protocol); } @@ -258,13 +262,22 @@ public class SipProfile implements Parcelable, Serializable, Cloneable { mProfile.mPassword = mUri.getUserPassword(); mUri.setUserPassword(null); try { - mProfile.mAddress = mAddressFactory.createAddress( - mDisplayName, mUri); if (!TextUtils.isEmpty(mProxyAddress)) { SipURI uri = (SipURI) mAddressFactory.createURI(fix(mProxyAddress)); mProfile.mProxyAddress = uri.getHost(); + } else { + if (!mProfile.mProtocol.equals(UDP)) { + mUri.setTransportParam(mProfile.mProtocol); + } + if (mProfile.mPort != DEFAULT_PORT) { + mUri.setPort(mProfile.mPort); + } } + mProfile.mAddress = mAddressFactory.createAddress( + mDisplayName, mUri); + } catch (InvalidArgumentException e) { + throw new RuntimeException(e); } catch (ParseException e) { // must not occur throw new RuntimeException(e); @@ -286,6 +299,7 @@ public class SipProfile implements Parcelable, Serializable, Cloneable { mSendKeepAlive = (in.readInt() == 0) ? false : true; mAutoRegistration = (in.readInt() == 0) ? false : true; mCallingUid = in.readInt(); + mPort = in.readInt(); } @Override @@ -299,6 +313,7 @@ public class SipProfile implements Parcelable, Serializable, Cloneable { out.writeInt(mSendKeepAlive ? 1 : 0); out.writeInt(mAutoRegistration ? 1 : 0); out.writeInt(mCallingUid); + out.writeInt(mPort); } @Override @@ -322,7 +337,13 @@ public class SipProfile implements Parcelable, Serializable, Cloneable { * @return the SIP URI string of this profile */ public String getUriString() { - return mAddress.getURI().toString(); + // We need to return the sip uri domain instead of + // the SIP URI with transport, port information if + // the outbound proxy address exists. + if (!TextUtils.isEmpty(mProxyAddress)) { + return "sip:" + getUserName() + "@" + mDomain; + } + return getUri().toString(); } /** @@ -377,8 +398,7 @@ public class SipProfile implements Parcelable, Serializable, Cloneable { * @return the port number of the SIP server */ public int getPort() { - int port = getUri().getPort(); - return (port == -1) ? DEFAULT_PORT : port; + return mPort; } /** @@ -441,4 +461,10 @@ public class SipProfile implements Parcelable, Serializable, Cloneable { public int getCallingUid() { return mCallingUid; } + + private Object readResolve() throws ObjectStreamException { + // For compatibility. + if (mPort == 0) mPort = DEFAULT_PORT; + return this; + } } diff --git a/voip/java/com/android/server/sip/SipHelper.java b/voip/java/com/android/server/sip/SipHelper.java index 13e6f14..518543a 100644 --- a/voip/java/com/android/server/sip/SipHelper.java +++ b/voip/java/com/android/server/sip/SipHelper.java @@ -215,8 +215,9 @@ class SipHelper { String tag) throws ParseException, SipException { FromHeader fromHeader = createFromHeader(userProfile, tag); ToHeader toHeader = createToHeader(userProfile); - SipURI requestURI = mAddressFactory.createSipURI("sip:" - + userProfile.getSipDomain()); + SipURI requestURI = mAddressFactory.createSipURI( + userProfile.getUriString().replaceFirst( + userProfile.getUserName() + "@", "")); List<ViaHeader> viaHeaders = createViaHeaders(); CallIdHeader callIdHeader = createCallIdHeader(); CSeqHeader cSeqHeader = createCSeqHeader(requestType); diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java index 5540174..27e6a72 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -933,10 +933,8 @@ public class WifiStateTracker extends NetworkStateTracker { resetConnections(true); } // When supplicant dies, kill the DHCP thread - if (mDhcpTarget != null) { - mDhcpTarget.getLooper().quit(); - mDhcpTarget = null; - } + mDhcpTarget.getLooper().quit(); + mContext.removeStickyBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION)); if (ActivityManagerNative.isSystemReady()) { intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); @@ -1407,10 +1405,9 @@ public class WifiStateTracker extends NetworkStateTracker { NetworkUtils.resetConnections(mInterfaceName); // Stop DHCP - if (mDhcpTarget != null) { - mDhcpTarget.setCancelCallback(true); - mDhcpTarget.removeMessages(EVENT_DHCP_START); - } + mDhcpTarget.setCancelCallback(true); + mDhcpTarget.removeMessages(EVENT_DHCP_START); + if (!NetworkUtils.stopDhcp(mInterfaceName)) { Log.e(TAG, "Could not stop DHCP"); } |
