diff options
77 files changed, 1651 insertions, 597 deletions
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java index d30a0c68f8fe..622bcdb0ba9c 100644 --- a/core/java/android/nfc/NfcAdapter.java +++ b/core/java/android/nfc/NfcAdapter.java @@ -26,14 +26,17 @@ import android.content.Context; import android.content.IntentFilter; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; +import android.nfc.tech.MifareClassic; +import android.nfc.tech.Ndef; +import android.nfc.tech.NfcA; +import android.nfc.tech.NfcF; import android.os.IBinder; -import android.os.Parcel; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Log; /** - * Represents the device's local NFC adapter. + * Represents the local NFC adapter. * <p> * Use the helper {@link #getDefaultAdapter(Context)} to get the default NFC * adapter for this Android device. @@ -43,30 +46,85 @@ public final class NfcAdapter { /** * Intent to start an activity when a tag with NDEF payload is discovered. - * If the tag has and NDEF payload this intent is started before - * {@link #ACTION_TECH_DISCOVERED}. * - * If any activities respond to this intent neither + * <p>The system inspects the first {@link NdefRecord} in the first {@link NdefMessage} and + * looks for a URI, SmartPoster, or MIME record. If a URI or SmartPoster record is found the + * intent will contain the URI in its data field. If a MIME record is found the intent will + * contain the MIME type in its type field. This allows activities to register + * {@link IntentFilter}s targeting specific content on tags. Activities should register the + * most specific intent filters possible to avoid the activity chooser dialog, which can + * disrupt the interaction with the tag as the user interacts with the screen. + * + * <p>If the tag has an NDEF payload this intent is started before + * {@link #ACTION_TECH_DISCOVERED}. If any activities respond to this intent neither * {@link #ACTION_TECH_DISCOVERED} or {@link #ACTION_TAG_DISCOVERED} will be started. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED"; /** - * Intent to started when a tag is discovered. The data URI is formated as - * {@code vnd.android.nfc://tag/} with the path having a directory entry for each technology - * in the {@link Tag#getTechList()} is sorted ascending order. + * Intent to start an activity when a tag is discovered and activities are registered for the + * specific technologies on the tag. + * + * <p>To receive this intent an activity must include an intent filter + * for this action and specify the desired tech types in a + * manifest <code>meta-data</code> entry. Here is an example manfiest entry: + * <pre> + * <activity android:name=".nfc.TechFilter" android:label="NFC/TechFilter"> + * <!-- Add a technology filter --> + * <intent-filter> + * <action android:name="android.nfc.action.TECH_DISCOVERED" /> + * </intent-filter> + * + * <meta-data android:name="android.nfc.action.TECH_DISCOVERED" + * android:resource="@xml/filter_nfc" + * /> + * </activity> + * </pre> + * + * <p>The meta-data XML file should contain one or more <code>tech-list</code> entries + * each consisting or one or more <code>tech</code> entries. The <code>tech</code> entries refer + * to the qualified class name implementing the technology, for example "android.nfc.tech.NfcA". + * + * <p>A tag matches if any of the + * <code>tech-list</code> sets is a subset of {@link Tag#getTechList() Tag.getTechList()}. Each + * of the <code>tech-list</code>s is considered independently and the + * activity is considered a match is any single <code>tech-list</code> matches the tag that was + * discovered. This provides AND and OR semantics for filtering desired techs. Here is an + * example that will match any tag using {@link NfcF} or any tag using {@link NfcA}, + * {@link MifareClassic}, and {@link Ndef}: + * + * <pre> + * <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + * <!-- capture anything using NfcF --> + * <tech-list> + * <tech>android.nfc.tech.NfcF</tech> + * </tech-list> + * + * <!-- OR --> * - * This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before - * {@link #ACTION_TAG_DISCOVERED} + * <!-- capture all MIFARE Classics with NDEF payloads --> + * <tech-list> + * <tech>android.nfc.tech.NfcA</tech> + * <tech>android.nfc.tech.MifareClassic</tech> + * <tech>android.nfc.tech.Ndef</tech> + * </tech-list> + * </resources> + * </pre> * - * If any activities respond to this intent {@link #ACTION_TAG_DISCOVERED} will not be started. + * <p>This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before + * {@link #ACTION_TAG_DISCOVERED}. If any activities respond to {@link #ACTION_NDEF_DISCOVERED} + * this intent will not be started. If any activities respond to this intent + * {@link #ACTION_TAG_DISCOVERED} will not be started. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED"; /** * Intent to start an activity when a tag is discovered. + * + * <p>This intent will not be started when a tag is discovered if any activities respond to + * {@link #ACTION_NDEF_DISCOVERED} or {@link #ACTION_TECH_DISCOVERED} for the current tag. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED"; @@ -78,17 +136,23 @@ public final class NfcAdapter { public static final String ACTION_TAG_LEFT_FIELD = "android.nfc.action.TAG_LOST"; /** - * Mandatory Tag extra for the ACTION_TAG intents. + * Mandatory extra containing the {@link Tag} that was discovered for the + * {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and + * {@link #ACTION_TAG_DISCOVERED} intents. */ public static final String EXTRA_TAG = "android.nfc.extra.TAG"; /** - * Optional NdefMessage[] extra for the ACTION_TAG intents. + * Optional extra containing an array of {@link NdefMessage} present on the discovered tag for + * the {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and + * {@link #ACTION_TAG_DISCOVERED} intents. */ public static final String EXTRA_NDEF_MESSAGES = "android.nfc.extra.NDEF_MESSAGES"; /** - * Optional byte[] extra for the tag identifier. + * Optional extra containing a byte array containing the ID of the discovered tag for + * the {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED}, and + * {@link #ACTION_TAG_DISCOVERED} intents. */ public static final String EXTRA_ID = "android.nfc.extra.ID"; @@ -359,14 +423,13 @@ public final class NfcAdapter { /** * Return true if this NFC Adapter has any features enabled. - * <p> - * If this method returns false, then applications should request the user - * turn on NFC tag discovery in Settings. - * <p> - * If this method returns false, the NFC hardware is guaranteed not to - * perform or respond to any NFC communication. * - * @return true if this NFC Adapter is enabled to discover new tags + * <p>Application may use this as a helper to suggest that the user + * should turn on NFC in Settings. + * <p>If this method returns false, the NFC hardware is guaranteed not to + * generate or respond to any NFC transactions. + * + * @return true if this NFC Adapter has any features enabled */ public boolean isEnabled() { try { @@ -414,17 +477,37 @@ public final class NfcAdapter { } /** - * Enables foreground dispatching to the given Activity. This will force all NFC Intents that - * match the given filters to be delivered to the activity bypassing the standard dispatch - * mechanism. If no IntentFilters are given all the PendingIntent will be invoked for every - * dispatch Intent. + * Enable foreground dispatch to the given Activity. + * + * <p>This will give give priority to the foreground activity when + * dispatching a discovered {@link Tag} to an application. + * + * <p>If any IntentFilters are provided to this method they are used to match dispatch Intents + * for both the {@link NfcAdapter#ACTION_NDEF_DISCOVERED} and + * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. Since {@link NfcAdapter#ACTION_TECH_DISCOVERED} + * relies on meta data outside of the IntentFilter matching for that dispatch Intent is handled + * by passing in the tech lists separately. Each first level entry in the tech list represents + * an array of technologies that must all be present to match. If any of the first level sets + * match then the dispatch is routed through the given PendingIntent. In other words, the second + * level is ANDed together and the first level entries are ORed together. * - * This method must be called from the main thread. + * <p>If you pass {@code null} for both the {@code filters} and {@code techLists} parameters + * that acts a wild card and will cause the foreground activity to receive all tags via the + * {@link NfcAdapter#ACTION_TAG_DISCOVERED} intent. + * + * <p>This method must be called from the main thread, and only when the activity is in the + * foreground (resumed). Also, activities must call {@link #disableForegroundDispatch} before + * the completion of their {@link Activity#onPause} callback to disable foreground dispatch + * after it has been enabled. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. * * @param activity the Activity to dispatch to * @param intent the PendingIntent to start for the dispatch * @param filters the IntentFilters to override dispatching for, or null to always dispatch - * @throws IllegalStateException + * @param techLists the tech lists used to perform matching for dispatching of the + * {@link NfcAdapter#ACTION_TECH_DISCOVERED} intent + * @throws IllegalStateException if the Activity is not currently in the foreground */ public void enableForegroundDispatch(Activity activity, PendingIntent intent, IntentFilter[] filters, String[][] techLists) { @@ -450,13 +533,18 @@ public final class NfcAdapter { } /** - * Disables foreground activity dispatching setup with - * {@link #enableForegroundDispatch}. + * Disable foreground dispatch to the given activity. * - * <p>This must be called before the Activity returns from - * it's <code>onPause()</code> or this method will throw an IllegalStateException. + * <p>After calling {@link #enableForegroundDispatch}, an activity + * must call this method before its {@link Activity#onPause} callback + * completes. * * <p>This method must be called from the main thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param activity the Activity to disable dispatch to + * @throws IllegalStateException if the Activity has already been paused */ public void disableForegroundDispatch(Activity activity) { ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity, @@ -484,13 +572,24 @@ public final class NfcAdapter { } /** - * Enable NDEF message push over P2P while this Activity is in the foreground. For this to - * function properly the other NFC device being scanned must support the "com.android.npp" - * NDEF push protocol. + * Enable NDEF message push over P2P while this Activity is in the foreground. + * + * <p>For this to function properly the other NFC device being scanned must + * support the "com.android.npp" NDEF push protocol. Support for this + * protocol is currently optional for Android NFC devices. * - * <p><em>NOTE</em> While foreground NDEF push is active standard tag dispatch is disabled. + * <p>This method must be called from the main thread. + * + * <p class="note"><em>NOTE:</em> While foreground NDEF push is active standard tag dispatch is disabled. * Only the foreground activity may receive tag discovered dispatches via * {@link #enableForegroundDispatch}. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param activity the foreground Activity + * @param msg a NDEF Message to push over P2P + * @throws IllegalStateException if the Activity is not currently in the foreground + * @throws OperationNotSupportedException if this Android device does not support NDEF push */ public void enableForegroundNdefPush(Activity activity, NdefMessage msg) { if (activity == null || msg == null) { @@ -510,13 +609,19 @@ public final class NfcAdapter { } /** - * Disables foreground NDEF push setup with - * {@link #enableForegroundNdefPush}. + * Disable NDEF message push over P2P. * - * <p>This must be called before the Activity returns from - * it's <code>onPause()</code> or this method will throw an IllegalStateException. + * <p>After calling {@link #enableForegroundNdefPush}, an activity + * must call this method before its {@link Activity#onPause} callback + * completes. * * <p>This method must be called from the main thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param activity the Foreground activity + * @throws IllegalStateException if the Activity has already been paused + * @throws OperationNotSupportedException if this Android device does not support NDEF push */ public void disableForegroundNdefPush(Activity activity) { ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity, diff --git a/core/java/android/nfc/NfcSecureElement.java b/core/java/android/nfc/NfcSecureElement.java index ea2846ea9959..3b5f39eaac8a 100755 --- a/core/java/android/nfc/NfcSecureElement.java +++ b/core/java/android/nfc/NfcSecureElement.java @@ -35,8 +35,8 @@ public final class NfcSecureElement { private static final String TAG = "NfcSecureElement"; private INfcSecureElement mService; - - + + /** * @hide */ @@ -68,7 +68,7 @@ public final class NfcSecureElement { public byte [] exchangeAPDU(int handle,byte [] data) throws IOException { - + // Perform exchange APDU try { @@ -85,7 +85,7 @@ public final class NfcSecureElement { } public void closeSecureElementConnection(int handle) throws IOException { - + try { int status = mService.closeSecureElementConnection(handle); // Handle potential errors @@ -96,14 +96,14 @@ public final class NfcSecureElement { 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 { @@ -113,16 +113,16 @@ public final class NfcSecureElement { return null; } } - + /** * Returns Secure Element UID. - * + * * @return Secure Element UID. */ public byte[] getSecureElementUid(int handle) throws IOException { - + byte[] uid = null; - try { + try { uid = mService.getSecureElementUid(handle); // Handle potential errors if (uid == null) { diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java index 45a34470c283..b676975b297f 100644 --- a/core/java/android/nfc/Tag.java +++ b/core/java/android/nfc/Tag.java @@ -16,6 +16,7 @@ package android.nfc; +import android.content.Context; import android.nfc.tech.IsoDep; import android.nfc.tech.MifareClassic; import android.nfc.tech.MifareUltralight; @@ -33,27 +34,76 @@ import android.os.Parcelable; import java.util.Arrays; /** - * Represents a (generic) discovered tag. + * Represents an NFC tag that has been discovered. * <p> - * A tag is a passive NFC element, such as NFC Forum Tag's, MIFARE class Tags, - * Sony FeliCa Tags, etc. + * {@link Tag} is an immutable object that represents the state of a NFC tag at + * the time of discovery. It can be used as a handle to {@link TagTechnology} classes + * to perform advanced operations, or directly queried for its ID via {@link #getId} and the + * set of technologies it contains via {@link #getTechList}. Arrays passed to and + * returned by this class are <em>not</em> cloned, so be careful not to modify them. * <p> - * Tag's have a type and usually have a UID. + * A new tag object is created every time a tag is discovered (comes into range), even + * if it is the same physical tag. If a tag is removed and then returned into range, then + * only the most recent tag object can be successfully used to create a {@link TagTechnology}. + * + * <h3>Tag Dispatch</h3> + * When a tag is discovered, a {@link Tag} object is created and passed to a + * single activity via the {@link NfcAdapter#EXTRA_TAG} extra in an + * {@link android.content.Intent} via {@link Context#startActivity}. A four stage dispatch is used + * to select the + * most appropriate activity to handle the tag. The Android OS executes each stage in order, + * and completes dispatch as soon as a single matching activity is found. If there are multiple + * matching activities found at any one stage then the Android activity chooser dialog is shown + * to allow the user to select the activity to receive the tag. + * + * <p>The Tag dispatch mechanism was designed to give a high probability of dispatching + * a tag to the correct activity without showing the user an activity chooser dialog. + * This is important for NFC interactions because they are very transient -- if a user has to + * move the Android device to choose an application then the connection will likely be broken. + * + * <h4>1. Foreground activity dispatch</h4> + * A foreground activity that has called + * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} is + * given priority. See the documentation on + * {@link NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} for + * its usage. + * <h4>2. NDEF data dispatch</h4> + * If the tag contains NDEF data the system inspects the first {@link NdefRecord} in the first + * {@link NdefMessage}. If the record is a URI, SmartPoster, or MIME data + * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_NDEF_DISCOVERED}. For URI + * and SmartPoster records the URI is put into the intent's data field. For MIME records the MIME + * type is put in the intent's type field. This allows activities to register to be launched only + * when data they know how to handle is present on a tag. This is the preferred method of handling + * data on a tag since NDEF data can be stored on many types of tags and doesn't depend on a + * specific tag technology. + * See {@link NfcAdapter#ACTION_NDEF_DISCOVERED} for more detail. If the tag does not contain + * NDEF data, or if no activity is registered + * for {@link NfcAdapter#ACTION_NDEF_DISCOVERED} with a matching data URI or MIME type then dispatch + * moves to stage 3. + * <h4>3. Tag Technology dispatch</h4> + * {@link Context#startActivity} is called with {@link NfcAdapter#ACTION_TECH_DISCOVERED} to + * dispatch the tag to an activity that can handle the technologies present on the tag. + * Technologies are defined as sub-classes of {@link TagTechnology}, see the package + * {@link android.nfc.tech}. The Android OS looks for an activity that can handle one or + * more technologies in the tag. See {@link NfcAdapter#ACTION_TECH_DISCOVERED} for more detail. + * <h4>4. Fall-back dispatch</h4> + * If no activity has been matched then {@link Context#startActivity} is called with + * {@link NfcAdapter#ACTION_TAG_DISCOVERED}. This is intended as a fall-back mechanism. + * See {@link NfcAdapter#ACTION_TAG_DISCOVERED}. + * + * <h3>NFC Tag Background</h3> + * An NFC tag is a passive NFC device, powered by the NFC field of this Android device while + * it is in range. Tag's can come in many forms, such as stickers, cards, key fobs, or + * even embedded in a more sophisticated device. * <p> - * {@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 TagTechnology} using the - * static <code>get()</code> methods on the varios tech classes. + * Tags can have a wide range of capabilities. Simple tags just offer read/write semantics, + * and contain some one time + * programmable areas to make read-only. More complex tags offer math operations + * and per-sector access control and authentication. The most sophisticated tags + * contain operating environments allowing complex interactions with the + * code executing on the tag. Use {@link TagTechnology} classes to access a broad + * range of capabilities available in NFC tags. * <p> - * 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 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 - * returned by this class are *not* cloned, so be careful not to modify them. */ public final class Tag implements Parcelable { /*package*/ final byte[] mId; @@ -149,21 +199,35 @@ public final class Tag implements Parcelable { /** * Get the Tag Identifier (if it has one). - * <p>Tag ID is usually a serial number for the tag. - * - * @return ID, or null if it does not exist + * <p>The tag identifier is a low level serial number, used for anti-collision + * and identification. + * <p> Most tags have a stable unique identifier + * (UID), but some tags will generate a random ID every time they are discovered + * (RID), and there are some tags with no ID at all (the byte array will be zero-sized). + * <p> The size and format of an ID is specific to the RF technology used by the tag. + * <p> This function retrieves the ID as determined at discovery time, and does not + * perform any further RF communication or block. + * @return ID as byte array, never null */ public byte[] getId() { return mId; } /** - * Returns technologies present in the tag that this implementation understands, - * or a zero length array if there are no supported technologies on this tag. - * - * The elements of the list are the names of the classes implementing the technology. - * + * Get the technologies available in this tag, as fully qualified class names. + * <p> + * A technology is an implementation of the {@link TagTechnology} interface, + * and can be instantiated by calling the static <code>get(Tag)</code> + * method on the implementation with this Tag. The {@link TagTechnology} + * object can then be used to perform advanced, technology-specific operations on a tag. + * <p> + * Android defines a mandatory set of technologies that must be correctly + * enumerated by all Android NFC devices, and an optional + * set of proprietary technologies. + * See {@link TagTechnology} for more details. + * <p> * The ordering of the returned array is undefined and should not be relied upon. + * @return an array of fully-qualified {@link TagTechnology} class-names. */ public String[] getTechList() { return mTechStringList; @@ -176,7 +240,7 @@ public final class Tag implements Parcelable { } return false; } - + /** @hide */ public Bundle getTechExtras(int tech) { int pos = -1; @@ -198,6 +262,9 @@ public final class Tag implements Parcelable { return mTagService; } + /** + * Human-readable description of the tag, for debugging. + */ @Override public String toString() { StringBuilder sb = new StringBuilder("TAG ") diff --git a/core/java/android/nfc/tech/IsoDep.java b/core/java/android/nfc/tech/IsoDep.java index 774982ed88e6..9c3074ba4e2f 100644 --- a/core/java/android/nfc/tech/IsoDep.java +++ b/core/java/android/nfc/tech/IsoDep.java @@ -24,18 +24,17 @@ import android.util.Log; import java.io.IOException; /** - * A low-level connection to a {@link Tag} using the ISO-DEP technology, also known as - * ISO1443-4. + * Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations on a {@link Tag}. * - * <p>You can acquire this kind of connection with {@link #get}. - * Use this class to send and receive data with {@link #transceive transceive()}. + * <p>Acquire an {@link IsoDep} object using {@link #get}. + * <p>The primary ISO-DEP I/O operation is {@link #transceive}. Applications must + * implement their own protocol stack on top of {@link #transceive}. + * <p>Tags that enumerate the {@link IsoDep} technology in {@link Tag#getTechList} + * will also enumerate + * {@link NfcA} or {@link NfcB} (since IsoDep builds on top of either of these). * - * <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. + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class IsoDep extends BasicTagTechnology { private static final String TAG = "NFC"; @@ -49,10 +48,13 @@ public final class IsoDep extends BasicTagTechnology { private byte[] mHistBytes = null; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link IsoDep} for the given tag. + * <p>Does not cause any RF activity and does not block. + * <p>Returns null if {@link IsoDep} was not enumerated in {@link Tag#getTechList}. + * This indicates the tag does not support ISO-DEP. * - * @param tag The tag to get the tech from + * @param tag an ISO-DEP compatible tag + * @return ISO-DEP object */ public static IsoDep get(Tag tag) { if (!tag.hasTech(TagTechnology.ISO_DEP)) return null; @@ -62,7 +64,7 @@ public final class IsoDep extends BasicTagTechnology { return null; } } - + /** @hide */ public IsoDep(Tag tag) throws RemoteException { @@ -75,13 +77,16 @@ public final class IsoDep extends BasicTagTechnology { } /** - * Sets the timeout of an IsoDep transceive transaction in milliseconds. - * If the transaction has not completed before the timeout, - * any ongoing {@link #transceive} operation will be - * aborted and the connection to the tag is lost. This setting is applied - * only to the {@link Tag} object linked to this technology and will be - * reset when {@link IsoDep#close} is called. - * The default transaction timeout is 300 milliseconds. + * Set the timeout of {@link #transceive} in milliseconds. + * <p>The timeout only applies to ISO-DEP {@link #transceive}, and is + * reset to a default value when {@link #close} is called. + * <p>Setting a longer timeout may be useful when performing + * transactions that require a long processing time on the tag + * such as key generation. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param timeout timeout value in milliseconds */ public void setTimeout(int timeout) { try { @@ -102,29 +107,53 @@ public final class IsoDep extends BasicTagTechnology { } /** - * Return the historical bytes if the tag is using {@link NfcA}, null otherwise. + * Return the ISO-DEP historical bytes for {@link NfcA} tags. + * <p>Does not cause any RF activity and does not block. + * <p>The historical bytes can be used to help identify a tag. They are present + * only on {@link IsoDep} tags that are based on {@link NfcA} RF technology. + * If this tag is not {@link NfcA} then null is returned. + * <p>In ISO 14443-4 terminology, the historical bytes are a subset of the RATS + * response. + * + * @return ISO-DEP historical bytes, or null if this is not a {@link NfcA} tag */ public byte[] getHistoricalBytes() { return mHistBytes; } /** - * Return the hi layer response bytes if the tag is using {@link NfcB}, null otherwise. + * Return the higher layer response bytes for {@link NfcB} tags. + * <p>Does not cause any RF activity and does not block. + * <p>The higher layer response bytes can be used to help identify a tag. + * They are present only on {@link IsoDep} tags that are based on {@link NfcB} + * RF technology. If this tag is not {@link NfcB} then null is returned. + * <p>In ISO 14443-4 terminology, the higher layer bytes are a subset of the + * ATTRIB response. + * + * @return ISO-DEP historical bytes, or null if this is not a {@link NfcB} tag */ public byte[] getHiLayerResponse() { return mHiLayerResponse; } /** - * Send data to a tag and receive the response. - * <p> - * This method will block until the response is received. It can be canceled - * with {@link #close}. - * <p>Requires {@link android.Manifest.permission#NFC} permission. + * Send raw ISO-DEP data to the tag and receive the response. + * + * <p>Applications must only send the INF payload, and not the start of frame and + * end of frame indicators. Applications do not need to fragment the payload, it + * will be automatically fragmented and defragmented by {@link #transceive} if + * it exceeds FSD/FSC limits. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. * - * @param data bytes to send - * @return bytes received in response - * @throws IOException if the target is lost or connection closed + * @param data command bytes to send, must not be null + * @return response bytes received, will not be null + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or this operation is canceled */ public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java index d337eada0a6c..9a2f2bd5124b 100644 --- a/core/java/android/nfc/tech/MifareClassic.java +++ b/core/java/android/nfc/tech/MifareClassic.java @@ -25,32 +25,64 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; /** - * Technology class representing MIFARE Classic tags (also known as MIFARE Standard). + * Provides access to MIFARE Classic properties and I/O operations on a {@link Tag}. * - * <p>Support for this technology type is optional. If the NFC stack doesn't support this technology - * MIFARE Classic tags will still be scanned, but will only show the NfcA technology. + * <p>Acquire a {@link MifareClassic} object using {@link #get}. * - * <p>MIFARE Classic tags have sectors that each contain blocks. The block size is constant at - * 16 bytes, but the number of sectors and the sector size varies by product. MIFARE has encryption - * built in and each sector has two keys associated with it, as well as ACLs to determine what - * level acess each key grants. Before operating on a sector you must call either - * {@link #authenticateSectorWithKeyA(int, byte[])} or - * {@link #authenticateSectorWithKeyB(int, byte[])} to gain authorization for your request. + * <p>MIFARE Classic is also known as MIFARE Standard. + * <p>MIFARE Classic tags are divided into sectors, and each sector is sub-divided into + * blocks. Block size is always 16 bytes ({@link #BLOCK_SIZE}. Sector size varies. + * <ul> + * <li>MIFARE Classic Mini are 320 bytes ({@link #SIZE_MINI}), with 5 sectors each of 4 blocks. + * <li>MIFARE Classic 1k are 1024 bytes ({@link #SIZE_1K}), with 16 sectors each of 4 blocks. + * <li>MIFARE Classic 2k are 2048 bytes ({@link #SIZE_2K}), with 32 sectors each of 4 blocks. + * <li>MIFARE Classic 4k} are 4096 bytes ({@link #SIZE_4K}). The first 32 sectors contain 4 blocks + * and the last 8 sectors contain 16 blocks. + * </ul> + * + * <p>MIFARE Classic tags require authentication on a per-sector basis before any + * other I/O operations on that sector can be performed. There are two keys per sector, + * and ACL bits determine what I/O operations are allowed on that sector after + * authenticating with a key. {@see #authenticateSectorWithKeyA} and + * {@see #authenticateSectorWithKeyB}. + * + * <p>Three well-known authentication keys are defined in this class: + * {@link #KEY_DEFAULT}, {@link #KEY_MIFARE_APPLICATION_DIRECTORY}, + * {@link #KEY_NFC_FORUM}. + * <ul> + * <li>{@link #KEY_DEFAULT} is the default factory key for MIFARE Classic. + * <li>{@link #KEY_MIFARE_APPLICATION_DIRECTORY} is the well-known key for + * MIFARE Classic cards that have been formatted according to the + * MIFARE Application Directory (MAD) specification. + * <li>{@link #KEY_NFC_FORUM} is the well-known key for MIFARE Classic cards that + * have been formatted according to the NXP specification for NDEF on MIFARE Classic. + * + * <p>Implementation of this class on a Android NFC device is optional. + * If it is not implemented, then + * {@link MifareClassic} will never be enumerated in {@link Tag#getTechList}. + * If it is enumerated, then all {@link MifareClassic} I/O operations will be supported, + * and {@link Ndef#MIFARE_CLASSIC} NDEF tags will also be supported. In either case, + * {@link NfcA} will also be enumerated on the tag, because all MIFARE Classic tags are also + * {@link NfcA}. + * + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class MifareClassic extends BasicTagTechnology { /** - * The well-known default MIFARE read key. All keys are set to this at the factory. - * Using this key will effectively make the payload in the sector public. + * The default factory key. */ 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. + * The well-known key for tags formatted according to the + * MIFARE Application Directory (MAD) specification. */ 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 + * The well-known key for tags formatted according to the + * NDEF on Mifare Classic specification. */ public static final byte[] KEY_NFC_FORUM = {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7}; @@ -64,19 +96,19 @@ public final class MifareClassic extends BasicTagTechnology { /** A MIFARE Pro tag */ public static final int TYPE_PRO = 2; - /** The tag contains 16 sectors, each holding 4 blocks. */ + /** Tag contains 16 sectors, each with 4 blocks. */ public static final int SIZE_1K = 1024; - /** The tag contains 32 sectors, each holding 4 blocks. */ + /** Tag contains 32 sectors, each with 4 blocks. */ public static final int SIZE_2K = 2048; /** - * The tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors + * Tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors * contain 16 blocks. */ public static final int SIZE_4K = 4096; - /** The tag contains 5 sectors, each holding 4 blocks. */ + /** Tag contains 5 sectors, each with 4 blocks. */ public static final int SIZE_MINI = 320; - /** Size of a Mifare Classic block (in bytes) */ + /** Size of a MIFARE Classic block (in bytes) */ public static final int BLOCK_SIZE = 16; private static final int MAX_BLOCK_COUNT = 256; @@ -87,10 +119,14 @@ public final class MifareClassic extends BasicTagTechnology { private int mSize; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link MifareClassic} for the given tag. + * <p>Does not cause any RF activity and does not block. + * <p>Returns null if {@link MifareClassic} was not enumerated in {@link Tag#getTechList}. + * This indicates the tag is not MIFARE Classic compatible, or this Android + * device does not support MIFARE Classic. * - * @param tag The tag to get the tech from + * @param tag an MIFARE Classic compatible tag + * @return MIFARE Classic object */ public static MifareClassic get(Tag tag) { if (!tag.hasTech(TagTechnology.MIFARE_CLASSIC)) return null; @@ -160,17 +196,31 @@ public final class MifareClassic extends BasicTagTechnology { } } - /** Returns the type of the tag, determined at discovery time */ + /** + * Return the type of this MIFARE Classic compatible tag. + * <p>One of {@link #TYPE_UNKNOWN}, {@link #TYPE_CLASSIC}, {@link #TYPE_PLUS} or + * {@link #TYPE_PRO}. + * <p>Does not cause any RF activity and does not block. + * + * @return type + */ public int getType() { return mType; } - /** Returns the size of the tag in bytes, determined at discovery time */ + /** + * Return the size of the tag in bytes + * <p>One of {@link #SIZE_MINI}, {@link #SIZE_1K}, {@link #SIZE_2K}, {@link #SIZE_4K}. + * These constants are equal to their respective size in bytes. + * <p>Does not cause any RF activity and does not block. + * @return size in bytes + */ public int getSize() { return mSize; } - /** Returns true if the tag is emulated, determined at discovery time. + /** + * Return true if the tag is emulated, determined at discovery time. * These are actually smart-cards that emulate a Mifare Classic interface. * They can be treated identically to a Mifare Classic tag. * @hide @@ -179,7 +229,11 @@ public final class MifareClassic extends BasicTagTechnology { return mIsEmulated; } - /** Returns the number of sectors on this tag, determined at discovery time */ + /** + * Return the number of MIFARE Classic sectors. + * <p>Does not cause any RF activity and does not block. + * @return number of sectors + */ public int getSectorCount() { switch (mSize) { case SIZE_1K: @@ -195,12 +249,22 @@ public final class MifareClassic extends BasicTagTechnology { } } - /** Returns the total block count, determined at discovery time */ + /** + * Return the total number of MIFARE Classic blocks. + * <p>Does not cause any RF activity and does not block. + * @return total number of blocks + */ public int getBlockCount() { return mSize / BLOCK_SIZE; } - /** Returns the block count for the given sector, determined at discovery time */ + /** + * Return the number of blocks in the given sector. + * <p>Does not cause any RF activity and does not block. + * + * @param sectorIndex index of sector, starting from 0 + * @return number of blocks in the sector + */ public int getBlockCountInSector(int sectorIndex) { validateSector(sectorIndex); @@ -211,7 +275,13 @@ public final class MifareClassic extends BasicTagTechnology { } } - /** Return the sector index of a given block */ + /** + * Return the sector that contains a given block. + * <p>Does not cause any RF activity and does not block. + * + * @param blockIndex index of block to lookup, starting from 0 + * @return sector index that contains the block + */ public int blockToSector(int blockIndex) { validateBlock(blockIndex); @@ -222,7 +292,13 @@ public final class MifareClassic extends BasicTagTechnology { } } - /** Return the first block of a given sector */ + /** + * Return the first block of a given sector. + * <p>Does not cause any RF activity and does not block. + * + * @param sectorIndex index of sector to lookup, starting from 0 + * @return block index of first block in sector + */ public int sectorToBlock(int sectorIndex) { if (sectorIndex < 32) { return sectorIndex * 4; @@ -231,22 +307,55 @@ public final class MifareClassic extends BasicTagTechnology { } } - // Methods that require connect() /** - * Authenticate a sector. - * <p>Every sector has an A and B key with different access privileges, - * this method attempts to authenticate against the A key. - * <p>This requires a that the tag be connected. + * Authenticate a sector with key A. + * + * <p>Successful authentication of a sector with key A enables other + * I/O operations on that sector. The set of operations granted by key A + * key depends on the ACL bits set in that sector. For more information + * see the MIFARE Classic specification on {@see http://www.nxp.com}. + * + * <p>A failed authentication attempt causes an implicit reconnection to the + * tag, so authentication to other sectors will be lost. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param sectorIndex index of sector to authenticate, starting from 0 + * @param key 6-byte authentication key + * @return true on success, false on authentication failure + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException { return authenticate(sectorIndex, key, true); } /** - * Authenticate a sector. - * <p>Every sector has an A and B key with different access privileges, - * this method attempts to authenticate against the B key. - * <p>This requires a that the tag be connected. + * Authenticate a sector with key B. + * + * <p>Successful authentication of a sector with key B enables other + * I/O operations on that sector. The set of operations granted by key B + * depends on the ACL bits set in that sector. For more information + * see the MIFARE Classic specification on {@see http://www.nxp.com}. + * + * <p>A failed authentication attempt causes an implicit reconnection to the + * tag, so authentication to other sectors will be lost. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param sectorIndex index of sector to authenticate, starting from 0 + * @param key 6-byte authentication key + * @return true on success, false on authentication failure + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException { return authenticate(sectorIndex, key, false); @@ -291,8 +400,17 @@ public final class MifareClassic extends BasicTagTechnology { /** * Read 16-byte block. - * <p>This requires a that the tag be connected. - * @throws IOException + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param blockIndex index of block to read, starting from 0 + * @return 16 byte block + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public byte[] readBlock(int blockIndex) throws IOException { validateBlock(blockIndex); @@ -304,8 +422,17 @@ public final class MifareClassic extends BasicTagTechnology { /** * Write 16-byte block. - * <p>This requires a that the tag be connected. - * @throws IOException + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param blockIndex index of block to write, starting from 0 + * @param data 16 bytes of data to write + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public void writeBlock(int blockIndex, byte[] data) throws IOException { validateBlock(blockIndex); @@ -323,9 +450,18 @@ public final class MifareClassic extends BasicTagTechnology { } /** - * Increment a value block, and store the result in temporary memory. - * @param blockIndex - * @throws IOException + * Increment a value block, storing the result in the temporary block on the tag. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param blockIndex index of block to increment, starting from 0 + * @param value non-negative to increment by + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public void increment(int blockIndex, int value) throws IOException { validateBlock(blockIndex); @@ -342,9 +478,18 @@ public final class MifareClassic extends BasicTagTechnology { } /** - * Decrement a value block, and store the result in temporary memory. - * @param blockIndex - * @throws IOException + * Decrement a value block, storing the result in the temporary block on the tag. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param blockIndex index of block to decrement, starting from 0 + * @param value non-negative to decrement by + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public void decrement(int blockIndex, int value) throws IOException { validateBlock(blockIndex); @@ -361,9 +506,17 @@ public final class MifareClassic extends BasicTagTechnology { } /** - * Copy from temporary memory to value block. - * @param blockIndex - * @throws IOException + * Copy from the temporary block to a value block. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param blockIndex index of block to copy to + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public void transfer(int blockIndex) throws IOException { validateBlock(blockIndex); @@ -375,9 +528,17 @@ public final class MifareClassic extends BasicTagTechnology { } /** - * Copy from value block to temporary memory. - * @param blockIndex - * @throws IOException + * Copy from a value block to the temporary block. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param blockIndex index of block to copy from + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public void restore(int blockIndex) throws IOException { validateBlock(blockIndex); @@ -390,15 +551,18 @@ public final class MifareClassic extends BasicTagTechnology { /** * Send raw NfcA data to a tag and receive the response. - * <p> - * This method will block until the response is received. It can be canceled - * with {@link #close}. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - * <p>This requires a that the tag be connected. - * - * @param data bytes to send - * @return bytes received in response - * @throws IOException if the target is lost or connection closed + * + * <p>This is equivalent to connecting to this tag via {@link NfcA} + * and calling {@link NfcA#transceive}. Note that all MIFARE Classic + * tags are based on {@link NfcA} technology. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @see NfcA#transceive */ public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); diff --git a/core/java/android/nfc/tech/MifareUltralight.java b/core/java/android/nfc/tech/MifareUltralight.java index b514f1c160d6..f7fee72e2d6b 100644 --- a/core/java/android/nfc/tech/MifareUltralight.java +++ b/core/java/android/nfc/tech/MifareUltralight.java @@ -17,6 +17,7 @@ package android.nfc.tech; import android.nfc.Tag; +import android.nfc.TagLostException; import android.os.RemoteException; import java.io.IOException; @@ -24,14 +25,13 @@ import java.io.IOException; //TOOD: Ultralight C 3-DES authentication, one-way counter /** - * Technology class representing MIFARE Ultralight and MIFARE Ultralight C tags. + * Provides access to MIFARE Ultralight properties and I/O operations on a {@link Tag}. * - * <p>Support for this technology type is optional. If the NFC stack doesn't support this technology - * MIFARE Ultralight class tags will still be scanned, but will only show the NfcA technology. + * <p>Acquire a {@link MifareUltralight} object using {@link #get}. * - * <p>MIFARE Ultralight compatible tags have 4 byte pages. The read command - * returns 4 pages (16 bytes) at a time, for speed. The write command operates - * on a single page (4 bytes) to minimize EEPROM write cycles. + * <p>MIFARE Ultralight compatible tags have 4 byte pages {@link #PAGE_SIZE}. + * The primary operations on an Ultralight tag are {@link #readPages} and + * {@link #writePage}. * * <p>The original MIFARE Ultralight consists of a 64 byte EEPROM. The first * 4 pages are for the OTP area, manufacturer data, and locking bits. They are @@ -44,6 +44,16 @@ import java.io.IOException; * and authentication configuration and are readable. The final 4 pages are for * the authentication key and are not readable. For more information see the * NXP data sheet MF0ICU2. + * + * <p>Implementation of this class on a Android NFC device is optional. + * If it is not implemented, then + * {@link MifareUltralight} will never be enumerated in {@link Tag#getTechList}. + * If it is enumerated, then all {@link MifareUltralight} I/O operations will be supported. + * In either case, {@link NfcA} will also be enumerated on the tag, + * because all MIFARE Ultralight tags are also {@link NfcA} tags. + * + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class MifareUltralight extends BasicTagTechnology { /** A MIFARE Ultralight compatible tag of unknown type */ @@ -62,10 +72,15 @@ public final class MifareUltralight extends BasicTagTechnology { private int mType; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link MifareUltralight} for the given tag. + * <p>Returns null if {@link MifareUltralight} was not enumerated in + * {@link Tag#getTechList} - this indicates the tag is not MIFARE + * Ultralight compatible, or that this Android + * device does not implement MIFARE Ultralight. + * <p>Does not cause any RF activity and does not block. * - * @param tag The tag to get the tech from + * @param tag an MIFARE Ultralight compatible tag + * @return MIFARE Ultralight object */ public static MifareUltralight get(Tag tag) { if (!tag.hasTech(TagTechnology.MIFARE_ULTRALIGHT)) return null; @@ -93,28 +108,43 @@ public final class MifareUltralight extends BasicTagTechnology { } } - /** Returns the type of the tag. - * <p>It is very hard to always accurately classify a MIFARE Ultralight - * compatible tag as Ultralight original or Ultralight C. So consider - * {@link #getType} a hint. */ + /** + * Return the MIFARE Ultralight type of the tag. + * <p>One of {@link #TYPE_ULTRALIGHT} or {@link #TYPE_ULTRALIGHT_C} or + * {@link #TYPE_UNKNOWN}. + * <p>Depending on how the tag has been formatted, it can be impossible + * to accurately classify between original MIFARE Ultralight and + * Ultralight C. So treat this method as a hint. + * <p>Does not cause any RF activity and does not block. + * + * @return the type + */ public int getType() { return mType; } - // Methods that require connect() /** * Read 4 pages (16 bytes). - * <p>The MIFARE Ultralight protocol always reads 4 pages at a time. - * <p>If the read spans past the last readable block, then the tag will + * + * <p>The MIFARE Ultralight protocol always reads 4 pages at a time, to + * reduce the number of commands required to read an entire tag. + * <p>If a read spans past the last readable block, then the tag will * return pages that have been wrapped back to the first blocks. MIFARE * Ultralight tags have readable blocks 0x00 through 0x0F. So a read to * block offset 0x0E would return blocks 0x0E, 0x0F, 0x00, 0x01. MIFARE * Ultralight C tags have readable blocks 0x00 through 0x2B. So a read to * block 0x2A would return blocks 0x2A, 0x2B, 0x00, 0x01. - * <p>This requires that the tag be connected. * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param pageOffset index of first page to read, starting from 0 * @return 4 pages (16 bytes) - * @throws IOException + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public byte[] readPages(int pageOffset) throws IOException { validatePageOffset(pageOffset); @@ -126,12 +156,20 @@ public final class MifareUltralight extends BasicTagTechnology { /** * Write 1 page (4 bytes). - * <p>The MIFARE Ultralight protocol always writes 1 page at a time. - * <p>This requires that the tag be connected. * - * @param pageOffset The offset of the page to write - * @param data The data to write - * @throws IOException + * <p>The MIFARE Ultralight protocol always writes 1 page at a time, to + * minimize EEPROM write cycles. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param pageOffset index of page to write, starting from 0 + * @param data 4 bytes to write + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public void writePage(int pageOffset, byte[] data) throws IOException { validatePageOffset(pageOffset); @@ -147,15 +185,18 @@ public final class MifareUltralight extends BasicTagTechnology { /** * Send raw NfcA data to a tag and receive the response. - * <p> - * This method will block until the response is received. It can be canceled - * with {@link #close}. - * <p>Requires {@link android.Manifest.permission#NFC} permission. - * <p>This requires a that the tag be connected. * - * @param data bytes to send - * @return bytes received in response - * @throws IOException if the target is lost or connection closed + * <p>This is equivalent to connecting to this tag via {@link NfcA} + * and calling {@link NfcA#transceive}. Note that all MIFARE Classic + * tags are based on {@link NfcA} technology. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @see NfcA#transceive */ public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java index 39ff28284154..6727d6ad5090 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/core/java/android/nfc/tech/Ndef.java @@ -22,6 +22,7 @@ import android.nfc.INfcTag; import android.nfc.NdefMessage; import android.nfc.NfcAdapter; import android.nfc.Tag; +import android.nfc.TagLostException; import android.os.Bundle; import android.os.RemoteException; import android.util.Log; @@ -29,15 +30,44 @@ import android.util.Log; import java.io.IOException; /** - * A high-level connection to a {@link Tag} using one of the NFC type 1, 2, 3, or 4 technologies - * to interact with NDEF data. MiFare Classic cards that present NDEF data may also be used - * via this class. To determine the exact technology being used call {@link #getType()} + * Provides access to NDEF content and operations on a {@link Tag}. * - * <p>You can acquire this kind of connection with {@link #get}. + * <p>Acquire a {@link Ndef} object using {@link #get}. * - * <p class="note"><strong>Note:</strong> - * Use of this class requires the {@link android.Manifest.permission#NFC} - * permission. + * <p>NDEF is an NFC Forum data format. The data formats are implemented in + * {@link android.nfc.NdefMessage} and + * {@link android.nfc.NdefRecord}. This class provides methods to + * retrieve and modify the {@link android.nfc.NdefMessage} + * on a tag. + * + * <p>There are currently four NFC Forum standardized tag types that can be + * formatted to contain NDEF data. + * <ul> + * <li>NFC Forum Type 1 Tag ({@link #NFC_FORUM_TYPE_1}), such as the Innovision Topaz + * <li>NFC Forum Type 2 Tag ({@link #NFC_FORUM_TYPE_2}), such as the NXP MIFARE Ultralight + * <li>NFC Forum Type 3 Tag ({@link #NFC_FORUM_TYPE_3}), such as Sony Felica + * <li>NFC Forum Type 4 Tag ({@link #NFC_FORUM_TYPE_4}), such as NXP MIFARE Desfire + * </ul> + * It is mandatory for all Android devices with NFC to correctly enumerate + * {@link Ndef} on NFC Forum Tag Types 1-4, and implement all NDEF operations + * as defined in this class. + * + * <p>Some vendors have there own well defined specifications for storing NDEF data + * on tags that do not fall into the above categories. Android devices with NFC + * should enumerate and implement {@link Ndef} under these vendor specifications + * where possible, but it is not mandatory. {@link #getType} returns a String + * describing this specification, for example {@link #MIFARE_CLASSIC} is + * <code>com.nxp.ndef.mifareclassic</code>. + * + * <p>Android devices that support MIFARE Classic must also correctly + * implement {@link Ndef} on MIFARE Classic tags formatted to NDEF. + * + * <p>For guaranteed compatibility across all Android devices with NFC, it is + * recommended to use NFC Forum Types 1-4 in new deployments of NFC tags + * with NDEF payload. Vendor NDEF formats will not work on all Android devices. + * + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class Ndef extends BasicTagTechnology { private static final String TAG = "NFC"; @@ -77,14 +107,15 @@ public final class Ndef extends BasicTagTechnology { /** @hide */ public static final String UNKNOWN = "android.ndef.unknown"; + /** NFC Forum Tag Type 1 */ public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1"; - + /** NFC Forum Tag Type 2 */ public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2"; - + /** NFC Forum Tag Type 4 */ public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3"; - + /** NFC Forum Tag Type 4 */ public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4"; - + /** NDEF on MIFARE Classic */ public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic"; private final int mMaxNdefSize; @@ -93,10 +124,17 @@ public final class Ndef extends BasicTagTechnology { private final int mNdefType; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link Ndef} for the given tag. * - * @param tag The tag to get the tech from + * <p>Returns null if {@link Ndef} was not enumerated in {@link Tag#getTechList}. + * This indicates the tag is not NDEF formatted, or that this tag + * is NDEF formatted but under a vendor specification that this Android + * device does not implement. + * + * <p>Does not cause any RF activity and does not block. + * + * @param tag an MIFARE Classic compatible tag + * @return MIFARE Classic object */ public static Ndef get(Tag tag) { if (!tag.hasTech(TagTechnology.NDEF)) return null; @@ -126,22 +164,29 @@ public final class Ndef extends BasicTagTechnology { } /** - * Get the primary NDEF message on this tag. This data is read at discovery time - * and does not require a connection. + * Get the {@link NdefMessage} that was read from the tag at discovery time. + * + * <p>If the NDEF Message is modified by an I/O operation then it + * will not be updated here, this function only returns what was discovered + * when the tag entered the field. + * <p>Does not cause any RF activity and does not block. + * @return NDEF Message read from the tag at discovery time */ public NdefMessage getCachedNdefMessage() { return mNdefMsg; } /** - * Get NDEF tag type. + * Get the NDEF tag type. + * * <p>Returns one of {@link #NFC_FORUM_TYPE_1}, {@link #NFC_FORUM_TYPE_2}, * {@link #NFC_FORUM_TYPE_3}, {@link #NFC_FORUM_TYPE_4}, - * {@link #MIFARE_CLASSIC} or another NDEF tag type that is not yet in the - * Android API. - * <p>Android devices with NFC support must always correctly enumerate - * NFC Forum tag types, and may optionally enumerate - * {@link #MIFARE_CLASSIC} since it requires proprietary technology. + * {@link #MIFARE_CLASSIC} or another NDEF tag type that has not yet been + * formalized in this Android API. + * + * <p>Does not cause any RF activity and does not block. + * + * @return a string representing the NDEF tag type */ public String getType() { switch (mNdefType) { @@ -161,25 +206,44 @@ public final class Ndef extends BasicTagTechnology { } /** - * Get maximum NDEF message size in bytes + * Get the maximum NDEF message size in bytes. + * + * <p>Does not cause any RF activity and does not block. + * + * @return size in bytes */ public int getMaxSize() { return mMaxNdefSize; } /** - * Provides a hint on whether writes are likely to succeed. + * Determine if the tag is writable. + * + * <p>NFC Forum tags can be in read-only or read-write states. + * + * <p>Does not cause any RF activity and does not block. + * * <p>Requires {@link android.Manifest.permission#NFC} permission. - * @return true if write is likely to succeed + * + * @return true if the tag is writable */ public boolean isWritable() { return (mCardState == NDEF_MODE_READ_WRITE); } - // Methods that require connect() /** - * Get the primary NDEF message on this tag. This data is read actively - * and requires a connection. + * Read the current {@link android.nfc.NdefMessage} on this tag. + * + * <p>This always reads the current NDEF Message stored on the tag. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * @return the NDEF Message, never null + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled + * @throws FormatException if the NDEF Message on the tag is malformed */ public NdefMessage getNdefMessage() throws IOException, FormatException { checkConnected(); @@ -212,8 +276,18 @@ public final class Ndef extends BasicTagTechnology { } /** - * Overwrite the primary NDEF message - * @throws IOException + * Overwrite the {@link NdefMessage} on this tag. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param msg the NDEF Message to write, must not be null + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled + * @throws FormatException if the NDEF Message to write is malformed */ public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException { checkConnected(); @@ -244,8 +318,11 @@ public final class Ndef extends BasicTagTechnology { } /** - * Indicates whether a tag can be made read-only with - * {@link #makeReadOnly()} + * Indicates whether a tag can be made read-only with {@link #makeReadOnly()}. + * + * <p>Does not cause any RF activity and does not block. + * + * @return true if it is possible to make this tag read-only */ public boolean canMakeReadOnly() { if (mNdefType == TYPE_1 || mNdefType == TYPE_2) { @@ -256,11 +333,22 @@ public final class Ndef extends BasicTagTechnology { } /** - * Sets the CC field to indicate this tag is read-only - * and permanently sets the lock bits to prevent any further NDEF - * modifications. - * This is a one-way process and can not be reverted! - * @throws IOException + * Make a tag read-only. + * + * <p>This sets the CC field to indicate the tag is read-only, + * and where possible permanently sets the lock bits to prevent + * any further modification of the memory. + * <p>This is a one-way process and cannot be reverted! + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @return true on success, false if it is not possible to make this tag read-only + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled */ public boolean makeReadOnly() throws IOException { checkConnected(); diff --git a/core/java/android/nfc/tech/NdefFormatable.java b/core/java/android/nfc/tech/NdefFormatable.java index e2828b556e29..bb2eb943d46d 100644 --- a/core/java/android/nfc/tech/NdefFormatable.java +++ b/core/java/android/nfc/tech/NdefFormatable.java @@ -22,28 +22,39 @@ import android.nfc.INfcTag; import android.nfc.NdefMessage; import android.nfc.NfcAdapter; import android.nfc.Tag; +import android.nfc.TagLostException; import android.os.RemoteException; import android.util.Log; import java.io.IOException; /** - * An interface to a {@link Tag} allowing to format the tag as NDEF. + * Provide access to NDEF format operations on a {@link Tag}. * - * <p>You can acquire this kind of connection with {@link #get}. + * <p>Acquire a {@link NdefFormatable} object using {@link #get}. * - * <p class="note"><strong>Note:</strong> - * Use of this class requires the {@link android.Manifest.permission#NFC} - * permission. + * <p>Android devices with NFC must only enumerate and implement this + * class for tags for which it can format to NDEF. + * + * <p>Unfortunately the procedures to convert unformated tags to NDEF formatted + * tags are not specified by NFC Forum, and are not generally well-known. So + * there is no mandatory set of tags for which all Android devices with NFC + * must support {@link NdefFormatable}. + * + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class NdefFormatable extends BasicTagTechnology { private static final String TAG = "NFC"; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link NdefFormatable} for the given tag. + * <p>Does not cause any RF activity and does not block. + * <p>Returns null if {@link NdefFormatable} was not enumerated in {@link Tag#getTechList}. + * This indicates the tag is not NDEF formatable by this Android device. * - * @param tag The tag to get the tech from + * @param tag an NDEF formatable tag + * @return NDEF formatable object */ public static NdefFormatable get(Tag tag) { if (!tag.hasTech(TagTechnology.NDEF_FORMATABLE)) return null; @@ -63,20 +74,44 @@ public final class NdefFormatable extends BasicTagTechnology { } /** - * Formats a tag as NDEF, if possible. You may supply a first - * NdefMessage to be written on the tag. - * <p>Either all steps succeed, or an IOException is thrown if any one step - * fails. + * Format a tag as NDEF, and write a {@link NdefMessage}. + * + * <p>This is a multi-step process, an IOException is thrown + * if any one step fails. + * <p>The card is left in a read-write state after this operation. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param firstMessage the NDEF message to write after formatting, can be null + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled + * @throws FormatException if the NDEF Message to write is malformed */ public void format(NdefMessage firstMessage) throws IOException, FormatException { format(firstMessage, false); } /** - * Formats a tag as NDEF, if possible. You may supply a first - * NdefMessage to be written on the tag. - * <p>Either all steps succeed, or an IOException is thrown if any one step - * fails. + * Formats a tag as NDEF, write a {@link NdefMessage}, and make read-only. + * + * <p>This is a multi-step process, an IOException is thrown + * if any one step fails. + * <p>The card is left in a read-only state if this method returns successfully. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. + * + * @param firstMessage the NDEF message to write after formatting + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or the operation is canceled + * @throws FormatException if the NDEF Message to write is malformed */ public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException { format(firstMessage, true); diff --git a/core/java/android/nfc/tech/NfcA.java b/core/java/android/nfc/tech/NfcA.java index 24badc4865a5..1843eaed24db 100644 --- a/core/java/android/nfc/tech/NfcA.java +++ b/core/java/android/nfc/tech/NfcA.java @@ -23,18 +23,14 @@ import android.os.RemoteException; import java.io.IOException; /** - * A low-level connection to a {@link Tag} using the NFC-A technology, also known as - * ISO1443-3A. + * Provides access to NFC-A (ISO 14443-3A) properties and I/O operations on a {@link Tag}. * - * <p>You can acquire this kind of connection with {@link #get}. - * Use this class to send and receive data with {@link #transceive transceive()}. + * <p>Acquire a {@link NfcA} object using {@link #get}. + * <p>The primary NFC-A I/O operation is {@link #transceive}. Applications must + * implement their own protocol stack on top of {@link #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. + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class NfcA extends BasicTagTechnology { /** @hide */ @@ -46,10 +42,13 @@ public final class NfcA extends BasicTagTechnology { private byte[] mAtqa; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link NfcA} for the given tag. + * <p>Returns null if {@link NfcA} was not enumerated in {@link Tag#getTechList}. + * This indicates the tag does not support NFC-A. + * <p>Does not cause any RF activity and does not block. * - * @param tag The tag to get the tech from + * @param tag an NFC-A compatible tag + * @return NFC-A object */ public static NfcA get(Tag tag) { if (!tag.hasTech(TagTechnology.NFC_A)) return null; @@ -69,29 +68,46 @@ public final class NfcA extends BasicTagTechnology { } /** - * Returns the ATQA/SENS_RES bytes discovered at tag discovery. + * Return the ATQA/SENS_RES bytes from tag discovery. + * + * <p>Does not cause any RF activity and does not block. + * + * @return ATQA/SENS_RES bytes */ public byte[] getAtqa() { return mAtqa; } /** - * Returns the SAK/SEL_RES discovered at tag discovery. + * Return the SAK/SEL_RES bytes from tag discovery. + * + * <p>Does not cause any RF activity and does not block. + * + * @return SAK bytes */ public short getSak() { return mSak; } /** - * Send data to a tag and receive the response. - * <p> - * This method will block until the response is received. It can be canceled - * with {@link #close}. - * <p>Requires {@link android.Manifest.permission#NFC} permission. + * Send raw NFC-A commands to the tag and receive the response. + * + * <p>Applications must not append the EoD (CRC) to the payload, + * it will be automatically calculated. + * <p>Applications must only send commands that are complete bytes, + * for example a SENS_REQ is not possible (these are used to + * manage tag polling and initialization). + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. * * @param data bytes to send * @return bytes received in response - * @throws IOException if the target is lost or connection closed + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or this operation is canceled */ public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); diff --git a/core/java/android/nfc/tech/NfcB.java b/core/java/android/nfc/tech/NfcB.java index abeef32116cd..22cb11dd4763 100644 --- a/core/java/android/nfc/tech/NfcB.java +++ b/core/java/android/nfc/tech/NfcB.java @@ -23,18 +23,14 @@ import android.os.RemoteException; import java.io.IOException; /** - * A low-level connection to a {@link Tag} using the NFC-B technology, also known as - * ISO1443-3B. + * Provides access to NFC-B (ISO 14443-3B) properties and I/O operations on a {@link Tag}. * - * <p>You can acquire this kind of connection with {@link #get}. - * Use this class to send and receive data with {@link #transceive transceive()}. + * <p>Acquire a {@link NfcB} object using {@link #get}. + * <p>The primary NFC-B I/O operation is {@link #transceive}. Applications must + * implement their own protocol stack on top of {@link #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. + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class NfcB extends BasicTagTechnology { /** @hide */ @@ -46,10 +42,13 @@ public final class NfcB extends BasicTagTechnology { private byte[] mProtInfo; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link NfcB} for the given tag. + * <p>Returns null if {@link NfcB} was not enumerated in {@link Tag#getTechList}. + * This indicates the tag does not support NFC-B. + * <p>Does not cause any RF activity and does not block. * - * @param tag The tag to get the tech from + * @param tag an NFC-B compatible tag + * @return NFC-B object */ public static NfcB get(Tag tag) { if (!tag.hasTech(TagTechnology.NFC_B)) return null; @@ -69,31 +68,45 @@ public final class NfcB extends BasicTagTechnology { } /** - * Returns the Application Data bytes from the ATQB/SENSB_RES - * bytes discovered at tag discovery. + * Return the Application Data bytes from ATQB/SENSB_RES at tag discovery. + * + * <p>Does not cause any RF activity and does not block. + * + * @return Application Data bytes from ATQB/SENSB_RES bytes */ public byte[] getApplicationData() { return mAppData; } /** - * Returns the Protocol Info bytes from the ATQB/SENSB_RES - * bytes discovered at tag discovery. + * Return the Protocol Info bytes from ATQB/SENSB_RES at tag discovery. + * + * <p>Does not cause any RF activity and does not block. + * + * @return Protocol Info bytes from ATQB/SENSB_RES bytes */ public byte[] getProtocolInfo() { return mProtInfo; } /** - * Send data to a tag and receive the response. - * <p> - * This method will block until the response is received. It can be canceled - * with {@link #close}. - * <p>Requires {@link android.Manifest.permission#NFC} permission. + * Send raw NFC-B commands to the tag and receive the response. + * + * <p>Applications must not append the EoD (CRC) to the payload, + * it will be automatically calculated. + * <p>Applications must not send commands that manage the polling + * loop and initialization (SENSB_REQ, SLOT_MARKER etc). + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. * * @param data bytes to send * @return bytes received in response - * @throws IOException if the target is lost or connection closed + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or this operation is canceled */ public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); diff --git a/core/java/android/nfc/tech/NfcF.java b/core/java/android/nfc/tech/NfcF.java index f6177393b453..e0ebbe82c4e9 100644 --- a/core/java/android/nfc/tech/NfcF.java +++ b/core/java/android/nfc/tech/NfcF.java @@ -23,18 +23,14 @@ import android.os.RemoteException; import java.io.IOException; /** - * A low-level connection to a {@link Tag} using the NFC-F technology, also known as - * JIS6319-4. + * Provides access to NFC-F (JIS 6319-4) properties and I/O operations on a {@link Tag}. * - * <p>You can acquire this kind of connection with {@link #get}. - * Use this class to send and receive data with {@link #transceive transceive()}. + * <p>Acquire a {@link NfcF} object using {@link #get}. + * <p>The primary NFC-F I/O operation is {@link #transceive}. Applications must + * implement their own protocol stack on top of {@link #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. + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class NfcF extends BasicTagTechnology { /** @hide */ @@ -46,10 +42,13 @@ public final class NfcF extends BasicTagTechnology { private byte[] mManufacturer = null; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link NfcF} for the given tag. + * <p>Returns null if {@link NfcF} was not enumerated in {@link Tag#getTechList}. + * This indicates the tag does not support NFC-F. + * <p>Does not cause any RF activity and does not block. * - * @param tag The tag to get the tech from + * @param tag an NFC-F compatible tag + * @return NFC-F object */ public static NfcF get(Tag tag) { if (!tag.hasTech(TagTechnology.NFC_F)) return null; @@ -70,24 +69,44 @@ public final class NfcF extends BasicTagTechnology { } } + /** + * Return the System Code bytes from tag discovery. + * + * <p>Does not cause any RF activity and does not block. + * + * @return System Code bytes + */ public byte[] getSystemCode() { return mSystemCode; } + /** + * Return the Manufacturer bytes from tag discovery. + * + * <p>Does not cause any RF activity and does not block. + * + * @return Manufacturer bytes + */ public byte[] getManufacturer() { return mManufacturer; } /** - * Send data to a tag and receive the response. - * <p> - * This method will block until the response is received. It can be canceled - * with {@link #close}. - * <p>Requires {@link android.Manifest.permission#NFC} permission. + * Send raw NFC-F commands to the tag and receive the response. + * + * <p>Applications must not append the SoD (length) or EoD (CRC) to the payload, + * it will be automatically calculated. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. * * @param data bytes to send * @return bytes received in response - * @throws IOException if the target is lost or connection closed + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or this operation is canceled */ public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); diff --git a/core/java/android/nfc/tech/NfcV.java b/core/java/android/nfc/tech/NfcV.java index 8e1f066008af..fe721c88b048 100644 --- a/core/java/android/nfc/tech/NfcV.java +++ b/core/java/android/nfc/tech/NfcV.java @@ -23,18 +23,14 @@ import android.os.RemoteException; import java.io.IOException; /** - * A low-level connection to a {@link Tag} using NFC vicinity technology, also known as - * ISO15693. + * Provides access to NFC-V (ISO 15693) properties and I/O operations on a {@link Tag}. * - * <p>You can acquire this kind of connection with {@link #get}. - * Use this class to send and receive data with {@link #transceive transceive()}. + * <p>Acquire a {@link NfcV} object using {@link #get}. + * <p>The primary NFC-V I/O operation is {@link #transceive}. Applications must + * implement their own protocol stack on top of {@link #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. + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. */ public final class NfcV extends BasicTagTechnology { /** @hide */ @@ -47,10 +43,13 @@ public final class NfcV extends BasicTagTechnology { private byte mDsfId; /** - * Returns an instance of this tech for the given tag. If the tag doesn't support - * this tech type null is returned. + * Get an instance of {@link NfcV} for the given tag. + * <p>Returns null if {@link NfcV} was not enumerated in {@link Tag#getTechList}. + * This indicates the tag does not support NFC-V. + * <p>Does not cause any RF activity and does not block. * - * @param tag The tag to get the tech from + * @param tag an NFC-V compatible tag + * @return NFC-V object */ public static NfcV get(Tag tag) { if (!tag.hasTech(TagTechnology.NFC_V)) return null; @@ -69,24 +68,45 @@ public final class NfcV extends BasicTagTechnology { mDsfId = extras.getByte(EXTRA_DSFID); } + /** + * Return the Response Flag bytes from tag discovery. + * + * <p>Does not cause any RF activity and does not block. + * + * @return Response Flag bytes + */ public byte getResponseFlags() { return mRespFlags; } + /** + * Return the DSF ID bytes from tag discovery. + * + * <p>Does not cause any RF activity and does not block. + * + * @return DSF ID bytes + */ public byte getDsfId() { return mDsfId; } /** - * Send data to a tag and receive the response. - * <p> - * This method will block until the response is received. It can be canceled - * with {@link #close}. - * <p>Requires {@link android.Manifest.permission#NFC} permission. + * Send raw NFC-V commands to the tag and receive the response. + * + * <p>Applications must not append the CRC to the payload, + * it will be automatically calculated. The application does + * provide FLAGS, CMD and PARAMETER bytes. + * + * <p>This is an I/O operation and will block until complete. It must + * not be called from the main application thread. A blocked call will be canceled with + * {@link IOException} if {@link #close} is called from another thread. + * + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. * * @param data bytes to send * @return bytes received in response - * @throws IOException if the target is lost or connection closed + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or this operation is canceled */ public byte[] transceive(byte[] data) throws IOException { return transceive(data, true); diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java index 50df8659ae7a..be5cbd210d86 100644 --- a/core/java/android/nfc/tech/TagTechnology.java +++ b/core/java/android/nfc/tech/TagTechnology.java @@ -21,6 +21,64 @@ import android.nfc.Tag; import java.io.Closeable; import java.io.IOException; +/** + * {@link TagTechnology} is an interface to a technology in a {@link Tag}. + * <p> + * Obtain a {@link TagTechnology} implementation by calling the static method <code>get()</code> + * on the implementation class. + * <p> + * NFC tags are based on a number of independently developed technologies and offer a + * wide range of capabilities. The + * {@link TagTechnology} implementations provide access to these different + * technologies and capabilities. Some sub-classes map to technology + * specification (for example {@link NfcA}, {@link IsoDep}, others map to + * pseudo-technologies or capabilities (for example {@link Ndef}, {@link NdefFormatable}). + * <p> + * It is mandatory for all Android NFC devices to provide the following + * {@link TagTechnology} implementations. + * <ul> + * <li>{@link NfcA} (also known as ISO 14443-3A) + * <li>{@link NfcB} (also known as ISO 14443-3B) + * <li>{@link NfcF} (also known as JIS 6319-4) + * <li>{@link NfcV} (also known as ISO 15693) + * <li>{@link IsoDep} + * <li>{@link Ndef} on NFC Forum Type 1, Type 2, Type 3 or Type 4 compliant tags + * </ul> + * It is optional for Android NFC devices to provide the following + * {@link TagTechnology} implementations. If it is not provided, the + * Android device will never enumerate that class via {@link Tag#getTechList}. + * <ul> + * <li>{@link MifareClassic} + * <li>{@link MifareUltralight} + * <li>{@link NdefFormatable} must only be enumerated on tags for which this Android device + * is capable of formatting. Proprietary knowledge is often required to format a tag + * to make it NDEF compatible. + * </ul> + * <p> + * {@link TagTechnology} implementations provide methods that fall into two classes: + * <em>cached getters</em> and <em>I/O operations</em>. + * <h4>Cached getters</h4> + * These methods (usually prefixed by <code>get</code> or <code>is</code>) return + * properties of the tag, as determined at discovery time. These methods will never + * block or cause RF activity, and do not require {@link #connect} to have been called. + * They also never update, for example if a property is changed by an I/O operation with a tag + * then the cached getter will still return the result from tag discovery time. + * <h4>I/O operations</h4> + * I/O operations may require RF activity, and may block. They have the following semantics. + * <ul> + * <li>{@link #connect} must be called before using any other I/O operation. + * <li>{@link #close} must be called after completing I/O operations with a + * {@link TagTechnology}, and it will cancel all other blocked I/O operations on other threads + * (including {@link #connect} with {@link IOException}. + * <li>Only one {@link TagTechnology} can be connected at a time. Other calls to + * {@link #connect} will return {@link IOException}. + * <li>I/O operations may block, and should never be called on the main application + * thread. + * </ul> + * + * <p class="note"><strong>Note:</strong> Methods that perform I/O operations + * require the {@link android.Manifest.permission#NFC} permission. + */ public interface TagTechnology extends Closeable { /** * This technology is an instance of {@link NfcA}. @@ -90,22 +148,24 @@ public interface TagTechnology extends Closeable { public static final int MIFARE_ULTRALIGHT = 9; /** - * Get the {@link Tag} object this technology came from. + * Get the {@link Tag} object backing this {@link TagTechnology} object. + * @return the {@link Tag} backing this {@link TagTechnology} object. */ public Tag getTag(); /** - * Opens a connection to the {@link Tag} enabling interactive commands. The command set - * varies by the technology type. - * - * <p>This method blocks until the connection has been established. + * Enable I/O operations to the tag from this {@link TagTechnology} object. + * <p>May cause RF activity and may block. Must not be called + * from the main application thread. A blocked call will be canceled with + * {@link IOException} by calling {@link #close} from another thread. + * <p>Only one {@link TagTechnology} object can be connected to a {@link Tag} at a time. + * <p>Applications must call {@link #close} when I/O operations are complete. * - * <p>A call to {@link #close} from another thread will cancel a blocked call and cause an - * IOException to be thrown on the thread that is blocked. + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. * - * @see #reconnect() * @see #close() - * @throws IOException if the target is lost, or connect canceled + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or connect is canceled */ public void connect() throws IOException; @@ -113,40 +173,39 @@ public interface TagTechnology extends Closeable { * Re-connect to the {@link Tag} associated with this connection. Reconnecting to a tag can be * used to reset the state of the tag itself. * - * <p>This method blocks until the connection is re-established. + * <p>May cause RF activity and may block. Must not be called + * from the main application thread. A blocked call will be canceled with + * {@link IOException} by calling {@link #close} from another thread. * - * <p>A call to {@link #close} from another thread will cancel a blocked call and cause an - * IOException to be thrown on the thread that is blocked. + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. * * @see #connect() * @see #close() - * @throws IOException + * @throws TagLostException if the tag leaves the field + * @throws IOException if there is an I/O failure, or connect is canceled * @hide */ public void reconnect() throws IOException; /** - * Closes the connection to the {@link Tag}. This call is non-blocking and causes all blocking - * operations such as {@link #connect} to be canceled and immediately throw - * {@link java.io.IOException} on the thread that is blocked. + * Disable I/O operations to the tag from this {@link TagTechnology} object, and release resources. + * <p>Also causes all blocked I/O operations on other thread to be canceled and + * return with {@link IOException}. * - * <p> - * Once this method is called, this object cannot be re-used and should be discarded. Further - * calls to {@link #connect} will fail. + * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. * * @see #connect() - * @see #reconnect() */ public void close() throws IOException; /** - * Helper to indicate if {@link #connect} has succeeded. - * <p> - * Does not cause RF activity, and does not block. - * @return true if {@link #connect} has completed successfully and the {@link Tag} is believed - * to be within range. Applications must still handle {@link java.io.IOException} - * while using methods that require a connection in case the connection is lost after this - * method returns. + * Helper to indicate if I/O operations should be possible. + * + * <p>Returns true if {@link #connect} has completed, and {@link #close} has not been + * called, and the {@link Tag} is not known to be out of range. + * <p>Does not cause RF activity, and does not block. + * + * @return true if I/O operations should be possible */ public boolean isConnected(); } diff --git a/docs/html/sdk/android-3.0-highlights.jd b/docs/html/sdk/android-3.0-highlights.jd index 0378c35fcd60..591f08806da0 100644 --- a/docs/html/sdk/android-3.0-highlights.jd +++ b/docs/html/sdk/android-3.0-highlights.jd @@ -112,7 +112,7 @@ This document provides a glimpse of some of the new features and technologies, a <h3>New connectivity options</h3> -<p>Android 3.0 includes new connectivity features that add versatility and convenience for users. Built-in support for Media/Photo Transfer Protocol lets users instantly sync media files with a USB-connected camera or desktop computer, without needing to mount a USB mass-storage device. Users can also connect full keyboards over either USB or Bluetooth, for a familiar text-input environment. For improved wi-fi connectivity, a new combo scan reduces scan times across bands and filters. New support for Bluetooth tethering means that more types of devices can share the network connection of an Android-powered device.</p> +<p>Android 3.0 includes new connectivity features that add versatility and convenience for users. Built-in support for Media/Picture Transfer Protocol lets users instantly sync media files with a USB-connected camera or desktop computer, without needing to mount a USB mass-storage device. Users can also connect full keyboards over either USB or Bluetooth, for a familiar text-input environment. For improved wi-fi connectivity, a new combo scan reduces scan times across bands and filters. New support for Bluetooth tethering means that more types of devices can share the network connection of an Android-powered device.</p> <h3>Updated set of standard apps</h3> diff --git a/docs/html/sdk/images/3.0/browser.png b/docs/html/sdk/images/3.0/browser.png Binary files differindex 5d3ba3112654..0f16b2772b40 100644 --- a/docs/html/sdk/images/3.0/browser.png +++ b/docs/html/sdk/images/3.0/browser.png diff --git a/docs/html/sdk/images/3.0/browser_full.png b/docs/html/sdk/images/3.0/browser_full.png Binary files differindex 495a23d1521d..08a329d6de5e 100644 --- a/docs/html/sdk/images/3.0/browser_full.png +++ b/docs/html/sdk/images/3.0/browser_full.png diff --git a/docs/html/sdk/images/3.0/camera.png b/docs/html/sdk/images/3.0/camera.png Binary files differindex a5491823f315..7dabdfc0516b 100644 --- a/docs/html/sdk/images/3.0/camera.png +++ b/docs/html/sdk/images/3.0/camera.png diff --git a/docs/html/sdk/images/3.0/camera_full.png b/docs/html/sdk/images/3.0/camera_full.png Binary files differindex a5491823f315..3ee95c993ff8 100644 --- a/docs/html/sdk/images/3.0/camera_full.png +++ b/docs/html/sdk/images/3.0/camera_full.png diff --git a/docs/html/sdk/images/3.0/contacts.png b/docs/html/sdk/images/3.0/contacts.png Binary files differindex 0dcd16423c3a..9304701e07d2 100644 --- a/docs/html/sdk/images/3.0/contacts.png +++ b/docs/html/sdk/images/3.0/contacts.png diff --git a/docs/html/sdk/images/3.0/contacts_full.png b/docs/html/sdk/images/3.0/contacts_full.png Binary files differindex 829ad11ca43d..b5eaf5b19b2e 100644 --- a/docs/html/sdk/images/3.0/contacts_full.png +++ b/docs/html/sdk/images/3.0/contacts_full.png diff --git a/docs/html/sdk/images/3.0/copy.png b/docs/html/sdk/images/3.0/copy.png Binary files differindex 363aa8e75f91..a15c1cd8d92a 100644 --- a/docs/html/sdk/images/3.0/copy.png +++ b/docs/html/sdk/images/3.0/copy.png diff --git a/docs/html/sdk/images/3.0/copy_full.png b/docs/html/sdk/images/3.0/copy_full.png Binary files differindex a8db8a2bd598..124cf523bd0b 100644 --- a/docs/html/sdk/images/3.0/copy_full.png +++ b/docs/html/sdk/images/3.0/copy_full.png diff --git a/docs/html/sdk/images/3.0/home_hero1.png b/docs/html/sdk/images/3.0/home_hero1.png Binary files differindex c81e7efdb383..c00391f09658 100644 --- a/docs/html/sdk/images/3.0/home_hero1.png +++ b/docs/html/sdk/images/3.0/home_hero1.png diff --git a/docs/html/sdk/images/3.0/home_hero1_full.png b/docs/html/sdk/images/3.0/home_hero1_full.png Binary files differindex e280b81a7e5f..1910ed21e79d 100644 --- a/docs/html/sdk/images/3.0/home_hero1_full.png +++ b/docs/html/sdk/images/3.0/home_hero1_full.png diff --git a/docs/html/sdk/images/3.0/homescreen_cust_port.png b/docs/html/sdk/images/3.0/homescreen_cust_port.png Binary files differindex ef7f5ab4563e..b003a30e81a1 100644 --- a/docs/html/sdk/images/3.0/homescreen_cust_port.png +++ b/docs/html/sdk/images/3.0/homescreen_cust_port.png diff --git a/docs/html/sdk/images/3.0/homescreen_cust_port_full.png b/docs/html/sdk/images/3.0/homescreen_cust_port_full.png Binary files differindex 22433a3e8102..9c64edd6824d 100644 --- a/docs/html/sdk/images/3.0/homescreen_cust_port_full.png +++ b/docs/html/sdk/images/3.0/homescreen_cust_port_full.png diff --git a/docs/html/sdk/images/3.0/mail_drag.png b/docs/html/sdk/images/3.0/mail_drag.png Binary files differindex 6084caa606cb..1f09a7a51af7 100644 --- a/docs/html/sdk/images/3.0/mail_drag.png +++ b/docs/html/sdk/images/3.0/mail_drag.png diff --git a/docs/html/sdk/images/3.0/mail_drag_full.png b/docs/html/sdk/images/3.0/mail_drag_full.png Binary files differindex f99c61207906..be4472f8acd5 100644 --- a/docs/html/sdk/images/3.0/mail_drag_full.png +++ b/docs/html/sdk/images/3.0/mail_drag_full.png diff --git a/docs/html/sdk/images/3.0/tasks.png b/docs/html/sdk/images/3.0/tasks.png Binary files differindex 9e82dcb8f0f2..a4ba1bacabad 100644 --- a/docs/html/sdk/images/3.0/tasks.png +++ b/docs/html/sdk/images/3.0/tasks.png diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 3dcfe88b4742..4b8c58ebfe99 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -26,19 +26,41 @@ import android.util.Log; import android.util.TypedValue; /** - * Memory allocation class for renderscript. An allocation combines a Type with - * memory to provide storage for user data and objects. + * <p> + * Memory allocation class for renderscript. An allocation combines a + * {@link android.renderscript.Type} with the memory to provide storage for user data and objects. + * This implies that all memory in Renderscript is typed. + * </p> * - * Allocations may exist in one or more memory spaces. Currently those are - * Script: accessable by RS scripts. - * Graphics Texture: accessable as a graphics texture. - * Graphics Vertex: accessable as graphical vertex data. - * Graphics Constants: Accessable as constants in user shaders + * <p>Allocations are the primary way data moves into and out of scripts. Memory is user + * synchronized and it's possible for allocations to exist in multiple memory spaces + * concurrently. Currently those spaces are:</p> + * <ul> + * <li>Script: accessable by RS scripts.</li> + * <li>Graphics Texture: accessable as a graphics texture.</li> + * <li>Graphics Vertex: accessable as graphical vertex data.</li> + * <li>Graphics Constants: Accessable as constants in user shaders</li> + * </ul> + * </p> + * <p> + * For example, when creating a allocation for a texture, the user can + * specify its memory spaces as both script and textures. This means that it can both + * be used as script binding and as a GPU texture for rendering. To maintain + * synchronization if a script modifies an allocation used by other targets it must + * call a synchronizing function to push the updates to the memory, otherwise the results + * are undefined. + * </p> + * <p>By default, Android system side updates are always applied to the script accessable + * memory. If this is not present, they are then applied to the various HW + * memory types. A {@link android.renderscript.Allocation#syncAll syncAll()} + * call is necessary after the script data is updated to + * keep the other memory spaces in sync.</p> * - * By default java side updates are always applied to the script accessable - * memory. If this is not present they are then applied to the various HW - * memory types. A syncAll call is necessary after the script data is update to - * keep the other memory spaces in sync. + * <p>Allocation data is uploaded in one of two primary ways. For simple + * arrays there are copyFrom() functions that take an array from the control code and + * copy it to the slave memory store. Both type checked and unchecked copies are provided. + * The unchecked variants exist to allow apps to copy over arrays of structures from a + * control language that does not support structures.</p> * **/ public class Allocation extends BaseObj { diff --git a/graphics/java/android/renderscript/Byte2.java b/graphics/java/android/renderscript/Byte2.java index 6d2994d9d44c..7ec6cb0a11b0 100644 --- a/graphics/java/android/renderscript/Byte2.java +++ b/graphics/java/android/renderscript/Byte2.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs byte2 type back to java applications. + * Class for exposing the native Renderscript byte2 type back to the Android system. * **/ public class Byte2 { diff --git a/graphics/java/android/renderscript/Byte3.java b/graphics/java/android/renderscript/Byte3.java index dd739146313f..7bcd4b427ead 100644 --- a/graphics/java/android/renderscript/Byte3.java +++ b/graphics/java/android/renderscript/Byte3.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs byte3 type back to java applications. + * Class for exposing the native Renderscript byte3 type back to the Android system. * **/ public class Byte3 { diff --git a/graphics/java/android/renderscript/Byte4.java b/graphics/java/android/renderscript/Byte4.java index ebea589a7f72..c6e7f6330c64 100644 --- a/graphics/java/android/renderscript/Byte4.java +++ b/graphics/java/android/renderscript/Byte4.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs byte4 type back to java applications. + * Class for exposing the native Renderscript byte4 type back to the Android system. * **/ public class Byte4 { diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java index 10dc35b64955..4fc419c6a53a 100644 --- a/graphics/java/android/renderscript/Element.java +++ b/graphics/java/android/renderscript/Element.java @@ -20,25 +20,26 @@ import java.lang.reflect.Field; import android.util.Log; /** - * Element is the basic data type of RenderScript. An element can be of 2 - * forms. Basic elements contain a single component of data. This can be of - * any of the legal RS types. Examples of basic element types. - * Single float value - * 4 element float vector - * single RGB-565 color - * single unsigned int 16 - * - * Complex elements will contain a list of sub-elements and names. This in - * effect represents a structure of data. The fields can be accessed by name - * from a script or shader. The memory layout is defined and ordered. Data - * alignment is determinied by the most basic primitive type. i.e. a float4 + * <p>The most basic data type. An element represents one cell of a memory allocation. + * Element is the basic data type of Renderscript. An element can be of two forms: Basic elements or Complex forms. + * Examples of basic elements are:</p> + * <ul> + * <li>Single float value</li> + * <li>4 element float vector</li> + * <li>single RGB-565 color</li> + * <li>single unsigned int 16</li> + * </ul> + * <p>Complex elements contain a list of sub-elements and names that + * represents a structure of data. The fields can be accessed by name + * from a script or shader. The memory layout is defined and ordered. Data + * alignment is determinied by the most basic primitive type. i.e. a float4 * vector will be alligned to sizeof(float) and not sizeof(float4). The * ordering of elements in memory will be the order in which they were added - * with each component aligned as necessary. No re-ordering will be done. + * with each component aligned as necessary. No re-ordering will be done.</p> * - * The primary source of elements will be from scripts. A script that exports a - * bind point for a data structure will generate a RS element to represent the - * data exported by the script. + * <p>The primary source of elements are from scripts. A script that exports a + * bind point for a data structure generates a Renderscript element to represent the + * data exported by the script. The other common source of elements is from bitmap formats.</p> **/ public class Element extends BaseObj { int mSize; diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java index 40628bcde47d..bdda8305e2ed 100644 --- a/graphics/java/android/renderscript/FieldPacker.java +++ b/graphics/java/android/renderscript/FieldPacker.java @@ -18,8 +18,8 @@ package android.renderscript; /** - * Utility class for packing arguments and structures from java objects to rs - * objects. + * Utility class for packing arguments and structures from Android system objects to + * Renderscript objects. * **/ public class FieldPacker { diff --git a/graphics/java/android/renderscript/FileA3D.java b/graphics/java/android/renderscript/FileA3D.java index 79ee99758e45..b5419a7e21bd 100644 --- a/graphics/java/android/renderscript/FileA3D.java +++ b/graphics/java/android/renderscript/FileA3D.java @@ -28,9 +28,9 @@ import android.util.Log; import android.util.TypedValue; /** - * FileA3D allows users to load renderscript objects from files + * FileA3D allows users to load Renderscript objects from files * or resources stored on disk. It could be used to load items - * such as 3d geometry data converted a renderscript format from + * such as 3D geometry data converted to a Renderscript format from * content creation tools. Currently only meshes are supported * in FileA3D. * @@ -66,9 +66,9 @@ public class FileA3D extends BaseObj { } /** - * IndexEntry contains information about one of the renderscript + * IndexEntry contains information about one of the Renderscript * objects inside the file's index. It could be used to query the - * object's type and name and load the object itself if + * object's type and also name and load the object itself if * necessary. */ public static class IndexEntry { diff --git a/graphics/java/android/renderscript/Float2.java b/graphics/java/android/renderscript/Float2.java index 0a099f16c784..1d4ce3612d0e 100644 --- a/graphics/java/android/renderscript/Float2.java +++ b/graphics/java/android/renderscript/Float2.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs float2 type back to java applications. + * Class for exposing the native Renderscript float2 type back to the Android system. * **/ public class Float2 { diff --git a/graphics/java/android/renderscript/Float3.java b/graphics/java/android/renderscript/Float3.java index 2ffa32636786..ffd11350fbf6 100644 --- a/graphics/java/android/renderscript/Float3.java +++ b/graphics/java/android/renderscript/Float3.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs float3 type back to java applications. + * Class for exposing the native Renderscript float2 type back to the Android system. * **/ public class Float3 { diff --git a/graphics/java/android/renderscript/Float4.java b/graphics/java/android/renderscript/Float4.java index 19d91dc38ae1..c7cc3ae8ecc9 100644 --- a/graphics/java/android/renderscript/Float4.java +++ b/graphics/java/android/renderscript/Float4.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs float4 type back to java applications. + * Class for exposing the native Renderscript float2 type back to the Android system. * **/ public class Float4 { diff --git a/graphics/java/android/renderscript/Font.java b/graphics/java/android/renderscript/Font.java index 252ffc115c44..fa2759015725 100644 --- a/graphics/java/android/renderscript/Font.java +++ b/graphics/java/android/renderscript/Font.java @@ -30,7 +30,20 @@ import android.util.Log; import android.util.TypedValue; /** - * + * <p>This class gives users a simple way to draw hardware accelerated text. + * Internally, the glyphs are rendered using the Freetype library and an internal cache of + * rendered glyph bitmaps is maintained. Each font object represents a combination of a typeface, + * and point size. You can create multiple font objects to represent styles such as bold or italic text, + * faces, and different font sizes. During creation, the Android system quieries device's screen DPI to + * ensure proper sizing across multiple device configurations.</p> + * <p>Fonts are rendered using screen-space positions and no state setup beyond binding a + * font to the Renderscript is required. A note of caution on performance, though the state changes + * are transparent to the user, they do happen internally, and it is more efficient to + * render large batches of text in sequence. It is also more efficient to render multiple + * characters at once instead of one by one to improve draw call batching.</p> + * <p>Font color and transparency are not part of the font object and you can freely modify + * them in the script to suit the user's rendering needs. Font colors work as a state machine. + * Every new call to draw text uses the last color set in the script.</p> **/ public class Font extends BaseObj { diff --git a/graphics/java/android/renderscript/Int2.java b/graphics/java/android/renderscript/Int2.java index 8eceb71146de..7aaa4e886b16 100644 --- a/graphics/java/android/renderscript/Int2.java +++ b/graphics/java/android/renderscript/Int2.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs int2 type back to java applications. + * Class for exposing the native Renderscript int2 type back to the Android system. * **/ public class Int2 { diff --git a/graphics/java/android/renderscript/Int3.java b/graphics/java/android/renderscript/Int3.java index bbd296e790f1..e5c1cdff8f75 100644 --- a/graphics/java/android/renderscript/Int3.java +++ b/graphics/java/android/renderscript/Int3.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs int3 type back to java applications. + * Class for exposing the native Renderscript int3 type back to the Android system. * **/ public class Int3 { diff --git a/graphics/java/android/renderscript/Int4.java b/graphics/java/android/renderscript/Int4.java index c3ae112cadec..5289a8977f2a 100644 --- a/graphics/java/android/renderscript/Int4.java +++ b/graphics/java/android/renderscript/Int4.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs int4 type back to java applications. + * Class for exposing the native Renderscript int4 type back to the Android system. * **/ public class Int4 { diff --git a/graphics/java/android/renderscript/Long2.java b/graphics/java/android/renderscript/Long2.java index 834d13c561aa..8590b962cd43 100644 --- a/graphics/java/android/renderscript/Long2.java +++ b/graphics/java/android/renderscript/Long2.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * + * Class for exposing the native Renderscript long2 type back to the Android system. **/ public class Long2 { public Long2() { diff --git a/graphics/java/android/renderscript/Long3.java b/graphics/java/android/renderscript/Long3.java index c6d72894ba96..6ae837acccdf 100644 --- a/graphics/java/android/renderscript/Long3.java +++ b/graphics/java/android/renderscript/Long3.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * + * Class for exposing the native Renderscript long3 type back to the Android system. **/ public class Long3 { public Long3() { diff --git a/graphics/java/android/renderscript/Long4.java b/graphics/java/android/renderscript/Long4.java index 032c1d34ccf8..04c12f20c534 100644 --- a/graphics/java/android/renderscript/Long4.java +++ b/graphics/java/android/renderscript/Long4.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * + * Class for exposing the native Renderscript long4 type back to the Android system. **/ public class Long4 { public Long4() { diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java index c9a0ea8ab04b..78ff97bb20b4 100644 --- a/graphics/java/android/renderscript/Matrix2f.java +++ b/graphics/java/android/renderscript/Matrix2f.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs_matrix2x2 type back to java applications. + * Class for exposing the native Renderscript rs_matrix2x2 type back to the Android system. * **/ public class Matrix2f { diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java index 2ec8c625f079..253506df993e 100644 --- a/graphics/java/android/renderscript/Matrix3f.java +++ b/graphics/java/android/renderscript/Matrix3f.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs_matrix3x3 type back to java applications. + * Class for exposing the native Renderscript rs_matrix3x3 type back to the Android system. * **/ public class Matrix3f { diff --git a/graphics/java/android/renderscript/Matrix4f.java b/graphics/java/android/renderscript/Matrix4f.java index 2afd72e6f49b..adc180694916 100644 --- a/graphics/java/android/renderscript/Matrix4f.java +++ b/graphics/java/android/renderscript/Matrix4f.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs_matrix4x4 type back to java applications. + * Class for exposing the native Renderscript rs_matrix4x4 type back to the Android system. * **/ public class Matrix4f { diff --git a/graphics/java/android/renderscript/Mesh.java b/graphics/java/android/renderscript/Mesh.java index 7269cea76ecc..bb910cc6bb11 100644 --- a/graphics/java/android/renderscript/Mesh.java +++ b/graphics/java/android/renderscript/Mesh.java @@ -22,22 +22,21 @@ import android.util.Config; import android.util.Log; /** - * Mesh class is a container for geometric data displayed in - * renderscript. - * - * Internally, mesh is a collection of allocations that + * <p>This class is a container for geometric data displayed with + * Renderscript. Internally, a mesh is a collection of allocations that * represent vertex data (positions, normals, texture - * coordinates) and index data such as triangles and lines. - * - * Vertex data could either be interlieved within one - * allocation, provided separately as multiple allocation - * objects or done as a combination of the above. When a + * coordinates) and index data such as triangles and lines. </p> + * <p> + * Vertex data could either be interleaved within one + * allocation that is provided separately, as multiple allocation + * objects, or done as a combination of both. When a * vertex channel name matches an input in the vertex program, - * renderscript will automatically connect the two together. - * - * Parts of the mesh could be rendered with either explicit + * Renderscript automatically connects the two together. + * </p> + * <p> + * Parts of the mesh can be rendered with either explicit * index sets or primitive types. - * + * </p> **/ public class Mesh extends BaseObj { @@ -170,9 +169,9 @@ public class Mesh extends BaseObj { } /** - * Mesh builder object. It starts empty and requires the user to + * Mesh builder object. It starts empty and requires you to * add the types necessary to create vertex and index - * allocations + * allocations. * */ public static class Builder { diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java index 333880d58742..a48c2e359e93 100644 --- a/graphics/java/android/renderscript/ProgramFragment.java +++ b/graphics/java/android/renderscript/ProgramFragment.java @@ -22,9 +22,19 @@ import android.util.Log; /** - * ProgramFragment, also know as a fragment shader, describes a - * stage in the graphics pipeline responsible for manipulating - * pixel data in a user-defined way. + * <p>The Renderscript fragment program, also known as fragment shader is responsible + * for manipulating pixel data in a user defined way. It's constructed from a GLSL + * shader string containing the program body, textures inputs, and a Type object + * that describes the constants used by the program. Similar to the vertex programs, + * when an allocation with constant input values is bound to the shader, its values + * are sent to the graphics program automatically.</p> + * <p> The values inside the allocation are not explicitly tracked. If they change between two draw + * calls using the same program object, the runtime needs to be notified of that + * change by calling rsgAllocationSyncAll so it could send the new values to hardware. + * Communication between the vertex and fragment programs is handled internally in the + * GLSL code. For example, if the fragment program is expecting a varying input called + * varTex0, the GLSL code inside the program vertex must provide it. + * </p> * **/ public class ProgramFragment extends Program { diff --git a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java index 666a3e66c3a2..f99cd7b1d984 100644 --- a/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java +++ b/graphics/java/android/renderscript/ProgramFragmentFixedFunction.java @@ -22,13 +22,11 @@ import android.util.Log; /** - * ProgramFragmentFixedFunction is a helper class that provides + * <p>ProgramFragmentFixedFunction is a helper class that provides * a way to make a simple fragment shader without writing any - * GLSL code. - * - * This class allows for display of constant color, interpolated - * color from vertex shader, or combinations of the above - * blended with results of up to two texture lookups. + * GLSL code. This class allows for display of constant color, interpolated + * color from the vertex shader, or combinations of the both + * blended with results of up to two texture lookups.</p * **/ public class ProgramFragmentFixedFunction extends ProgramFragment { diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java index 71c527d46cf3..b89d36d7c218 100644 --- a/graphics/java/android/renderscript/ProgramRaster.java +++ b/graphics/java/android/renderscript/ProgramRaster.java @@ -22,7 +22,8 @@ import android.util.Log; /** - * + * Program raster is primarily used to specify whether point sprites are enabled and to control + * the culling mode. By default, back faces are culled. **/ public class ProgramRaster extends BaseObj { diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java index 9128f9ba0ac6..c46e6b9cfd85 100644 --- a/graphics/java/android/renderscript/ProgramStore.java +++ b/graphics/java/android/renderscript/ProgramStore.java @@ -22,16 +22,17 @@ import android.util.Log; /** - * ProgarmStore contains a set of parameters that control how + * <p>ProgramStore contains a set of parameters that control how * the graphics hardware handles writes to the framebuffer. - * - * It could be used to: - * - enable/diable depth testing - * - specify wheather depth writes are performed - * - setup various blending modes for use in effects like - * transparency - * - define write masks for color components written into the - * framebuffer + * It could be used to:</p> + * <ul> + * <li>enable/disable depth testing</li> + * <li>specify wheather depth writes are performed</li> + * <li>setup various blending modes for use in effects like + * transparency</li> + * <li>define write masks for color components written into the + * framebuffer</li> + * </ul> * **/ public class ProgramStore extends BaseObj { diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java index a965b819d8b1..55653f74afcc 100644 --- a/graphics/java/android/renderscript/ProgramVertex.java +++ b/graphics/java/android/renderscript/ProgramVertex.java @@ -14,6 +14,27 @@ * limitations under the License. */ + /** + * <p>The Renderscript vertex program, also known as a vertex shader, describes a stage in + * the graphics pipeline responsible for manipulating geometric data in a user-defined way. + * The object is constructed by providing the Renderscript system with the following data:</p> + * <ul> + * <li>Element describing its varying inputs or attributes</li> + * <li>GLSL shader string that defines the body of the program</li> + * <li>a Type that describes the layout of an Allocation containing constant or uniform inputs</li> + * </ul> + * + * <p>Once the program is created, you bind it to the graphics context, RenderScriptGL, and it will be used for + * all subsequent draw calls until you bind a new program. If the program has constant inputs, + * the user needs to bind an allocation containing those inputs. The allocation's type must match + * the one provided during creation. The Renderscript library then does all the necessary plumbing + * to send those constants to the graphics hardware. Varying inputs to the shader, such as position, normal, + * and texture coordinates are matched by name between the input Element and the Mesh object being drawn. + * The signatures don't have to be exact or in any strict order. As long as the input name in the shader + * matches a channel name and size available on the mesh, the runtime takes care of connecting the + * two. Unlike OpenGL, there is no need to link the vertex and fragment programs.</p> + * + **/ package android.renderscript; diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java index be893bbcb0e9..199952c436b4 100644 --- a/graphics/java/android/renderscript/RSSurfaceView.java +++ b/graphics/java/android/renderscript/RSSurfaceView.java @@ -30,7 +30,7 @@ import android.view.SurfaceHolder; import android.view.SurfaceView; /** - * + * The Surface View for a graphics renderscript (RenderScriptGL) to draw on. */ public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mSurfaceHolder; diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java index c656d75013f1..8ee4d724120f 100644 --- a/graphics/java/android/renderscript/Sampler.java +++ b/graphics/java/android/renderscript/Sampler.java @@ -29,8 +29,8 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; /** - * Sampler object which defines how data is extracted from textures. Samplers - * are attached to Program objects (currently only fragment) when those objects + * Sampler object which defines how data is extracted from textures. Samplers + * are attached to Program objects (currently only ProgramFragment) when those objects * need to access texture data. **/ public class Sampler extends BaseObj { diff --git a/graphics/java/android/renderscript/Short2.java b/graphics/java/android/renderscript/Short2.java index 82d897e730bd..7094eddad22a 100644 --- a/graphics/java/android/renderscript/Short2.java +++ b/graphics/java/android/renderscript/Short2.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs short2 type back to java applications. + * Class for exposing the native Renderscript Short2 type back to the Android system. * **/ public class Short2 { diff --git a/graphics/java/android/renderscript/Short3.java b/graphics/java/android/renderscript/Short3.java index 00da5741a675..f34500c9097d 100644 --- a/graphics/java/android/renderscript/Short3.java +++ b/graphics/java/android/renderscript/Short3.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs short3 type back to java applications. + * Class for exposing the native Renderscript short3 type back to the Android system. * **/ public class Short3 { diff --git a/graphics/java/android/renderscript/Short4.java b/graphics/java/android/renderscript/Short4.java index 450258dbd44c..5698feefafd6 100644 --- a/graphics/java/android/renderscript/Short4.java +++ b/graphics/java/android/renderscript/Short4.java @@ -21,7 +21,7 @@ import android.util.Log; /** - * Class for exposing the rs short4 type back to java applications. + * Class for exposing the native Renderscript short4 type back to the Android system. * **/ public class Short4 { diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java index bec76d0c9f83..9979e2aa25d9 100644 --- a/graphics/java/android/renderscript/Type.java +++ b/graphics/java/android/renderscript/Type.java @@ -21,19 +21,19 @@ import java.lang.reflect.Field; import android.util.Log; /** - * Type is an allocation template. It consists of an Element and one or more - * dimensions. It describes only the layout of memory but does not allocate and - * storage for the data thus described. + * <p>Type is an allocation template. It consists of an Element and one or more + * dimensions. It describes only the layout of memory but does not allocate any + * storage for the data that is described.</p> * - * A Type consists of several dimensions. Those are X, Y, Z, LOD (level of + * <p>A Type consists of several dimensions. Those are X, Y, Z, LOD (level of * detail), Faces (faces of a cube map). The X,Y,Z dimensions can be assigned * any positive integral value within the constraints of available memory. A * single dimension allocation would have an X dimension of greater than zero * while the Y and Z dimensions would be zero to indicate not present. In this * regard an allocation of x=10, y=1 would be considered 2 dimensionsal while - * x=10, y=0 would be considered 1 dimensional. + * x=10, y=0 would be considered 1 dimensional.</p> * - * The LOD and Faces dimensions are booleans to indicate present or not present. + * <p>The LOD and Faces dimensions are booleans to indicate present or not present.</p> * **/ public class Type extends BaseObj { diff --git a/graphics/java/android/renderscript/package.html b/graphics/java/android/renderscript/package.html new file mode 100644 index 000000000000..36a24fffead8 --- /dev/null +++ b/graphics/java/android/renderscript/package.html @@ -0,0 +1,85 @@ +<HTML> +<BODY> +<p>The Renderscript rendering and computational APIs offer a low-level, high performance means of +carrying out mathematical calculations and 3D graphics rendering. An example of Renderscript in +applications include the 3D carousel view that is present in Android 3.0 applications such as the +Books and YouTube applications. This API is intended for developers who are comfortable working with +native code and want to maximize their performance critical applications.</p> + +<p>Renderscript adopts a control and slave architecture where the low-level native code is controlled by the +higher level Android system that runs in the virtual machine (VM). The VM code handles resource +allocation and lifecycle management of the Renderscript enabled application and calls the Renderscript +code through high level entry points. The Android build tools generate these entry points through reflection on +the native Renderscript code, which you write in C (C99 standard). The Renderscript code +does the intensive computation and returns the result back to the Android VM.</p> + +<p>You can find the Renderscript native +APIs in the <code><sdk_root>/platforms/android-3.0/renderscript</code> directory. +The Android system APIs are broken into a few main groups:</p> + +<h4>Core</h4> +<p>These classes are used internally by the system for memory allocation. They are used by the classes that +are generated by the build tools:</p> +<ul> + <li>Allocation</li> + <li>Element</li> + <li>Type</li> + <li>Script</li> +</ul> + + +<h4>Data Types</h4> +<p>These data types are used by the classes that are generated +by the build tools. They are the reflected counterparts of the native data types that +are defined by the native Renderscript APIs and used by your Renderscript code. The +classes include:</p> +<ul> + <li>Byte2, Byte3, and Byte4</li> + <li>Float2, Float3, Float4</li> + <li>Int2, Int3, Int4</li> + <li>Long2, Long3, Long4</li> + <li>Matrix2f, Matrix3f, Matrix4f</li> + <li>Short2, Short3, Short4</li> +</ul> + +<p>For example, if you declared the following struct in your .rs Renderscript file:</p> + +<pre>struct Hello { float3 position; rs_matrix4x4 transform; }</pre> + +<p>The build tools generate a class through reflection that looks like the following:</p> +<pre> +class Hello { + static public class Item { + Float4 position; + Matrix4f transform; + } +Element createElement(RenderScript rs) { + Element.Builder eb = new Element.Builder(rs); + eb.add(Element.F32_3(rs), "position"); + eb.add(Element.MATRIX_4X4(rs), "transform"); + return eb.create(); + } +} +</pre> + +<h4>Graphics</h4> +<p>These classes are specific to graphics Renderscripts and support a typical rendering +pipeline.</p> +<ul> +<li>Mesh</li> +<li>ProgramFragment</li> +<li>ProgramRaster</li> +<li>ProgramStore</li> +<li>ProgramVertex</li> +<li>RSSurfaceView</li> +<li>Sampler</li> +</ul> + +</p> +<p> +For information on how to create an application that uses Renderscript, and also the +see <a href="../../../guide/topics/graphics/renderscript.html">3D with +Renderscript</a> dev guide. +</p> +</BODY> +</HTML> diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h index 9c64ac044340..c24c0dbcb28f 100644 --- a/include/utils/RefBase.h +++ b/include/utils/RefBase.h @@ -31,13 +31,10 @@ template<typename T> class wp; // --------------------------------------------------------------------------- -#define COMPARE(_op_) \ +#define COMPARE_WEAK(_op_) \ inline bool operator _op_ (const sp<T>& o) const { \ return m_ptr _op_ o.m_ptr; \ } \ -inline bool operator _op_ (const wp<T>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} \ inline bool operator _op_ (const T* o) const { \ return m_ptr _op_ o; \ } \ @@ -46,12 +43,18 @@ inline bool operator _op_ (const sp<U>& o) const { \ return m_ptr _op_ o.m_ptr; \ } \ template<typename U> \ -inline bool operator _op_ (const wp<U>& o) const { \ +inline bool operator _op_ (const U* o) const { \ + return m_ptr _op_ o; \ +} + +#define COMPARE(_op_) \ +COMPARE_WEAK(_op_) \ +inline bool operator _op_ (const wp<T>& o) const { \ return m_ptr _op_ o.m_ptr; \ } \ template<typename U> \ -inline bool operator _op_ (const U* o) const { \ - return m_ptr _op_ o; \ +inline bool operator _op_ (const wp<U>& o) const { \ + return m_ptr _op_ o.m_ptr; \ } // --------------------------------------------------------------------------- @@ -274,13 +277,43 @@ public: inline T* unsafe_get() const { return m_ptr; } // Operators - - COMPARE(==) - COMPARE(!=) - COMPARE(>) - COMPARE(<) - COMPARE(<=) - COMPARE(>=) + + COMPARE_WEAK(==) + COMPARE_WEAK(!=) + COMPARE_WEAK(>) + COMPARE_WEAK(<) + COMPARE_WEAK(<=) + COMPARE_WEAK(>=) + + inline bool operator == (const wp<T>& o) const { + return (m_ptr == o.m_ptr) && (m_refs == o.m_refs); + } + template<typename U> + inline bool operator == (const wp<U>& o) const { + return m_ptr == o.m_ptr; + } + + inline bool operator > (const wp<T>& o) const { + return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); + } + template<typename U> + inline bool operator > (const wp<U>& o) const { + return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr); + } + + inline bool operator < (const wp<T>& o) const { + return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); + } + template<typename U> + inline bool operator < (const wp<U>& o) const { + return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr); + } + inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; } + template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); } + inline bool operator <= (const wp<T>& o) const { return !operator > (o); } + template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); } + inline bool operator >= (const wp<T>& o) const { return !operator < (o); } + template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); } private: template<typename Y> friend class sp; @@ -294,6 +327,7 @@ template <typename T> TextOutput& operator<<(TextOutput& to, const wp<T>& val); #undef COMPARE +#undef COMPARE_WEAK // --------------------------------------------------------------------------- // No user serviceable parts below here. diff --git a/libs/rs/java/HelloWorld/Android.mk b/libs/rs/java/HelloWorld/Android.mk new file mode 100644 index 000000000000..72f0f03b2187 --- /dev/null +++ b/libs/rs/java/HelloWorld/Android.mk @@ -0,0 +1,30 @@ +# +# Copyright (C) 2011 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +ifneq ($(TARGET_SIMULATOR),true) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) + +LOCAL_PACKAGE_NAME := HelloWorld + +include $(BUILD_PACKAGE) + +endif diff --git a/libs/rs/java/HelloWorld/AndroidManifest.xml b/libs/rs/java/HelloWorld/AndroidManifest.xml new file mode 100644 index 000000000000..e7c9a95051c9 --- /dev/null +++ b/libs/rs/java/HelloWorld/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.rs.helloworld"> + <uses-sdk android:minSdkVersion="11" /> + <application android:label="HelloWorld" + android:icon="@drawable/test_pattern"> + <activity android:name="HelloWorld" + android:label="HelloWorld" + android:theme="@android:style/Theme.Black.NoTitleBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/libs/rs/java/HelloWorld/res/drawable/test_pattern.png b/libs/rs/java/HelloWorld/res/drawable/test_pattern.png Binary files differnew file mode 100644 index 000000000000..e7d145554c00 --- /dev/null +++ b/libs/rs/java/HelloWorld/res/drawable/test_pattern.png diff --git a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorld.java b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorld.java new file mode 100644 index 000000000000..f63015e7b596 --- /dev/null +++ b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorld.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.helloworld; + +import android.app.Activity; +import android.os.Bundle; + +// Renderscript activity +public class HelloWorld extends Activity { + + // Custom view to use with RenderScript + private HelloWorldView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our view and set it as the content of our Activity + mView = new HelloWorldView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally an app should implement onResume() and onPause() + // to take appropriate action when the activity loses focus + super.onResume(); + mView.resume(); + } + + @Override + protected void onPause() { + // Ideally an app should implement onResume() and onPause() + // to take appropriate action when the activity loses focus + super.onPause(); + mView.pause(); + } + +} + diff --git a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldRS.java b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldRS.java new file mode 100644 index 000000000000..c9c1316f01b5 --- /dev/null +++ b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldRS.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.helloworld; + +import android.content.res.Resources; +import android.renderscript.*; + +// This is the renderer for the HelloWorldView +public class HelloWorldRS { + private Resources mRes; + private RenderScriptGL mRS; + + private ScriptC_helloworld mScript; + + public HelloWorldRS() { + } + + // This provides us with the renderscript context and resources that + // allow us to create the script that does rendering + public void init(RenderScriptGL rs, Resources res) { + mRS = rs; + mRes = res; + initRS(); + } + + public void onActionDown(int x, int y) { + mScript.set_gTouchX(x); + mScript.set_gTouchY(y); + } + + private void initRS() { + mScript = new ScriptC_helloworld(mRS, mRes, R.raw.helloworld); + mRS.bindRootScript(mScript); + } +} + + + diff --git a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldView.java b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldView.java new file mode 100644 index 000000000000..8cddb2a7a77e --- /dev/null +++ b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/HelloWorldView.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.helloworld; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.view.MotionEvent; + +public class HelloWorldView extends RSSurfaceView { + // Renderscipt context + private RenderScriptGL mRS; + // Script that does the rendering + private HelloWorldRS mRender; + + public HelloWorldView(Context context) { + super(context); + ensureRenderScript(); + } + + private void ensureRenderScript() { + if (mRS == null) { + // Initialize renderscript with desired surface characteristics. + // In this case, just use the defaults + RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); + mRS = createRenderScriptGL(sc); + // Create an instance of the script that does the rendering + mRender = new HelloWorldRS(); + mRender.init(mRS, getResources()); + } + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + ensureRenderScript(); + } + + @Override + protected void onDetachedFromWindow() { + // Handle the system event and clean up + mRender = null; + if (mRS != null) { + mRS = null; + destroyRenderScriptGL(); + } + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + // Pass touch events from the system to the rendering script + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + mRender.onActionDown((int)ev.getX(), (int)ev.getY()); + return true; + } + + return false; + } +} + + diff --git a/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/helloworld.rs b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/helloworld.rs new file mode 100644 index 000000000000..fa171f56e1a7 --- /dev/null +++ b/libs/rs/java/HelloWorld/src/com/android/rs/helloworld/helloworld.rs @@ -0,0 +1,47 @@ +// Copyright (C) 2011 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma version(1) + +// Tell which java package name the reflected files should belong to +#pragma rs java_package_name(com.android.rs.helloworld) + +// Built-in header with graphics API's +#include "rs_graphics.rsh" + +// gTouchX and gTouchY are variables that will be reflected for use +// by the java API. We can use them to notify the script of touch events. +int gTouchX; +int gTouchY; + +// This is invoked automatically when the script is created +void init() { + gTouchX = 50.0f; + gTouchY = 50.0f; +} + +int root(int launchID) { + + // Clear the background color + rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f); + // Tell the runtime what the font color should be + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + // Introuduce ourselves to the world by drawing a greeting + // at the position user touched on the screen + rsgDrawText("Hello World!", gTouchX, gTouchY); + + // Return value tells RS roughly how often to redraw + // in this case 20 ms + return 20; +} diff --git a/libs/rs/java/Samples/src/com/android/samples/RsList.java b/libs/rs/java/Samples/src/com/android/samples/RsList.java index d47be42039c1..2d7add0c5eed 100644 --- a/libs/rs/java/Samples/src/com/android/samples/RsList.java +++ b/libs/rs/java/Samples/src/com/android/samples/RsList.java @@ -16,26 +16,8 @@ package com.android.samples; -import android.renderscript.RSSurfaceView; -import android.renderscript.RenderScript; - import android.app.Activity; -import android.content.res.Configuration; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.provider.Settings.System; -import android.util.Config; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.Window; -import android.widget.Button; -import android.widget.ListView; - -import java.lang.Runtime; public class RsList extends Activity { diff --git a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java index 8e2d51f0dbe9..6ee545ac5a58 100644 --- a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java +++ b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java @@ -73,17 +73,12 @@ public class RsListRS { "Yemen", "Yugoslavia", "Zambia", "Zimbabwe" }; - int mWidth; - int mHeight; - public RsListRS() { } - public void init(RenderScriptGL rs, Resources res, int width, int height) { + public void init(RenderScriptGL rs, Resources res) { mRS = rs; mRes = res; - mWidth = width; - mHeight = height; initRS(); } diff --git a/libs/rs/java/Samples/src/com/android/samples/RsListView.java b/libs/rs/java/Samples/src/com/android/samples/RsListView.java index 00b1723043e4..b67bd48a8730 100644 --- a/libs/rs/java/Samples/src/com/android/samples/RsListView.java +++ b/libs/rs/java/Samples/src/com/android/samples/RsListView.java @@ -15,55 +15,40 @@ */ package com.android.samples; - -import java.io.Writer; -import java.util.ArrayList; -import java.util.concurrent.Semaphore; - import android.renderscript.RSSurfaceView; -import android.renderscript.RenderScript; import android.renderscript.RenderScriptGL; import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.Handler; -import android.os.Message; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.KeyEvent; import android.view.MotionEvent; public class RsListView extends RSSurfaceView { public RsListView(Context context) { super(context); - //setFocusable(true); + ensureRenderScript(); } private RenderScriptGL mRS; private RsListRS mRender; - - public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { - super.surfaceChanged(holder, format, w, h); + private void ensureRenderScript() { if (mRS == null) { RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); - sc.setDepth(16, 24); mRS = createRenderScriptGL(sc); - mRS.setSurface(holder, w, h); mRender = new RsListRS(); - mRender.init(mRS, getResources(), w, h); + mRender.init(mRS, getResources()); } } @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + ensureRenderScript(); + } + + @Override protected void onDetachedFromWindow() { + mRender = null; if (mRS != null) { mRS = null; destroyRenderScriptGL(); @@ -71,23 +56,14 @@ public class RsListView extends RSSurfaceView { } @Override - public boolean onKeyDown(int keyCode, KeyEvent event) - { - // break point at here - // this method doesn't work when 'extends View' include 'extends ScrollView'. - return super.onKeyDown(keyCode, event); - } - - - @Override public boolean onTouchEvent(MotionEvent ev) { boolean ret = false; int act = ev.getAction(); - if (act == ev.ACTION_DOWN) { + if (act == MotionEvent.ACTION_DOWN) { mRender.onActionDown((int)ev.getX(), (int)ev.getY()); ret = true; - } else if (act == ev.ACTION_MOVE) { + } else if (act == MotionEvent.ACTION_MOVE) { mRender.onActionMove((int)ev.getX(), (int)ev.getY()); ret = true; } diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java index 33c1719e3373..ff8c2dec28d3 100644 --- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java +++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java @@ -16,26 +16,8 @@ package com.android.samples; -import android.renderscript.RSSurfaceView; -import android.renderscript.RenderScript; - import android.app.Activity; -import android.content.res.Configuration; import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.provider.Settings.System; -import android.util.Config; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.Window; -import android.widget.Button; -import android.widget.ListView; - -import java.lang.Runtime; public class RsRenderStates extends Activity { diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java index 87840a765d03..49b65d6d95ed 100644 --- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java +++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java @@ -16,8 +16,6 @@ package com.android.samples; -import java.io.Writer; - import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -39,11 +37,11 @@ public class RsRenderStatesRS { public RsRenderStatesRS() { } - public void init(RenderScriptGL rs, Resources res, int width, int height) { + public void init(RenderScriptGL rs, Resources res) { mRS = rs; + mWidth = mRS.getWidth(); + mHeight = mRS.getHeight(); mRes = res; - mWidth = width; - mHeight = height; mOptionsARGB.inScaled = false; mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888; mMode = 0; @@ -51,6 +49,15 @@ public class RsRenderStatesRS { initRS(); } + public void surfaceChanged() { + mWidth = mRS.getWidth(); + mHeight = mRS.getHeight(); + + Matrix4f proj = new Matrix4f(); + proj.loadOrthoWindow(mWidth, mHeight); + mPVA.setProjection(proj); + } + private Resources mRes; private RenderScriptGL mRS; diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java index 235d29bc709a..4d339dd33e1c 100644 --- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java +++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java @@ -16,54 +16,48 @@ package com.android.samples; -import java.io.Writer; -import java.util.ArrayList; -import java.util.concurrent.Semaphore; - import android.renderscript.RSSurfaceView; -import android.renderscript.RenderScript; import android.renderscript.RenderScriptGL; import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.os.Handler; -import android.os.Message; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.KeyEvent; import android.view.MotionEvent; +import android.view.SurfaceHolder; public class RsRenderStatesView extends RSSurfaceView { public RsRenderStatesView(Context context) { super(context); - //setFocusable(true); + ensureRenderScript(); } private RenderScriptGL mRS; private RsRenderStatesRS mRender; - - public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { - super.surfaceChanged(holder, format, w, h); + private void ensureRenderScript() { if (mRS == null) { RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig(); sc.setDepth(16, 24); mRS = createRenderScriptGL(sc); - mRS.setSurface(holder, w, h); mRender = new RsRenderStatesRS(); - mRender.init(mRS, getResources(), w, h); + mRender.init(mRS, getResources()); } } @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + ensureRenderScript(); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + mRender.surfaceChanged(); + } + + @Override protected void onDetachedFromWindow() { + mRender = null; if (mRS != null) { mRS = null; destroyRenderScriptGL(); @@ -71,25 +65,13 @@ public class RsRenderStatesView extends RSSurfaceView { } @Override - public boolean onKeyDown(int keyCode, KeyEvent event) - { - // break point at here - // this method doesn't work when 'extends View' include 'extends ScrollView'. - return super.onKeyDown(keyCode, event); - } - - - @Override - public boolean onTouchEvent(MotionEvent ev) - { - boolean ret = false; - int act = ev.getAction(); - if (act == ev.ACTION_DOWN) { + public boolean onTouchEvent(MotionEvent ev) { + if (ev.getAction() == MotionEvent.ACTION_DOWN) { mRender.onActionDown((int)ev.getX(), (int)ev.getY()); - ret = true; + return true; } - return ret; + return false; } } diff --git a/libs/rs/java/Samples/src/com/android/samples/rslist.rs b/libs/rs/java/Samples/src/com/android/samples/rslist.rs index b79f4fcf6637..52c870a19492 100644 --- a/libs/rs/java/Samples/src/com/android/samples/rslist.rs +++ b/libs/rs/java/Samples/src/com/android/samples/rslist.rs @@ -37,7 +37,6 @@ int textPos = 0; int root(int launchID) { rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f); - rsgClearDepth(1.0f); textPos -= (int)gDY*2; gDY *= 0.95; |