Merge "Fix issue 2712130: Sholes: problem when playing audio while recording over bluetooth SCO." into gingerbread
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index 0f96d6b..5d222d9 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -24,7 +24,7 @@
 interface INfcTag
 {
     int close(int nativeHandle);
-    int connect(int nativeHandle);
+    int connect(int nativeHandle, int technology);
     int reconnect(int nativeHandle);
     int[] getTechList(int nativeHandle);
     byte[] getUid(int nativeHandle);
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index d042634..7404950 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -63,6 +63,8 @@
     /*package*/ final Bundle[] mTechExtras;
     /*package*/ final int mServiceHandle;  // for use by NFC service, 0 indicates a mock
 
+    /*package*/ int mConnectedTechnology;
+
     /**
      * Hidden constructor to be used by NFC service and internal classes.
      * @hide
@@ -76,6 +78,8 @@
         // Ensure mTechExtras is as long as mTechList
         mTechExtras = Arrays.copyOf(techListExtras, techList.length);
         mServiceHandle = serviceHandle;
+
+        mConnectedTechnology = -1;
     }
 
     /**
@@ -244,4 +248,29 @@
             return new Tag[size];
         }
     };
+
+    /*
+     * @hide
+     */
+    public synchronized void setConnectedTechnology(int technology) {
+        if (mConnectedTechnology == -1) {
+            mConnectedTechnology = technology;
+        } else {
+            throw new IllegalStateException("Close other technology first!");
+        }
+    }
+
+    /*
+     * @hide
+     */
+    public int getConnectedTechnology() {
+        return mConnectedTechnology;
+    }
+
+    /*
+     * @hide
+     */
+    public void setTechnologyDisconnected() {
+        mConnectedTechnology = -1;
+    }
 }
diff --git a/core/java/android/nfc/technology/BasicTagTechnology.java b/core/java/android/nfc/technology/BasicTagTechnology.java
index a50c10b..553f6ec 100644
--- a/core/java/android/nfc/technology/BasicTagTechnology.java
+++ b/core/java/android/nfc/technology/BasicTagTechnology.java
@@ -22,6 +22,7 @@
 import android.nfc.INfcTag;
 import android.nfc.NfcAdapter;
 import android.nfc.Tag;
+import android.nfc.ErrorCodes;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -101,6 +102,13 @@
         return mTag;
     }
 
+    public void checkConnected() {
+       if ((mTag.getConnectedTechnology() != getTechnologyId()) ||
+               (mTag.getConnectedTechnology() == -1)) {
+           throw new IllegalStateException("Call connect() first!");
+       }
+    }
+
     /**
      * <p>Requires {@link android.Manifest.permission#NFC} permission.
      */
@@ -144,8 +152,53 @@
      */
     @Override
     public void connect() throws IOException {
-        //TODO(nxp): enforce exclusivity
-        mIsConnected = true;
+        try {
+            int errorCode = mTagService.connect(mTag.getServiceHandle(), getTechnologyId());
+
+            if (errorCode == ErrorCodes.SUCCESS) {
+                // Store this in the tag object
+                mTag.setConnectedTechnology(getTechnologyId());
+                mIsConnected = true;
+            } else {
+                throw new IOException();
+            }
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            throw new IOException("NFC service died");
+        }
+    }
+
+    /**
+     * Re-connect to the {@link Tag} associated with this connection.
+     * <p>
+     * Reconnecting to a tag can be used to reset the state of the tag itself.
+     * This method blocks until the connection is re-established.
+     * <p>
+     * {@link #close} can be called from another thread to cancel this connection
+     * attempt.
+     * <p>Requires {@link android.Manifest.permission#NFC} permission.
+     * @throws IOException if the target is lost, or connect canceled
+     */
+    @Override
+    public void reconnect() throws IOException {
+        if (!mIsConnected) {
+            throw new IllegalStateException("Technology not connected yet");
+        } else {
+            try {
+                int errorCode = mTagService.reconnect(mTag.getServiceHandle());
+
+                if (errorCode != ErrorCodes.SUCCESS) {
+                    mIsConnected = false;
+                    mTag.setTechnologyDisconnected();
+                    throw new IOException();
+                }
+            } catch (RemoteException e) {
+                mIsConnected = false;
+                mTag.setTechnologyDisconnected();
+                attemptDeadServiceRecovery(e);
+                throw new IOException("NFC service died");
+            }
+        }
     }
 
     /**
@@ -160,7 +213,6 @@
      */
     @Override
     public void close() {
-        mIsConnected = false;
         try {
             /* Note that we don't want to physically disconnect the tag,
              * but just reconnect to it to reset its state
@@ -168,6 +220,9 @@
             mTagService.reconnect(mTag.getServiceHandle());
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
+        } finally {
+            mIsConnected = false;
+            mTag.setTechnologyDisconnected();
         }
     }
 
@@ -183,6 +238,8 @@
      * @throws IOException if the target is lost or connection closed
      */
     public byte[] transceive(byte[] data) throws IOException {
+        checkConnected();
+
         try {
             byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, true);
             if (response == null) {
diff --git a/core/java/android/nfc/technology/IsoDep.java b/core/java/android/nfc/technology/IsoDep.java
index 5346c67..118bff7 100644
--- a/core/java/android/nfc/technology/IsoDep.java
+++ b/core/java/android/nfc/technology/IsoDep.java
@@ -75,6 +75,8 @@
      * @throws IOException, UnsupportedOperationException
      */
     public void selectAid(byte[] aid) throws IOException, UnsupportedOperationException {
+        checkConnected();
+
         throw new UnsupportedOperationException();
     }
 }
diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java
index defdcf2..d5f0a31 100644
--- a/core/java/android/nfc/technology/MifareClassic.java
+++ b/core/java/android/nfc/technology/MifareClassic.java
@@ -229,6 +229,8 @@
      * Authenticate for a given sector.
      */
     public boolean authenticateSector(int sector, byte[] key, boolean keyA) {
+        checkConnected();
+
         byte[] cmd = new byte[12];
 
         // First byte is the command
@@ -264,6 +266,8 @@
      * @throws IOException
      */
     public byte[] readBlock(int sector, int block) throws IOException {
+        checkConnected();
+
         byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
         byte[] blockread_cmd = { 0x30, addr }; // phHal_eMifareRead
 
@@ -300,6 +304,8 @@
      */
     @Override
     public byte[] transceive(byte[] data) throws IOException {
+        checkConnected();
+
         try {
             byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
             if (response == null) {
diff --git a/core/java/android/nfc/technology/MifareUltralight.java b/core/java/android/nfc/technology/MifareUltralight.java
index 58d2645..7103b4d 100644
--- a/core/java/android/nfc/technology/MifareUltralight.java
+++ b/core/java/android/nfc/technology/MifareUltralight.java
@@ -66,11 +66,44 @@
      * @throws IOException
      */
     public byte[] readBlock(int block) throws IOException {
+        checkConnected();
+
         byte[] blockread_cmd = { 0x30, (byte)block }; // phHal_eMifareRead
         return transceive(blockread_cmd);
     }
 
     /**
+     * @throws IOException
+     */
+    public byte[] readOTP() throws IOException {
+        checkConnected();
+
+        return readBlock(3); // OTP is at page 3
+    }
+
+    public void writePage(int block, byte[] data) throws IOException {
+        checkConnected();
+
+        byte[] pagewrite_cmd = new byte[data.length + 2];
+        pagewrite_cmd[0] = (byte) 0xA2;
+        pagewrite_cmd[1] = (byte) block;
+        System.arraycopy(data, 0, pagewrite_cmd, 2, data.length);
+
+        transceive(pagewrite_cmd);
+    }
+
+    public void writeBlock(int block, byte[] data) throws IOException {
+        checkConnected();
+
+        byte[] blockwrite_cmd = new byte[data.length + 2];
+        blockwrite_cmd[0] = (byte) 0xA0;
+        blockwrite_cmd[1] = (byte) block;
+        System.arraycopy(data, 0, blockwrite_cmd, 2, data.length);
+
+        transceive(blockwrite_cmd);
+    }
+
+    /**
      * Send data to a tag and receive the response.
      * <p>
      * This method will block until the response is received. It can be canceled
@@ -83,6 +116,8 @@
      */
     @Override
     public byte[] transceive(byte[] data) throws IOException {
+        checkConnected();
+
         try {
             byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
             if (response == null) {
@@ -95,12 +130,4 @@
         }
     }
 
-    /**
-     * @throws IOException
-     */
-    /*
-    public byte[] readOTP();
-    public void writePage(int block, byte[] data);
-    public void writeBlock(int block, byte[] data);
-     */
 }
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
index 7e194aa..c45c97d 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -113,6 +113,8 @@
      * and requires a connection.
      */
     public NdefMessage getNdefMessage() throws IOException, FormatException {
+        checkConnected();
+
         try {
             int serviceHandle = mTag.getServiceHandle();
             if (mTagService.isNdef(serviceHandle)) {
@@ -143,6 +145,8 @@
      * @throws IOException
      */
     public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
+        checkConnected();
+
         try {
             int errorCode = mTagService.ndefWrite(mTag.getServiceHandle(), msg);
             switch (errorCode) {
@@ -172,6 +176,8 @@
      * @throws IOException
      */
     public void writeExtraNdefMessage(int i, NdefMessage msg) throws IOException, FormatException {
+        checkConnected();
+
         throw new UnsupportedOperationException();
     }
 
@@ -180,6 +186,8 @@
      * @throws IOException
      */
     public boolean makeReadonly() throws IOException {
+        checkConnected();
+
         try {
             int errorCode = mTagService.ndefMakeReadOnly(mTag.getServiceHandle());
             switch (errorCode) {
@@ -205,11 +213,15 @@
      * For NFC Forum Type 1 and 2 only.
      */
     public void makeLowLevelReadonly() {
+        checkConnected();
+
         throw new UnsupportedOperationException();
     }
 
     @Override
     public byte[] transceive(byte[] data) {
+        checkConnected();
+
         throw new UnsupportedOperationException();
     }
 }
diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java
index bd21e58..899b95f 100644
--- a/core/java/android/nfc/technology/NdefFormatable.java
+++ b/core/java/android/nfc/technology/NdefFormatable.java
@@ -49,7 +49,9 @@
      * NdefFormatable#format(NdefMessage)}
      */
     public boolean canBeFormatted() throws IOException {
-      throw new UnsupportedOperationException();
+        checkConnected();
+
+        throw new UnsupportedOperationException();
     }
 
     /**
@@ -57,6 +59,8 @@
      * NdefMessage to be written on the tag.
      */
     public void format(NdefMessage firstMessage) throws IOException, FormatException {
+        checkConnected();
+
         try {
             byte[] DEFAULT_KEY = {(byte)0xFF,(byte)0xFF,(byte)0xFF,
                                   (byte)0xFF,(byte)0xFF,(byte)0xFF};
@@ -97,6 +101,8 @@
 
     @Override
     public byte[] transceive(byte[] data) {
+        checkConnected();
+
         throw new UnsupportedOperationException();
     }
 }
diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java
index bef1cc4..62216c1 100644
--- a/core/java/android/nfc/technology/TagTechnology.java
+++ b/core/java/android/nfc/technology/TagTechnology.java
@@ -82,6 +82,11 @@
     public void connect() throws IOException;
 
     /**
+     * @throws IOException
+     */
+    public void reconnect() throws IOException;
+
+    /**
      * Non-blocking. Immediately causes all blocking calls
      * to throw IOException.
      */
diff --git a/docs/html/guide/developing/debug-tasks.jd b/docs/html/guide/developing/debug-tasks.jd
index f0bf84c..8f40b48 100644
--- a/docs/html/guide/developing/debug-tasks.jd
+++ b/docs/html/guide/developing/debug-tasks.jd
@@ -42,8 +42,8 @@
   <dd>Dumps a log of system
       messages. The messages include a stack trace when the device throws an error,
       as well as {@link android.util.Log} messages you've written from your application. To run
-      logcat, execute <code>adb logcat</code> from your Android SDK {@code tools/} directory or,
-from DDMS, select <strong>Device > Run
+      logcat, execute <code>adb logcat</code> from your Android SDK {@code platform-tools/}
+directory or, from DDMS, select <strong>Device > Run
       logcat</strong>. When using the <a href="{@docRoot}sdk/eclipse-adt.html">ADT plugin for
 Eclipse</a>, you can also view logcat messages by opening the Logcat view, available from
 <strong>Window > Show View > Other > Android > Logcat</strong>.
diff --git a/docs/html/guide/developing/device.jd b/docs/html/guide/developing/device.jd
index 2e2d803..a4cec63 100644
--- a/docs/html/guide/developing/device.jd
+++ b/docs/html/guide/developing/device.jd
@@ -104,7 +104,8 @@
 </ol>
 
 <p>You can verify that your device is connected by executing <code>adb devices</code> from your 
-SDK {@code tools/} directory. If connected, you'll see the device name listed as a "device."</p>
+SDK {@code platform-tools/} directory. If connected, you'll see the device name listed as a
+"device."</p>
 
 <p>If using Eclipse, run or debug as usual. You will be presented
 with a <b>Device Chooser</b> dialog that lists the available emulator(s) and connected device(s).
diff --git a/docs/html/guide/developing/other-ide.jd b/docs/html/guide/developing/other-ide.jd
index 234b18f..d309f47 100644
--- a/docs/html/guide/developing/other-ide.jd
+++ b/docs/html/guide/developing/other-ide.jd
@@ -166,9 +166,10 @@
 <p>Once you've created your project, you're ready to begin development.
 You can move your project folder wherever you want for development, but keep in mind
 that you must use the <a href="{@docRoot}guide/developing/tools/adb.html">Android Debug Bridge</a> 
-(adb) &mdash; located in the SDK <code>tools/</code> directory &mdash; to send your application 
+(adb) &mdash; located in the SDK <code>platform-tools/</code> directory &mdash; to send your
+application 
 to the emulator (discussed later). So you need access between your project solution and 
-the <code>tools/</code> folder.</p>
+the <code>platform-tools/</code> folder.</p>
 
 <p class="caution"><strong>Caution:</strong> You should refrain from moving the
 location of the SDK directory, because this will break the build scripts. (They
@@ -460,7 +461,7 @@
   </li>
 
   <li><strong>Install your application</strong>
-    <p>From your SDK's <code>tools/</code> directory, install the {@code .apk} on the
+    <p>From your SDK's <code>platform-tools/</code> directory, install the {@code .apk} on the
 emulator:
     <pre>adb install <em>&lt;path_to_your_bin&gt;</em>.apk</pre>
     <p>Your APK file (signed with either a release or debug key) is in your project {@code bin/}
@@ -507,7 +508,7 @@
 Development</a> for more information.</p>
 
 <p>Once your device is set up and connected via USB, navigate to your
-SDK's <code>tools/</code> directory and install the <code>.apk</code> on the device:
+SDK's <code>platform-tools/</code> directory and install the <code>.apk</code> on the device:
     <pre>adb -d install <em>path/to/your/app</em>.apk</pre>
     <p>The {@code -d} flag specifies that you want to use the attached device (in case you also
 have an emulator running).</p>
diff --git a/docs/html/guide/developing/tools/adb.jd b/docs/html/guide/developing/tools/adb.jd
index 04eed8e..3c6351e 100644
--- a/docs/html/guide/developing/tools/adb.jd
+++ b/docs/html/guide/developing/tools/adb.jd
@@ -79,6 +79,8 @@
   <li>A daemon, which runs as a background process on each emulator or device instance. </li>
 </ul>
 
+<p>You can find the {@code adb} tool in {@code &lt;sdk&gt;/platform-tools/}.</p>
+
 <p>When you start an adb client, the client first checks whether there is an adb server process already running. If there isn't, it starts the server process. When the server starts, it binds to local TCP port 5037 and listens for commands sent from adb clients&mdash;all adb clients use port 5037 to communicate with the adb server. </p>
 
 <p>The server then sets up connections to all running emulator/device instances. It locates emulator/device instances by scanning odd-numbered ports in the range 5555 to 5585, the range used by emulators/devices. Where the server finds an adb daemon, it sets up a connection to that port. Note that each emulator/device instance acquires a pair of sequential ports &mdash; an even-numbered port for console connections and an odd-numbered port for adb connections. For example: </p>
diff --git a/docs/html/guide/developing/tools/draw9patch.jd b/docs/html/guide/developing/tools/draw9patch.jd
index 61da1e0..4d8043b 100644
--- a/docs/html/guide/developing/tools/draw9patch.jd
+++ b/docs/html/guide/developing/tools/draw9patch.jd
@@ -4,8 +4,9 @@
 <p>The Draw 9-patch tool allows you to easily create a 
    {@link android.graphics.NinePatch} graphic using a WYSIWYG editor.</p>
 <p>For an introduction to Nine-patch graphics and how they work, please read 
-the section on Nine-patch in the 
-<a href="{@docRoot}guide/topics/resources/available-resources.html#ninepatch">Nine-patch Images</a> topic.</p>
+the section about Nine-patch in the 
+<a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">2D Graphics</a>
+document.</p>
 
 <img src="{@docRoot}images/draw9patch-norm.png" style="float:right" alt="" height="300" width="341"
 />
diff --git a/docs/html/guide/developing/tools/index.jd b/docs/html/guide/developing/tools/index.jd
index 899c0dc..b3e4625 100644
--- a/docs/html/guide/developing/tools/index.jd
+++ b/docs/html/guide/developing/tools/index.jd
@@ -55,7 +55,8 @@
                   <dd>The adb tool lets you install your application's .apk files on an
                   emulator or device and access the emulator or device from a command line.
                   You can also use it to link a standard debugger to application code running
-                  on an Android emulator or device.</dd>
+                  on an Android emulator or device.
+                <p>This is located in {@code &lt;sdk&gt;/platform-tools/}.</p></dd>
 
   <dt><a href="aapt.html">Android Asset
           Packaging Tool</a> (aapt)</dt>
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index e46dbb4..13a86dd 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -14,9 +14,9 @@
           <li><a href="#drawables-from-xml">Creating from resource XML</a></li>
         </ol>
       </li>
-      <li><a href="#shape-drawable">ShapeDrawable</a></li>
+      <li><a href="#shape-drawable">Shape Drawable</a></li>
    <!--   <li><a href="#state-list">StateListDrawable</a></li> -->
-      <li><a href="#nine-patch">NinePatchDrawable</a></li>
+      <li><a href="#nine-patch">Nine-patch</a></li>
       <li><a href="#tween-animation">Tween Animation</a></li>
       <li><a href="#frame-animation">Frame Animation</a></li>
     </ol>
@@ -165,7 +165,7 @@
 
 
 
-<h2 id="shape-drawable">ShapeDrawable</h2>
+<h2 id="shape-drawable">Shape Drawable</h2>
 
 <p>When you want to dynamically draw some two-dimensional graphics, a {@link android.graphics.drawable.ShapeDrawable}
 object will probably suit your needs. With a ShapeDrawable, you can programmatically draw
@@ -234,6 +234,11 @@
 Some properties you might want to adjust include
 alpha transparency, color filter, dither, opacity and color.</p>
 
+<p>You can also define primitive drawable shapes using XML. For more information, see the
+section about Shape Drawables in the <a
+href="{@docRoot}guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a>
+document.</p>
+
 <!-- TODO
 <h2 id="state-list">StateListDrawable</h2>
 
@@ -245,7 +250,7 @@
 of the object it's attached to.
 -->
 
-<h2 id="nine-patch">NinePatchDrawable</h2>
+<h2 id="nine-patch">Nine-patch</h2>
 
 <p>A {@link android.graphics.drawable.NinePatchDrawable} graphic is a stretchable bitmap image, which Android
 will automatically resize to accommodate the contents of the View in which you have placed it as the background. 
@@ -424,8 +429,8 @@
 <code>{@link android.view.View#setAnimation(android.view.animation.Animation) View.setAnimation()}</code>.
 </p>
 
-<p>For more information on the XML syntax, available tags and attributes, see the discussion on animation 
-in the <a href="{@docRoot}guide/topics/resources/available-resources.html#animation">Available Resources</a>.</p>
+<p>For more information on the XML syntax, available tags and attributes, see <a
+href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
 
 <p class="note"><strong>Note:</strong> Regardless of how your animation may move or resize, the bounds of the 
 View that holds your animation will not automatically adjust to accommodate it. Even so, the animation will still
@@ -489,4 +494,6 @@
 <code>{@link android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code> method in 
 your Activity, which will get called when Android brings your window into focus.</p> 
 
+<p>For more information on the XML syntax, available tags and attributes, see <a
+href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
 
diff --git a/docs/html/sdk/installing.jd b/docs/html/sdk/installing.jd
index 488382e..9de247a 100644
--- a/docs/html/sdk/installing.jd
+++ b/docs/html/sdk/installing.jd
@@ -446,7 +446,7 @@
 </tr>
 <td colspan="3"><code>tools/</code></td>
 <td>Contains the set of development and profiling tools that are platform-independent, such
-as the emulator, the AVD and SDK Manager, adb, ddms, hierarchyviewer and more. The tools in
+as the emulator, the AVD and SDK Manager, ddms, hierarchyviewer and more. The tools in
 this directory may be updated at any time (from the <em>Android SDK Tools</em> component),
 independent of platform releases, whereas the tools in {@code platform-tools/} may be updated based
 on the latest platform release.</td>