Merge "Use EGL_NATIVE_VISUAL_ID to select EGLConfig" into gingerbread
diff --git a/NOTICE b/NOTICE
index 5560999..c45f010 100644
--- a/NOTICE
+++ b/NOTICE
@@ -63,6 +63,17 @@
 These files are Copyright 2003-2010 VisualOn, but released under
 the Apache2 License.
 
+  =========================================================================
+  ==  NOTICE file corresponding to the section 4 d of                    ==
+  ==  the Apache License, Version 2.0,                                   ==
+  ==  in this case for the Audio Effects code.                           ==
+  =========================================================================
+
+Audio Effects
+These files are Copyright (C) 2004-2010 NXP Software and
+Copyright (C) 2010 The Android Open Source Project, but released under
+the Apache2 License.
+
                                Apache License
                            Version 2.0, January 2004
                         http://www.apache.org/licenses/
diff --git a/api/10.xml b/api/10.xml
index 3b9ab1a..15fcffe 100644
--- a/api/10.xml
+++ b/api/10.xml
@@ -157967,21 +157967,6 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
-<method name="setPackageObbPath"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageName" type="java.lang.String">
-</parameter>
-<parameter name="path" type="java.lang.String">
-</parameter>
-</method>
 </class>
 <class name="MockResources"
  extends="android.content.res.Resources"
diff --git a/api/9.xml b/api/9.xml
index 3b9ab1a..15fcffe 100644
--- a/api/9.xml
+++ b/api/9.xml
@@ -157967,21 +157967,6 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
-<method name="setPackageObbPath"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageName" type="java.lang.String">
-</parameter>
-<parameter name="path" type="java.lang.String">
-</parameter>
-</method>
 </class>
 <class name="MockResources"
  extends="android.content.res.Resources"
diff --git a/api/current.xml b/api/current.xml
index 4006e67..6631b85 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -45984,19 +45984,6 @@
 <exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
 </exception>
 </method>
-<method name="getPackageObbPaths"
- return="java.lang.String[]"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageName" type="java.lang.String">
-</parameter>
-</method>
 <method name="getPackagesForUid"
  return="java.lang.String[]"
  abstract="true"
@@ -46468,21 +46455,6 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
-<method name="setPackageObbPaths"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageName" type="java.lang.String">
-</parameter>
-<parameter name="paths" type="java.lang.String[]">
-</parameter>
-</method>
 <field name="COMPONENT_ENABLED_STATE_DEFAULT"
  type="int"
  transient="false"
@@ -100830,6 +100802,19 @@
 <parameter name="activity" type="android.app.Activity">
 </parameter>
 </method>
+<method name="disableForegroundNdefPush"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="activity" type="android.app.Activity">
+</parameter>
+</method>
 <method name="enableForegroundDispatch"
  return="void"
  abstract="false"
@@ -100847,6 +100832,21 @@
 <parameter name="filters" type="android.content.IntentFilter...">
 </parameter>
 </method>
+<method name="enableForegroundNdefPush"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="activity" type="android.app.Activity">
+</parameter>
+<parameter name="msg" type="android.nfc.NdefMessage">
+</parameter>
+</method>
 <method name="getDefaultAdapter"
  return="android.nfc.NfcAdapter"
  abstract="false"
@@ -101070,6 +101070,33 @@
 >
 </field>
 </class>
+<class name="TagLostException"
+ extends="java.io.IOException"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="TagLostException"
+ type="android.nfc.TagLostException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<constructor name="TagLostException"
+ type="android.nfc.TagLostException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="message" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
 </package>
 <package name="android.nfc.technology"
 >
@@ -101083,17 +101110,6 @@
 >
 <implements name="android.nfc.technology.TagTechnology">
 </implements>
-<method name="checkConnected"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="close"
  return="void"
  abstract="false"
@@ -101164,21 +101180,6 @@
 <exception name="IOException" type="java.io.IOException">
 </exception>
 </method>
-<method name="transceive"
- return="byte[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="data" type="byte[]">
-</parameter>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
 </class>
 <class name="IsoDep"
  extends="android.nfc.technology.BasicTagTechnology"
@@ -101188,22 +101189,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="IsoDep"
- type="android.nfc.technology.IsoDep"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.nfc.NfcAdapter">
-</parameter>
-<parameter name="tag" type="android.nfc.Tag">
-</parameter>
-<parameter name="extras" type="android.os.Bundle">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</constructor>
 <method name="getHiLayerResponse"
  return="byte[]"
  abstract="false"
@@ -101226,6 +101211,34 @@
  visibility="public"
 >
 </method>
+<method name="setTimeout"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="timeout" type="int">
+</parameter>
+</method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
 </class>
 <class name="MifareClassic"
  extends="android.nfc.technology.BasicTagTechnology"
@@ -101235,22 +101248,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="MifareClassic"
- type="android.nfc.technology.MifareClassic"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.nfc.NfcAdapter">
-</parameter>
-<parameter name="tag" type="android.nfc.Tag">
-</parameter>
-<parameter name="extras" type="android.os.Bundle">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</constructor>
 <method name="authenticateBlock"
  return="boolean"
  abstract="false"
@@ -101267,6 +101264,8 @@
 </parameter>
 <parameter name="keyA" type="boolean">
 </parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
 </method>
 <method name="authenticateSector"
  return="boolean"
@@ -101284,6 +101283,8 @@
 </parameter>
 <parameter name="keyA" type="boolean">
 </parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
 </method>
 <method name="decrement"
  return="void"
@@ -101443,6 +101444,21 @@
 <exception name="IOException" type="java.io.IOException">
 </exception>
 </method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
 <method name="transfer"
  return="void"
  abstract="false"
@@ -101593,17 +101609,6 @@
  visibility="public"
 >
 </field>
-<field name="TYPE_DESFIRE"
- type="int"
- transient="false"
- volatile="false"
- value="3"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="TYPE_PLUS"
  type="int"
  transient="false"
@@ -101626,17 +101631,6 @@
  visibility="public"
 >
 </field>
-<field name="TYPE_ULTRALIGHT"
- type="int"
- transient="false"
- volatile="false"
- value="4"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="TYPE_UNKNOWN"
  type="int"
  transient="false"
@@ -101657,22 +101651,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="MifareUltralight"
- type="android.nfc.technology.MifareUltralight"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.nfc.NfcAdapter">
-</parameter>
-<parameter name="tag" type="android.nfc.Tag">
-</parameter>
-<parameter name="extras" type="android.os.Bundle">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</constructor>
 <method name="getType"
  return="int"
  abstract="false"
@@ -101694,12 +101672,12 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="block" type="int">
+<parameter name="page" type="int">
 </parameter>
 <exception name="IOException" type="java.io.IOException">
 </exception>
 </method>
-<method name="readOTP"
+<method name="transceive"
  return="byte[]"
  abstract="false"
  native="false"
@@ -101709,21 +101687,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
-<method name="writeBlock"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="block" type="int">
-</parameter>
 <parameter name="data" type="byte[]">
 </parameter>
 <exception name="IOException" type="java.io.IOException">
@@ -101739,7 +101702,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="block" type="int">
+<parameter name="page" type="int">
 </parameter>
 <parameter name="data" type="byte[]">
 </parameter>
@@ -101810,21 +101773,6 @@
  visibility="public"
 >
 </method>
-<method name="getExtraNdefMessage"
- return="android.nfc.NdefMessage[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<exception name="FormatException" type="android.nfc.FormatException">
-</exception>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
 <method name="getMaxSize"
  return="int"
  abstract="false"
@@ -101886,25 +101834,6 @@
 <exception name="IOException" type="java.io.IOException">
 </exception>
 </method>
-<method name="writeExtraNdefMessage"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="i" type="int">
-</parameter>
-<parameter name="msg" type="android.nfc.NdefMessage">
-</parameter>
-<exception name="FormatException" type="android.nfc.FormatException">
-</exception>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
 <method name="writeNdefMessage"
  return="void"
  abstract="false"
@@ -102023,22 +101952,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="NfcA"
- type="android.nfc.technology.NfcA"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.nfc.NfcAdapter">
-</parameter>
-<parameter name="tag" type="android.nfc.Tag">
-</parameter>
-<parameter name="extras" type="android.os.Bundle">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</constructor>
 <method name="getAtqa"
  return="byte[]"
  abstract="false"
@@ -102061,6 +101974,21 @@
  visibility="public"
 >
 </method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
 </class>
 <class name="NfcB"
  extends="android.nfc.technology.BasicTagTechnology"
@@ -102070,22 +101998,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="NfcB"
- type="android.nfc.technology.NfcB"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.nfc.NfcAdapter">
-</parameter>
-<parameter name="tag" type="android.nfc.Tag">
-</parameter>
-<parameter name="extras" type="android.os.Bundle">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</constructor>
 <method name="getApplicationData"
  return="byte[]"
  abstract="false"
@@ -102108,6 +102020,21 @@
  visibility="public"
 >
 </method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
 </class>
 <class name="NfcF"
  extends="android.nfc.technology.BasicTagTechnology"
@@ -102117,22 +102044,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="NfcF"
- type="android.nfc.technology.NfcF"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.nfc.NfcAdapter">
-</parameter>
-<parameter name="tag" type="android.nfc.Tag">
-</parameter>
-<parameter name="extras" type="android.os.Bundle">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</constructor>
 <method name="getManufacturer"
  return="byte[]"
  abstract="false"
@@ -102155,6 +102066,21 @@
  visibility="public"
 >
 </method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
 </class>
 <class name="NfcV"
  extends="android.nfc.technology.BasicTagTechnology"
@@ -102164,22 +102090,6 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<constructor name="NfcV"
- type="android.nfc.technology.NfcV"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.nfc.NfcAdapter">
-</parameter>
-<parameter name="tag" type="android.nfc.Tag">
-</parameter>
-<parameter name="extras" type="android.os.Bundle">
-</parameter>
-<exception name="RemoteException" type="android.os.RemoteException">
-</exception>
-</constructor>
 <method name="getDsfId"
  return="byte"
  abstract="false"
@@ -102202,6 +102112,21 @@
  visibility="public"
 >
 </method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
 </class>
 <interface name="TagTechnology"
  abstract="true"
@@ -159724,19 +159649,6 @@
 <exception name="PackageManager.NameNotFoundException" type="android.content.pm.PackageManager.NameNotFoundException">
 </exception>
 </method>
-<method name="getPackageObbPaths"
- return="java.lang.String[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageName" type="java.lang.String">
-</parameter>
-</method>
 <method name="getPackagesForUid"
  return="java.lang.String[]"
  abstract="false"
@@ -160206,36 +160118,6 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
-<method name="setPackageObbPath"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageName" type="java.lang.String">
-</parameter>
-<parameter name="path" type="java.lang.String">
-</parameter>
-</method>
-<method name="setPackageObbPaths"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="packageName" type="java.lang.String">
-</parameter>
-<parameter name="paths" type="java.lang.String[]">
-</parameter>
-</method>
 </class>
 <class name="MockResources"
  extends="android.content.res.Resources"
@@ -226827,7 +226709,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
 </parameter>
 </method>
 </interface>
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e3fa32c..162d9eb 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1439,6 +1439,16 @@
         }
     }
 
+    public void unregisterOnActivityPausedListener(Activity activity,
+            OnActivityPausedListener listener) {
+        synchronized (mOnPauseListeners) {
+            ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
+            if (list != null) {
+                list.remove(listener);
+            }
+        }
+    }
+
     public final ActivityInfo resolveActivityInfo(Intent intent) {
         ActivityInfo aInfo = intent.resolveActivityInfo(
                 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 18ab478..50ec34f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2699,25 +2699,6 @@
             return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
         }
 
-        @Override
-        public void setPackageObbPaths(String packageName, String[] paths) {
-            try {
-                mPM.setPackageObbPaths(packageName, paths);
-            } catch (RemoteException e) {
-                // Should never happen!
-            }
-        }
-
-        @Override
-        public String[] getPackageObbPaths(String packageName) {
-            try {
-                return mPM.getPackageObbPaths(packageName);
-            } catch (RemoteException e) {
-                // Should never happen!
-            }
-            return null;
-        }
-
         private final ContextImpl mContext;
         private final IPackageManager mPM;
 
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 44b0c96..bfc9185 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -321,7 +321,4 @@
 
     boolean setInstallLocation(int loc);
     int getInstallLocation();
-
-    void setPackageObbPaths(in String packageName, in String[] paths);
-    String[] getPackageObbPaths(in String packageName);
 }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a1c29f7..922f8cd 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2271,32 +2271,4 @@
      */
     public abstract void movePackage(
             String packageName, IPackageMoveObserver observer, int flags);
-
-    /**
-     * Sets the Opaque Binary Blob (OBB) file path associated with a package
-     * name. The caller must have the
-     * {@link android.Manifest.permission#INSTALL_PACKAGES} permission.
-     * <p>
-     * NOTE: The existence or format of this file is not currently checked, but
-     * it may be in the future.
-     * 
-     * @param packageName Name of the package with which to associate the .obb
-     *            file.
-     * @param paths Arrays of paths on the filesystem to the .obb files
-     *            associated with the package.
-     * @see #getPackageObbPaths(String)
-     */
-    public abstract void setPackageObbPaths(String packageName, String[] paths);
-
-    /**
-     * Gets the Opaque Binary Blob (OBB) file path associated with the package.
-     * The caller must be the owner of the package queried or have the
-     * {@link android.Manifest.permission#INSTALL_PACKAGES} permission.
-     * 
-     * @param packageName Name of the package with which to associate the .obb
-     *            file.
-     * @return array of paths to .obb files associated with the package
-     * @see #setPackageObbPaths(String, String[])
-     */
-    public abstract String[] getPackageObbPaths(String packageName);
 }
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 4a75514..f079e42 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -25,6 +25,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
 import android.view.IRotationWatcher;
 import android.view.IWindowManager;
 import android.view.Surface;
@@ -489,6 +490,8 @@
         private final Handler mHandler;
         private SensorEvent mValuesPool;
         public SparseBooleanArray mSensors = new SparseBooleanArray();
+        public SparseBooleanArray mFirstEvent = new SparseBooleanArray();
+        public SparseIntArray mSensorAccuracies = new SparseIntArray();
 
         ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) {
             mSensorEventListener = listener;
@@ -499,10 +502,30 @@
             mHandler = new Handler(looper) {
                 @Override
                 public void handleMessage(Message msg) {
-                    SensorEvent t = (SensorEvent)msg.obj;
-                    if (t.accuracy >= 0) {
-                        mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy);
+                    final SensorEvent t = (SensorEvent)msg.obj;
+                    final int handle = t.sensor.getHandle();
+
+                    switch (t.sensor.getType()) {
+                        // Only report accuracy for sensors that support it.
+                        case Sensor.TYPE_MAGNETIC_FIELD:
+                        case Sensor.TYPE_ORIENTATION:
+                            // call onAccuracyChanged() only if the value changes
+                            final int accuracy = mSensorAccuracies.get(handle);
+                            if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
+                                mSensorAccuracies.put(handle, t.accuracy);
+                                mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy);
+                            }
+                            break;
+                        default:
+                            // For other sensors, just report the accuracy once
+                            if (mFirstEvent.get(handle) == false) {
+                                mFirstEvent.put(handle, true);
+                                mSensorEventListener.onAccuracyChanged(
+                                        t.sensor, SENSOR_STATUS_ACCURACY_HIGH);
+                            }
+                            break;
                     }
+
                     mSensorEventListener.onSensorChanged(t);
                     returnToPool(t);
                 }
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index cb9fc9d..cfeff52 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -50,6 +50,8 @@
     void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
         in IntentFilter[] filters);
     void disableForegroundDispatch(in ComponentName activity);
+    void enableForegroundNdefPush(in ComponentName activity, in NdefMessage msg);
+    void disableForegroundNdefPush(in ComponentName activity);
 
     // Non-public methods
     // TODO: check and complete
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index 5d222d9..57dc38c 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -17,6 +17,7 @@
 package android.nfc;
 
 import android.nfc.NdefMessage;
+import android.nfc.TransceiveResult;
 
 /**
  * @hide
@@ -30,7 +31,7 @@
     byte[] getUid(int nativeHandle);
     boolean isNdef(int nativeHandle);
     boolean isPresent(int nativeHandle);
-    byte[] transceive(int nativeHandle, in byte[] data, boolean raw);
+    TransceiveResult transceive(int nativeHandle, in byte[] data, boolean raw);
 
     int getLastError(int nativeHandle);
 
@@ -39,4 +40,7 @@
     int ndefMakeReadOnly(int nativeHandle);
     boolean ndefIsWritable(int nativeHandle);
     int formatNdef(int nativeHandle, in byte[] key);
+
+    void setIsoDepTimeout(int timeout);
+    void resetIsoDepTimeout();
 }
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index c0c0462..f6605b8 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -413,13 +413,6 @@
         }
     }
 
-    class ForegroundDispatchPausedListener implements OnActivityPausedListener {
-        @Override
-        public void onPaused(Activity activity) {
-            disableForegroundDispatchInternal(activity, true);
-        }
-    }
-
     /**
      * 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
@@ -438,12 +431,12 @@
             throw new NullPointerException();
         }
         if (!activity.isResumed()) {
-            throw new IllegalStateException("Foregorund dispatching can onlly be enabled " +
+            throw new IllegalStateException("Foregorund dispatching can only be enabled " +
                     "when your activity is resumed");
         }
         try {
             ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity,
-                    new ForegroundDispatchPausedListener());
+                    mForegroundDispatchListener);
             sService.enableForegroundDispatch(activity.getComponentName(), intent, filters);
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
@@ -452,15 +445,26 @@
 
     /**
      * Disables foreground activity dispatching setup with
-     * {@link #enableForegroundDispatch}. This must be called before the Activity returns from
+     * {@link #enableForegroundDispatch}.
+     *
+     * <p>This must be called before the Activity returns from
      * it's <code>onPause()</code> or this method will throw an IllegalStateException.
      *
-     * This method must be called from the main thread.
+     * <p>This method must be called from the main thread.
      */
     public void disableForegroundDispatch(Activity activity) {
+        ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity,
+                mForegroundDispatchListener);
         disableForegroundDispatchInternal(activity, false);
     }
 
+    OnActivityPausedListener mForegroundDispatchListener = new OnActivityPausedListener() {
+        @Override
+        public void onPaused(Activity activity) {
+            disableForegroundDispatchInternal(activity, true);
+        }
+    };
+
     void disableForegroundDispatchInternal(Activity activity, boolean force) {
         try {
             sService.disableForegroundDispatch(activity.getComponentName());
@@ -474,6 +478,60 @@
     }
 
     /**
+     * Enable NDEF messages push while this Activity is in the foreground.
+     */
+    public void enableForegroundNdefPush(Activity activity, NdefMessage msg) {
+        if (activity == null || msg == null) {
+            throw new NullPointerException();
+        }
+        if (!activity.isResumed()) {
+            throw new IllegalStateException("Foregorund NDEF push can only be enabled " +
+                    "when your activity is resumed");
+        }
+        try {
+            ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity,
+                    mForegroundNdefPushListener);
+            sService.enableForegroundNdefPush(activity.getComponentName(), msg);
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+        }
+    }
+
+    /**
+     * Disables foreground NDEF push setup with
+     * {@link #enableForegroundNdefPush}.
+     *
+     * <p>This must be called before the Activity returns from
+     * it's <code>onPause()</code> or this method will throw an IllegalStateException.
+     *
+     * <p>This method must be called from the main thread.
+     */
+    public void disableForegroundNdefPush(Activity activity) {
+        ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity,
+                mForegroundNdefPushListener);
+        disableForegroundNdefPushInternal(activity, false);
+    }
+
+    OnActivityPausedListener mForegroundNdefPushListener = new OnActivityPausedListener() {
+        @Override
+        public void onPaused(Activity activity) {
+            disableForegroundNdefPushInternal(activity, true);
+        }
+    };
+
+    void disableForegroundNdefPushInternal(Activity activity, boolean force) {
+        try {
+            sService.disableForegroundNdefPush(activity.getComponentName());
+            if (!force && !activity.isResumed()) {
+                throw new IllegalStateException("You must disable forgeground NDEF push " +
+                        "while your activity is still resumed");
+            }
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+        }
+    }
+
+    /**
      * Retrieve a TagTechnology object used to interact with a Tag that is
      * in field.
      * <p>
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 7bd2289..8e2360a 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -36,8 +36,8 @@
 /**
  * Represents a (generic) discovered tag.
  * <p>
- * A tag is a passive NFC element, such as NFC Forum Tag's, Mifare class Tags,
- * Sony Felica Tags.
+ * A tag is a passive NFC element, such as NFC Forum Tag's, MIFARE class Tags,
+ * Sony FeliCa Tags, etc.
  * <p>
  * Tag's have a type and usually have a UID.
  * <p>
diff --git a/core/java/android/nfc/TagLostException.java b/core/java/android/nfc/TagLostException.java
new file mode 100644
index 0000000..1981d7c
--- /dev/null
+++ b/core/java/android/nfc/TagLostException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import java.io.IOException;
+
+public class TagLostException extends IOException {
+    public TagLostException() {
+        super();
+    }
+
+    public TagLostException(String message) {
+        super(message);
+    }
+}
diff --git a/core/java/android/nfc/TransceiveResult.aidl b/core/java/android/nfc/TransceiveResult.aidl
new file mode 100644
index 0000000..98f92ee
--- /dev/null
+++ b/core/java/android/nfc/TransceiveResult.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+parcelable TransceiveResult;
diff --git a/core/java/android/nfc/TransceiveResult.java b/core/java/android/nfc/TransceiveResult.java
new file mode 100644
index 0000000..16244b8
--- /dev/null
+++ b/core/java/android/nfc/TransceiveResult.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Class used to pipe transceive result from the NFC service.
+ *
+ * @hide
+ */
+public final class TransceiveResult implements Parcelable {
+    private final boolean mTagLost;
+    private final boolean mSuccess;
+    private final byte[] mResponseData;
+
+    public TransceiveResult(final boolean success, final boolean tagIsLost,
+            final byte[] data) {
+        mSuccess = success;
+        mTagLost = tagIsLost;
+        mResponseData = data;
+    }
+
+    public boolean isSuccessful() {
+        return mSuccess;
+    }
+
+    public boolean isTagLost() {
+        return mTagLost;
+    }
+
+    public byte[] getResponseData() {
+        return mResponseData;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mSuccess ? 1 : 0);
+        dest.writeInt(mTagLost ? 1 : 0);
+        if (mSuccess) {
+            dest.writeInt(mResponseData.length);
+            dest.writeByteArray(mResponseData);
+        }
+    }
+
+    public static final Parcelable.Creator<TransceiveResult> CREATOR =
+            new Parcelable.Creator<TransceiveResult>() {
+        @Override
+        public TransceiveResult createFromParcel(Parcel in) {
+            boolean success = (in.readInt() == 1) ? true : false;
+            boolean tagLost = (in.readInt() == 1) ? true : false;
+            byte[] responseData;
+
+            if (success) {
+                int responseLength = in.readInt();
+                responseData = new byte[responseLength];
+                in.readByteArray(responseData);
+            } else {
+                responseData = null;
+            }
+            return new TransceiveResult(success, tagLost, responseData);
+        }
+
+        @Override
+        public TransceiveResult[] newArray(int size) {
+            return new TransceiveResult[size];
+        }
+    };
+
+}
diff --git a/core/java/android/nfc/technology/BasicTagTechnology.java b/core/java/android/nfc/technology/BasicTagTechnology.java
index f529ee5..b67c607 100644
--- a/core/java/android/nfc/technology/BasicTagTechnology.java
+++ b/core/java/android/nfc/technology/BasicTagTechnology.java
@@ -21,8 +21,10 @@
 import android.nfc.INfcAdapter;
 import android.nfc.INfcTag;
 import android.nfc.NfcAdapter;
+import android.nfc.TransceiveResult;
 import android.nfc.Tag;
 import android.nfc.ErrorCodes;
+import android.nfc.TagLostException;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -39,10 +41,7 @@
     /*package*/ final INfcAdapter mService;
     /*package*/ final INfcTag mTagService;
 
-    /**
-     * @hide
-     */
-    public BasicTagTechnology(NfcAdapter adapter, Tag tag, int tech) throws RemoteException {
+    BasicTagTechnology(NfcAdapter adapter, Tag tag, int tech) throws RemoteException {
         int[] techList = tag.getTechnologyList();
         int i;
 
@@ -64,46 +63,36 @@
         mSelectedTechnology = tech;
     }
 
-    /**
-     * @hide
-     */
-    public BasicTagTechnology(NfcAdapter adapter, Tag tag) throws RemoteException {
+    BasicTagTechnology(NfcAdapter adapter, Tag tag) throws RemoteException {
         this(adapter, tag, tag.getTechnologyList()[0]);
     }
 
-    /**
-     * Get the {@link Tag} this connection is associated with.
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     */
     @Override
     public Tag getTag() {
         return mTag;
     }
 
-    public void checkConnected() {
+    /** Internal helper to throw IllegalStateException if the technology isn't connected */
+    void checkConnected() {
        if ((mTag.getConnectedTechnology() != getTechnologyId()) ||
                (mTag.getConnectedTechnology() == -1)) {
            throw new IllegalStateException("Call connect() first!");
        }
     }
 
-    /**
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     */
     @Override
     public int getTechnologyId() {
         return mSelectedTechnology;
     }
 
     /**
-     * Helper to indicate if {@link #transceive transceive()} calls might succeed.
+     * Helper to indicate if {@link #connect} has succeeded.
      * <p>
      * Does not cause RF activity, and does not block.
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
      * @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 {@link #transceive transceive()}, in case connection is lost after this method
-     * returns true.
+     * while using methods that require a connection in case the connection is lost after this
+     * method returns.
      */
     public boolean isConnected() {
         if (!mIsConnected) {
@@ -118,16 +107,6 @@
         }
     }
 
-    /**
-     * Connect to the {@link Tag} associated with this connection.
-     * <p>
-     * This method blocks until the connection is 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 connect() throws IOException {
         try {
@@ -146,17 +125,6 @@
         }
     }
 
-    /**
-     * 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) {
@@ -179,16 +147,6 @@
         }
     }
 
-    /**
-     * Close this connection.
-     * <p>
-     * Causes blocking operations such as {@link #transceive transceive()} or {@link #connect} to
-     * be canceled and immediately throw {@link java.io.IOException}.
-     * <p>
-     * Once this method is called, this object cannot be re-used and should be discarded. Further
-     * calls to {@link #transceive transceive()} or {@link #connect} will fail.
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     */
     @Override
     public void close() {
         try {
@@ -204,34 +162,29 @@
         }
     }
 
-    /** internal transceive */
+    /** Internal transceive */
     /*package*/ byte[] transceive(byte[] data, boolean raw) throws IOException {
         checkConnected();
 
         try {
-            byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, raw);
-            if (response == null) {
+            TransceiveResult result = mTagService.transceive(mTag.getServiceHandle(), data, raw);
+            if (result == null) {
                 throw new IOException("transceive failed");
+            } else {
+                if (result.isSuccessful()) {
+                    return result.getResponseData();
+                } else {
+                    if (result.isTagLost()) {
+                        throw new TagLostException("Tag was lost.");
+                    }
+                    else {
+                        throw new IOException("transceive failed");
+                    }
+                }
             }
-            return response;
         } catch (RemoteException e) {
             Log.e(TAG, "NFC service dead", e);
             throw new IOException("NFC service died");
         }
     }
-
-    /**
-     * 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.
-     *
-     * @param data bytes to send
-     * @return bytes received in response
-     * @throws IOException if the target is lost or connection closed
-     */
-    public byte[] transceive(byte[] data) throws IOException {
-        return transceive(data, true);
-    }
 }
diff --git a/core/java/android/nfc/technology/IsoDep.java b/core/java/android/nfc/technology/IsoDep.java
index 03c518e..c58127a 100644
--- a/core/java/android/nfc/technology/IsoDep.java
+++ b/core/java/android/nfc/technology/IsoDep.java
@@ -20,6 +20,7 @@
 import android.nfc.Tag;
 import android.os.Bundle;
 import android.os.RemoteException;
+import android.util.Log;
 
 import java.io.IOException;
 
@@ -38,6 +39,8 @@
  * permission.
  */
 public final class IsoDep extends BasicTagTechnology {
+    private static final String TAG = "NFC";
+
     /** @hide */
     public static final String EXTRA_HI_LAYER_RESP = "hiresp";
     /** @hide */
@@ -46,6 +49,7 @@
     private byte[] mHiLayerResponse = null;
     private byte[] mHistBytes = null;
 
+    /** @hide */
     public IsoDep(NfcAdapter adapter, Tag tag, Bundle extras)
             throws RemoteException {
         super(adapter, tag, TagTechnology.ISO_DEP);
@@ -56,16 +60,58 @@
     }
 
     /**
-     * 3A only
+     * 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.
+     */
+    public void setTimeout(int timeout) {
+        try {
+            mTagService.setIsoDepTimeout(timeout);
+        } catch (RemoteException e) {
+            Log.e(TAG, "NFC service dead", e);
+        }
+    }
+
+    @Override
+    public void close() {
+        try {
+            mTagService.resetIsoDepTimeout();
+        } catch (RemoteException e) {
+            Log.e(TAG, "NFC service dead", e);
+        }
+        super.close();
+    }
+
+    /**
+     * Return the historical bytes if the tag is using {@link NfcA}, null otherwise.
      */
     public byte[] getHistoricalBytes() {
         return mHistBytes;
     }
 
     /**
-     * 3B only
+     * Return the hi layer response bytes if the tag is using {@link NfcB}, null otherwise.
      */
     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.
+     *
+     * @param data bytes to send
+     * @return bytes received in response
+     * @throws IOException if the target is lost or connection closed
+     */
+    public byte[] transceive(byte[] data) throws IOException {
+        return transceive(data, true);
+    }
 }
diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java
index 3be38fe..a2abaa3 100644
--- a/core/java/android/nfc/technology/MifareClassic.java
+++ b/core/java/android/nfc/technology/MifareClassic.java
@@ -17,6 +17,7 @@
 package android.nfc.technology;
 
 import android.nfc.NfcAdapter;
+import android.nfc.TagLostException;
 import android.nfc.Tag;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -24,21 +25,22 @@
 import java.io.IOException;
 
 /**
- * Concrete class for TagTechnology.MIFARE_CLASSIC
+ * Technology class representing MIFARE Classic tags (also known as MIFARE Standard).
  *
- * MIFARE Classic has n sectors, with varying sizes, although
- * they are at least the same pattern for any one MIFARE Classic
- * product. Each sector has two keys. Authentication with the correct
- * key is needed before access to any sector.
+ * <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.
  *
- * Each sector has k blocks.
- * Block size is constant across the whole MIFARE classic family.
+ * <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 #authenticateSector(int, byte[], boolean)} or
+ * {@link #authenticateBlock(int, byte[], boolean)} to gain authorize your request.
  */
 public final class MifareClassic extends BasicTagTechnology {
     /**
-     * The well-known, default MIFARE read key.
-     * Use this key to effectively make the payload in this sector
-     * public.
+     * 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.
      */
     public static final byte[] KEY_DEFAULT =
             {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
@@ -53,39 +55,45 @@
     public static final byte[] KEY_NFC_FORUM =
             {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7};
 
+    /** A MIFARE Classic tag */
     public static final int TYPE_CLASSIC = 0;
+    /** A MIFARE Plus tag */
     public static final int TYPE_PLUS = 1;
+    /** A MIFARE Pro tag */
     public static final int TYPE_PRO = 2;
-    public static final int TYPE_DESFIRE = 3;
-    public static final int TYPE_ULTRALIGHT = 4;
+    /** The tag type is unknown */
     public static final int TYPE_UNKNOWN = 5;
 
+    /** The tag contains 16 sectors, each holding 4 blocks. */
     public static final int SIZE_1K = 1024;
+    /** The tag contains 32 sectors, each holding 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
+     * contain 16 blocks.
+     */
     public static final int SIZE_4K = 4096;
+    /** The tag contains 5 sectors, each holding 4 blocks. */
     public static final int SIZE_MINI = 320;
+    /** The capacity is unknown */
     public static final int SIZE_UNKNOWN = 0;
 
     private boolean mIsEmulated;
     private int mType;
     private int mSize;
 
+    /** @hide */
     public MifareClassic(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
         super(adapter, tag, TagTechnology.MIFARE_CLASSIC);
 
-        // Check if this could actually be a Mifare
+        // Check if this could actually be a MIFARE Classic
         NfcA a = (NfcA) adapter.getTechnology(tag, TagTechnology.NFC_A);
-        //short[] ATQA = getATQA(tag);
 
         mIsEmulated = false;
         mType = TYPE_UNKNOWN;
         mSize = SIZE_UNKNOWN;
 
         switch (a.getSak()) {
-            case 0x00:
-                // could be UL or UL-C
-                mType = TYPE_ULTRALIGHT;
-                break;
             case 0x08:
                 // Type == classic
                 // Size = 1K
@@ -122,7 +130,7 @@
                 // TODO this really should be a short, not byte
                 if (a.getAtqa()[0] == 0x03) {
                     // Type == DESFIRE
-                    mType = TYPE_DESFIRE;
+                    break;
                 } else {
                     // Type == MF+
                     // SL = SL3
@@ -160,27 +168,25 @@
                 mType = TYPE_PRO;
                 mSize = SIZE_4K;
                 break;
-            default:
-                // Unknown mifare
-                mType = TYPE_UNKNOWN;
-                mSize = SIZE_UNKNOWN;
-                break;
         }
     }
 
-    // Immutable data known at discovery time
+    /** Returns the size of the tag, determined at discovery time */
     public int getSize() {
         return mSize;
     }
 
+    /** Returns the size of the tag, determined at discovery time */
     public int getType() {
         return mType;
     }
 
+    /** Returns true if the tag is emulated, determined at discovery time */
     public boolean isEmulated() {
         return mIsEmulated;
     }
 
+    /** Returns the number of sectors on this tag, determined at discovery time */
     public int getSectorCount() {
         switch (mSize) {
             case SIZE_1K: {
@@ -201,10 +207,12 @@
         }
     }
 
+    /** Returns the sector size, determined at discovery time */
     public int getSectorSize(int sector) {
         return getBlockCount(sector) * 16;
     }
 
+    /** Returns the total block count, determined at discovery time */
     public int getTotalBlockCount() {
         int totalBlocks = 0;
         for (int sec = 0; sec < getSectorCount(); sec++) {
@@ -214,6 +222,7 @@
         return totalBlocks;
     }
 
+    /** Returns the block count for the given sector, determined at discovery time */
     public int getBlockCount(int sector) {
         if (sector >= getSectorCount()) {
             throw new IllegalArgumentException("this card only has " + getSectorCount() +
@@ -237,10 +246,10 @@
 
     // Methods that require connect()
     /**
-     * Authenticate for a given block.
-     * Note that this will authenticate the entire sector the block belongs to.
+     * Authenticate the entire sector that the given block resides in.
+     * <p>This requires a that the tag be connected.
      */
-    public boolean authenticateBlock(int block, byte[] key, boolean keyA) {
+    public boolean authenticateBlock(int block, byte[] key, boolean keyA) throws IOException {
         checkConnected();
 
         byte[] cmd = new byte[12];
@@ -266,6 +275,8 @@
             if ((transceive(cmd, false) != null)) {
                 return true;
             }
+        } catch (TagLostException e) {
+            throw e;
         } catch (IOException e) {
             // No need to deal with, will return false anyway
         }
@@ -274,8 +285,9 @@
 
     /**
      * Authenticate for a given sector.
+     * <p>This requires a that the tag be connected.
      */
-    public boolean authenticateSector(int sector, byte[] key, boolean keyA) {
+    public boolean authenticateSector(int sector, byte[] key, boolean keyA) throws IOException {
         checkConnected();
 
         byte addr = (byte) ((firstBlockInSector(sector)) & 0xff);
@@ -288,6 +300,7 @@
     /**
      * Sector indexing starts at 0.
      * Block indexing starts at 0, and resets in each sector.
+     * <p>This requires a that the tag be connected.
      * @throws IOException
      */
     public byte[] readBlock(int sector, int block) throws IOException {
@@ -295,11 +308,11 @@
 
         byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
         return readBlock(addr);
-
     }
 
     /**
      * Reads absolute block index.
+     * <p>This requires a that the tag be connected.
      * @throws IOException
      */
     public byte[] readBlock(int block) throws IOException {
@@ -313,6 +326,7 @@
 
     /**
      * Writes absolute block index.
+     * <p>This requires a that the tag be connected.
      * @throws IOException
      */
     public void writeBlock(int block, byte[] data) throws IOException {
@@ -329,6 +343,7 @@
 
     /**
      * Writes relative block in sector.
+     * <p>This requires a that the tag be connected.
      * @throws IOException
      */
     public void writeBlock(int sector, int block, byte[] data) throws IOException {
@@ -342,7 +357,6 @@
     public void increment(int block) throws IOException {
         checkConnected();
 
-        byte addr = (byte) block;
         byte[] incr_cmd = { (byte) 0xC1, (byte) block };
 
         transceive(incr_cmd, false);
@@ -351,7 +365,6 @@
     public void decrement(int block) throws IOException {
         checkConnected();
 
-        byte addr = (byte) block;
         byte[] decr_cmd = { (byte) 0xC0, (byte) block };
 
         transceive(decr_cmd, false);
@@ -360,7 +373,6 @@
     public void transfer(int block) throws IOException {
         checkConnected();
 
-        byte addr = (byte) block;
         byte[] trans_cmd = { (byte) 0xB0, (byte) block };
 
         transceive(trans_cmd, false);
@@ -369,9 +381,24 @@
     public void restore(int block) throws IOException {
         checkConnected();
 
-        byte addr = (byte) block;
         byte[] rest_cmd = { (byte) 0xC2, (byte) block };
 
         transceive(rest_cmd, false);
     }
+
+    /**
+     * 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
+     */
+    public byte[] transceive(byte[] data) throws IOException {
+        return transceive(data, true);
+    }
 }
diff --git a/core/java/android/nfc/technology/MifareUltralight.java b/core/java/android/nfc/technology/MifareUltralight.java
index 525b85b..5c8cb3c 100644
--- a/core/java/android/nfc/technology/MifareUltralight.java
+++ b/core/java/android/nfc/technology/MifareUltralight.java
@@ -16,33 +16,35 @@
 
 package android.nfc.technology;
 
-import java.io.IOException;
-
 import android.nfc.NfcAdapter;
 import android.nfc.Tag;
 import android.os.Bundle;
 import android.os.RemoteException;
 
+import java.io.IOException;
+
 /**
- * Concrete class for TagTechnology.MIFARE_ULTRALIGHT
+ * Technology class representing MIFARE Ultralight and MIFARE Ultralight C tags.
  *
- * MIFARE Ultralight has n sectors, with varying sizes, although
- * they are at least the same pattern for any one MIFARE Ultralight
- * product. Each sector has two keys. Authentication with the correct
- * key is needed before access to any sector.
+ * <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.
  *
- * Each sector has k blocks.
- * Block size is constant across the whole MIFARE Ultralight family.
+ * <p>MIFARE Ultralight class tags have a series of 4 bytes pages that can be individually written
+ * and read in chunks of 4 for a total read of 16 bytes.
  */
 public final class MifareUltralight extends BasicTagTechnology {
+    /** A MIFARE Ultralight tag */
     public static final int TYPE_ULTRALIGHT = 1;
+    /** A MIFARE Ultralight C tag */
     public static final int TYPE_ULTRALIGHT_C = 2;
+    /** The tag type is unknown */
     public static final int TYPE_UNKNOWN = 10;
 
     private static final int NXP_MANUFACTURER_ID = 0x04;
 
     private int mType;
 
+    /** @hide */
     public MifareUltralight(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
         super(adapter, tag, TagTechnology.MIFARE_ULTRALIGHT);
 
@@ -57,49 +59,59 @@
         }
     }
 
+    /** Returns the type of the tag */
     public int getType() {
         return mType;
     }
 
     // Methods that require connect()
     /**
+     * Reads a single 16 byte block from the given page offset.
+     *
+     * <p>This requires a that the tag be connected.
+     *
      * @throws IOException
      */
-    public byte[] readBlock(int block) throws IOException {
+    public byte[] readBlock(int page) throws IOException {
         checkConnected();
 
-        byte[] blockread_cmd = { 0x30, (byte)block }; // phHal_eMifareRead
+        byte[] blockread_cmd = { 0x30, (byte) page}; // phHal_eMifareRead
         return transceive(blockread_cmd, false);
     }
 
     /**
+     * Writes a 4 byte page to the tag.
+     *
+     * <p>This requires a that the tag be connected.
+     *
+     * @param page The offset of the page to write
+     * @param data The data to write
      * @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 {
+    public void writePage(int page, byte[] data) throws IOException {
         checkConnected();
 
         byte[] pagewrite_cmd = new byte[data.length + 2];
         pagewrite_cmd[0] = (byte) 0xA2;
-        pagewrite_cmd[1] = (byte) block;
+        pagewrite_cmd[1] = (byte) page;
         System.arraycopy(data, 0, pagewrite_cmd, 2, data.length);
 
         transceive(pagewrite_cmd, false);
     }
 
-    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, false);
+    /**
+     * 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
+     */
+    public byte[] transceive(byte[] data) throws IOException {
+        return transceive(data, true);
     }
 }
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
index 5f05b58..f537941 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -100,15 +100,6 @@
     }
 
     /**
-     * Get optional extra NDEF messages.
-     * Some tags may contain extra NDEF messages, but not all
-     * implementations will be able to read them.
-     */
-    public NdefMessage[] getExtraNdefMessage() throws IOException, FormatException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Get 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},
@@ -208,22 +199,6 @@
     }
 
     /**
-     * Attempt to write extra NDEF messages.
-     * Implementations may be able to write extra NDEF
-     * message after the first primary message, but it is not
-     * guaranteed. Even if it can be written, other implementations
-     * may not be able to read NDEF messages after the primary message.
-     * It is recommended to use additional NDEF records instead.
-     *
-     * @throws IOException
-     */
-    public void writeExtraNdefMessage(int i, NdefMessage msg) throws IOException, FormatException {
-        checkConnected();
-
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Indicates whether a tag can be made read-only with
      * {@link #makeReadonly()}
      */
@@ -246,28 +221,26 @@
         checkConnected();
 
         try {
-            int errorCode = mTagService.ndefMakeReadOnly(mTag.getServiceHandle());
-            switch (errorCode) {
-                case ErrorCodes.SUCCESS:
-                    return true;
-                case ErrorCodes.ERROR_IO:
-                    throw new IOException();
-                case ErrorCodes.ERROR_INVALID_PARAM:
-                    return false;
-                default:
-                    // Should not happen
-                    throw new IOException();
-            }
+            if (mTagService.isNdef(mTag.getServiceHandle())) {
+                int errorCode = mTagService.ndefMakeReadOnly(mTag.getServiceHandle());
+                switch (errorCode) {
+                    case ErrorCodes.SUCCESS:
+                        return true;
+                    case ErrorCodes.ERROR_IO:
+                        throw new IOException();
+                    case ErrorCodes.ERROR_INVALID_PARAM:
+                        return false;
+                    default:
+                        // Should not happen
+                        throw new IOException();
+                }
+           }
+           else {
+               throw new IOException("Tag is not ndef");
+           }
         } catch (RemoteException e) {
             Log.e(TAG, "NFC service dead", e);
             return false;
         }
     }
-
-    @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 0901607..e2fd034 100644
--- a/core/java/android/nfc/technology/NdefFormatable.java
+++ b/core/java/android/nfc/technology/NdefFormatable.java
@@ -91,11 +91,4 @@
             Log.e(TAG, "NFC service dead", e);
         }
     }
-
-    @Override
-    public byte[] transceive(byte[] data) {
-        checkConnected();
-
-        throw new UnsupportedOperationException();
-    }
 }
diff --git a/core/java/android/nfc/technology/NfcA.java b/core/java/android/nfc/technology/NfcA.java
index 20fe09e..0615a10 100644
--- a/core/java/android/nfc/technology/NfcA.java
+++ b/core/java/android/nfc/technology/NfcA.java
@@ -21,6 +21,8 @@
 import android.os.Bundle;
 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.
@@ -44,6 +46,7 @@
     private short mSak;
     private byte[] mAtqa;
 
+    /** @hide */
     public NfcA(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
         super(adapter, tag, TagTechnology.NFC_A);
         mSak = extras.getShort(EXTRA_SAK);
@@ -63,4 +66,19 @@
     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.
+     *
+     * @param data bytes to send
+     * @return bytes received in response
+     * @throws IOException if the target is lost or connection closed
+     */
+    public byte[] transceive(byte[] data) throws IOException {
+        return transceive(data, true);
+    }
 }
diff --git a/core/java/android/nfc/technology/NfcB.java b/core/java/android/nfc/technology/NfcB.java
index 767558e..c14b98d 100644
--- a/core/java/android/nfc/technology/NfcB.java
+++ b/core/java/android/nfc/technology/NfcB.java
@@ -21,6 +21,8 @@
 import android.os.Bundle;
 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.
@@ -44,6 +46,7 @@
     private byte[] mAppData;
     private byte[] mProtInfo;
 
+    /** @hide */
     public NfcB(NfcAdapter adapter, Tag tag, Bundle extras)
             throws RemoteException {
         super(adapter, tag, TagTechnology.NFC_B);
@@ -67,4 +70,18 @@
         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.
+     *
+     * @param data bytes to send
+     * @return bytes received in response
+     * @throws IOException if the target is lost or connection closed
+     */
+    public byte[] transceive(byte[] data) throws IOException {
+        return transceive(data, true);
+    }
 }
diff --git a/core/java/android/nfc/technology/NfcF.java b/core/java/android/nfc/technology/NfcF.java
index f7f1fd3..434e5df 100644
--- a/core/java/android/nfc/technology/NfcF.java
+++ b/core/java/android/nfc/technology/NfcF.java
@@ -21,6 +21,8 @@
 import android.os.Bundle;
 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.
@@ -44,6 +46,7 @@
     private byte[] mSystemCode = null;
     private byte[] mManufacturer = null;
 
+    /** @hide */
     public NfcF(NfcAdapter adapter, Tag tag, Bundle extras)
             throws RemoteException {
         super(adapter, tag, TagTechnology.NFC_F);
@@ -60,4 +63,19 @@
     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.
+     *
+     * @param data bytes to send
+     * @return bytes received in response
+     * @throws IOException if the target is lost or connection closed
+     */
+    public byte[] transceive(byte[] data) throws IOException {
+        return transceive(data, true);
+    }
 }
diff --git a/core/java/android/nfc/technology/NfcV.java b/core/java/android/nfc/technology/NfcV.java
index 4b51119..142ef9d 100644
--- a/core/java/android/nfc/technology/NfcV.java
+++ b/core/java/android/nfc/technology/NfcV.java
@@ -21,8 +21,10 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 
+import java.io.IOException;
+
 /**
- * A low-level connection to a {@link Tag} using the NFC-V technology, also known as
+ * A low-level connection to a {@link Tag} using NFC vicinity technology, also known as
  * ISO15693.
  *
  * <p>You can acquire this kind of connection with {@link NfcAdapter#getTechnology}.
@@ -45,6 +47,7 @@
     private byte mRespFlags;
     private byte mDsfId;
 
+    /** @hide */
     public NfcV(NfcAdapter adapter, Tag tag, Bundle extras)
             throws RemoteException {
         super(adapter, tag, TagTechnology.NFC_V);
@@ -59,4 +62,19 @@
     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.
+     *
+     * @param data bytes to send
+     * @return bytes received in response
+     * @throws IOException if the target is lost or connection closed
+     */
+    public byte[] transceive(byte[] data) throws IOException {
+        return transceive(data, true);
+    }
 }
diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java
index 62216c1..96f1724 100644
--- a/core/java/android/nfc/technology/TagTechnology.java
+++ b/core/java/android/nfc/technology/TagTechnology.java
@@ -22,47 +22,60 @@
 
 public interface TagTechnology {
     /**
-     * This object is an instance of {@link NfcA}
+     * This technology is an instance of {@link NfcA}.
+     * <p>Support for this technology type is mandatory.
      */
     public static final int NFC_A = 1;
 
     /**
-     * This object is an instance of {@link NfcB}
+     * This technology is an instance of {@link NfcB}.
+     * <p>Support for this technology type is mandatory.
      */
     public static final int NFC_B = 2;
 
     /**
-     * This object is an instance of {@link IsoDep}
+     * This technology is an instance of {@link IsoDep}.
+     * <p>Support for this technology type is mandatory.
      */
     public static final int ISO_DEP = 3;
 
     /**
-     * This object is an instance of {@link NfcF}
+     * This technology is an instance of {@link NfcF}.
+     * <p>Support for this technology type is mandatory.
      */
     public static final int NFC_F = 4;
 
     /**
-     * This object is an instance of {@link NfcV}
+     * This technology is an instance of {@link NfcV}.
+     * <p>Support for this technology type is mandatory.
      */
     public static final int NFC_V = 5;
 
     /**
-     * This object is an instance of {@link Ndef}
+     * This technology is an instance of {@link Ndef}.
+     * <p>Support for this technology type is mandatory.
      */
     public static final int NDEF = 6;
 
     /**
-     * This object is an instance of {@link NdefFormatable}
+     * This technology is an instance of {@link NdefFormatable}.
+     * <p>Support for this technology type is mandatory.
      */
     public static final int NDEF_FORMATABLE = 7;
 
     /**
-     * This object is an instance of {@link MifareClassic}
+     * This technology is an instance of {@link MifareClassic}.
+     * <p>Support for this technology type is optional. If a stack doesn't support this technology
+     * type tags using it must still be discovered and present the lower level radio interface
+     * technologies in use.
      */
     public static final int MIFARE_CLASSIC = 8;
 
     /**
-     * This object is an instance of {@link MifareUltralight}
+     * This technology is an instance of {@link MifareUltralight}.
+     * <p>Support for this technology type is optional. If a stack doesn't support this technology
+     * type tags using it must still be discovered and present the lower level radio interface
+     * technologies in use.
      */
     public static final int MIFARE_ULTRALIGHT = 9;
 
@@ -72,23 +85,51 @@
     public int getTechnologyId();
 
     /**
-     * Get the backing tag object.
+     * Get the {@link Tag} object this technology came from.
      */
     public Tag getTag();
 
     /**
-     * @throws IOException
+     * 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.
+     *
+     * <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.
+     *
+     * @see #reconnect()
+     * @see #close()
+     * @throws IOException if the target is lost, or connect canceled
      */
     public void connect() throws IOException;
 
     /**
+     * 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>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.
+     *
+     * @see #connect()
+     * @see #close()
      * @throws IOException
      */
     public void reconnect() throws IOException;
 
     /**
-     * Non-blocking. Immediately causes all blocking calls
-     * to throw 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.
+     *
+     * <p>
+     * Once this method is called, this object cannot be re-used and should be discarded. Further
+     * calls to {@link #connect} will fail.
+     *
+     * @see #connect()
+     * @see #reconnect()
      */
     public void close();
 }
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 642a563..33cd810 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -329,7 +329,14 @@
          from the touch driver. This code exists for one particular device,
          and should not be enabled for any others. -->
     <bool name="config_filterJumpyTouchEvents">false</bool>
-    
+
+    <!-- Specifies the amount of time to disable virtual keys after the screen is touched
+         in order to filter out accidental virtual key presses due to swiping gestures
+         or taps near the edge of the display.  May be 0 to disable the feature.
+         It is recommended that this value be no more than 250 ms.
+         This feature should be disabled for most devices. -->
+    <integer name="config_virtualKeyQuietTimeMillis">0</integer>
+
     <!-- Component name of the default wallpaper. This will be ImageWallpaper if not 
          specified -->
     <string name="default_wallpaper_component">@null</string>
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index c8a4593..d5f385b 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -47,7 +47,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Arrays;
 
 public class PackageManagerTests extends AndroidTestCase {
     private static final boolean localLOGV = true;
@@ -2839,164 +2838,6 @@
         installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
                 fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
     }
-
-    @LargeTest
-    public void testPackageObbPaths_Nonexistent() {
-        try {
-            final PackageManager pm = getPm();
-
-            // Invalid Java package name.
-            pm.getPackageObbPaths("=non-existent");
-
-            fail("Should not be able to get package OBB paths for non-existent package");
-        } catch (IllegalArgumentException e) {
-            // pass
-        }
-    }
-
-    @LargeTest
-    public void testPackageObbPaths_Initial() {
-        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
-
-        try {
-            final PackageManager pm = getPm();
-
-            assertEquals("Initial obb paths should be null",
-                    null, pm.getPackageObbPaths(ip.pkg.packageName));
-        } finally {
-            cleanUpInstall(ip);
-        }
-    }
-
-    @LargeTest
-    public void testPackageObbPaths_Null() {
-        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
-
-        try {
-            final PackageManager pm = getPm();
-
-            pm.setPackageObbPaths(ip.pkg.packageName, null);
-
-            assertEquals("Returned paths should be null",
-                    null, pm.getPackageObbPaths(ip.pkg.packageName));
-        } finally {
-            cleanUpInstall(ip);
-        }
-    }
-
-    @LargeTest
-    public void testPackageObbPaths_Empty() {
-        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
-
-        try {
-            final PackageManager pm = getPm();
-
-            final String[] paths = new String[0];
-
-            pm.setPackageObbPaths(ip.pkg.packageName, paths);
-
-            assertEquals("Empty list should be interpreted as null",
-                    null, pm.getPackageObbPaths(ip.pkg.packageName));
-        } finally {
-            cleanUpInstall(ip);
-        }
-    }
-
-    @LargeTest
-    public void testPackageObbPaths_Single() {
-        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
-
-        try {
-            final PackageManager pm = getPm();
-
-            final String[] paths = new String[] {
-                "/example/test",
-            };
-
-            pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
-
-            assertTrue("Previously set paths should be the same as the returned paths.",
-                    Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
-        } finally {
-            cleanUpInstall(ip);
-        }
-    }
-
-    @LargeTest
-    public void testPackageObbPaths_Multiple() {
-        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
-
-        try {
-            final PackageManager pm = getPm();
-
-            final String[] paths = new String[] {
-                    "/example/test1",
-                    "/example/test2",
-            };
-
-            pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
-
-            assertTrue("Previously set paths should be the same as the returned paths.",
-                    Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
-        } finally {
-            cleanUpInstall(ip);
-        }
-    }
-
-    @LargeTest
-    public void testPackageObbPaths_Twice() {
-        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
-
-        try {
-            final PackageManager pm = getPm();
-
-            final String[] paths = new String[] {
-                    "/example/test1",
-                    "/example/test2",
-            };
-
-            pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
-
-            assertTrue("Previously set paths should be the same as the returned paths.",
-                    Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
-
-            paths[0] = "/example/test3";
-            pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
-
-            assertTrue("Previously set paths should be the same as the returned paths.",
-                    Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
-        } finally {
-            cleanUpInstall(ip);
-        }
-    }
-
-    @LargeTest
-    public void testPackageObbPaths_ReplacePackage() {
-        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, false);
-
-        try {
-            final PackageManager pm = getPm();
-
-            final String[] paths = new String[] {
-                    "/example/test1",
-                    "/example/test2",
-            };
-
-            pm.setPackageObbPaths(ip.pkg.packageName, paths.clone());
-
-            Log.i(TAG, "Creating replaceReceiver");
-            final GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
-
-            final int flags = PackageManager.INSTALL_REPLACE_EXISTING;
-            invokeInstallPackage(ip.packageURI, flags, receiver);
-            assertInstall(ip.pkg, flags, ip.pkg.installLocation);
-
-            assertTrue("Previously set paths should be the same as the returned paths.",
-                    Arrays.equals(paths, pm.getPackageObbPaths(ip.pkg.packageName)));
-        } finally {
-            cleanUpInstall(ip);
-        }
-    }
     /*---------- Recommended install location tests ----*/
     /*
      * TODO's
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index 49351b0..7568ba7 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -103,6 +103,12 @@
      */
     virtual bool filterJumpyTouchEvents() = 0;
 
+    /* Gets the amount of time to disable virtual keys after the screen is touched
+     * in order to filter out accidental virtual key presses due to swiping gestures
+     * or taps near the edge of the display.  May be 0 to disable the feature.
+     */
+    virtual nsecs_t getVirtualKeyQuietTime() = 0;
+
     /* Gets the configured virtual key definitions for an input device. */
     virtual void getVirtualKeyDefinitions(const String8& deviceName,
             Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0;
@@ -177,6 +183,10 @@
     virtual void updateGlobalMetaState() = 0;
     virtual int32_t getGlobalMetaState() = 0;
 
+    virtual void disableVirtualKeysUntil(nsecs_t time) = 0;
+    virtual bool shouldDropVirtualKey(nsecs_t now,
+            InputDevice* device, int32_t keyCode, int32_t scanCode) = 0;
+
     virtual InputReaderPolicyInterface* getPolicy() = 0;
     virtual InputDispatcherInterface* getDispatcher() = 0;
     virtual EventHubInterface* getEventHub() = 0;
@@ -264,6 +274,11 @@
     InputConfiguration mInputConfiguration;
     void updateInputConfiguration();
 
+    nsecs_t mDisableVirtualKeysTimeout;
+    virtual void disableVirtualKeysUntil(nsecs_t time);
+    virtual bool shouldDropVirtualKey(nsecs_t now,
+            InputDevice* device, int32_t keyCode, int32_t scanCode);
+
     // state queries
     typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
     int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
@@ -585,6 +600,7 @@
         bool useBadTouchFilter;
         bool useJumpyTouchFilter;
         bool useAveragingTouchFilter;
+        nsecs_t virtualKeyQuietTime;
     } mParameters;
 
     // Immutable calibration parameters in parsed form.
@@ -810,6 +826,7 @@
     void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
             BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
             int32_t motionEventAction);
+    void detectGestures(nsecs_t when);
 
     bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
     const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index 969ee79..a2a5455 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -247,13 +247,13 @@
             int32_t mode = data.readInt32();
             status_t res = turnElectronBeamOff(mode);
             reply->writeInt32(res);
-        }
+        } break;
         case TURN_ELECTRON_BEAM_ON: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             int32_t mode = data.readInt32();
             status_t res = turnElectronBeamOn(mode);
             reply->writeInt32(res);
-        }
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 3197ab2..83b382b 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -198,7 +198,7 @@
         const sp<InputReaderPolicyInterface>& policy,
         const sp<InputDispatcherInterface>& dispatcher) :
         mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
-        mGlobalMetaState(0) {
+        mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) {
     configureExcludedDevices();
     updateGlobalMetaState();
     updateInputConfiguration();
@@ -453,6 +453,24 @@
     } // release state lock
 }
 
+void InputReader::disableVirtualKeysUntil(nsecs_t time) {
+    mDisableVirtualKeysTimeout = time;
+}
+
+bool InputReader::shouldDropVirtualKey(nsecs_t now,
+        InputDevice* device, int32_t keyCode, int32_t scanCode) {
+    if (now < mDisableVirtualKeysTimeout) {
+        LOGI("Dropping virtual key from device %s because virtual keys are "
+                "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
+                device->getName().string(),
+                (mDisableVirtualKeysTimeout - now) * 0.000001,
+                keyCode, scanCode);
+        return true;
+    } else {
+        return false;
+    }
+}
+
 void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
     { // acquire state lock
         AutoMutex _l(mStateLock);
@@ -937,6 +955,11 @@
                 keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
             } else {
                 // key down
+                if ((policyFlags & POLICY_FLAG_VIRTUAL)
+                        && mContext->shouldDropVirtualKey(when, getDevice(), keyCode, scanCode)) {
+                    return;
+                }
+
                 mLocked.keyDowns.push();
                 KeyDown& keyDown = mLocked.keyDowns.editTop();
                 keyDown.keyCode = keyCode;
@@ -1340,6 +1363,7 @@
     mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
     mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
     mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+    mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime();
 }
 
 void TouchInputMapper::dumpParameters(String8& dump) {
@@ -2060,6 +2084,7 @@
 
     TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
     if (touchResult == DISPATCH_TOUCH) {
+        detectGestures(when);
         dispatchTouches(when, policyFlags);
     }
 
@@ -2145,6 +2170,11 @@
                     if (mCurrentTouch.pointerCount == 1) {
                         const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
                         if (virtualKey) {
+                            if (mContext->shouldDropVirtualKey(when, getDevice(),
+                                    virtualKey->keyCode, virtualKey->scanCode)) {
+                                return DROP_STROKE;
+                            }
+
                             mLocked.currentVirtualKey.down = true;
                             mLocked.currentVirtualKey.downTime = when;
                             mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
@@ -2182,6 +2212,26 @@
     return touchResult;
 }
 
+void TouchInputMapper::detectGestures(nsecs_t when) {
+    // Disable all virtual key touches that happen within a short time interval of the
+    // most recent touch.  The idea is to filter out stray virtual key presses when
+    // interacting with the touch screen.
+    //
+    // Problems we're trying to solve:
+    //
+    // 1. While scrolling a list or dragging the window shade, the user swipes down into a
+    //    virtual key area that is implemented by a separate touch panel and accidentally
+    //    triggers a virtual key.
+    //
+    // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
+    //    area and accidentally triggers a virtual key.  This often happens when virtual keys
+    //    are layed out below the screen near to where the on screen keyboard's space bar
+    //    is displayed.
+    if (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
+        mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime);
+    }
+}
+
 void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
     uint32_t currentPointerCount = mCurrentTouch.pointerCount;
     uint32_t lastPointerCount = mLastTouch.pointerCount;
diff --git a/libs/ui/tests/InputReader_test.cpp b/libs/ui/tests/InputReader_test.cpp
index de4b05a..f31a6be 100644
--- a/libs/ui/tests/InputReader_test.cpp
+++ b/libs/ui/tests/InputReader_test.cpp
@@ -131,6 +131,10 @@
         return mFilterJumpyTouchEvents;
     }
 
+    virtual nsecs_t getVirtualKeyQuietTime() {
+        return 0;
+    }
+
     virtual void getVirtualKeyDefinitions(const String8& deviceName,
             Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
         ssize_t index = mVirtualKeyDefinitions.indexOfKey(deviceName);
@@ -631,6 +635,14 @@
     virtual InputDispatcherInterface* getDispatcher() {
         return mDispatcher.get();
     }
+
+    virtual void disableVirtualKeysUntil(nsecs_t time) {
+    }
+
+    virtual bool shouldDropVirtualKey(nsecs_t now,
+            InputDevice* device, int32_t keyCode, int32_t scanCode) {
+        return false;
+    }
 };
 
 
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index ccc6a34..7194614 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -25,13 +25,14 @@
 #include <arpa/inet.h>
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/foundation/ADebug.h>
 
 namespace android {
 
@@ -47,6 +48,82 @@
     disconnect();
 }
 
+static bool MakeSocketBlocking(int s, bool blocking) {
+    // Make socket non-blocking.
+    int flags = fcntl(s, F_GETFL, 0);
+    if (flags == -1) {
+        return false;
+    }
+
+    if (blocking) {
+        flags &= ~O_NONBLOCK;
+    } else {
+        flags |= O_NONBLOCK;
+    }
+
+    return fcntl(s, F_SETFL, flags) != -1;
+}
+
+static status_t MyConnect(
+        int s, const struct sockaddr *addr, socklen_t addrlen) {
+    status_t result = UNKNOWN_ERROR;
+
+    MakeSocketBlocking(s, false);
+
+    if (connect(s, addr, addrlen) == 0) {
+        result = OK;
+    } else if (errno != EINPROGRESS) {
+        result = -errno;
+    } else {
+        for (;;) {
+            fd_set rs, ws;
+            FD_ZERO(&rs);
+            FD_ZERO(&ws);
+            FD_SET(s, &rs);
+            FD_SET(s, &ws);
+
+            struct timeval tv;
+            tv.tv_sec = 0;
+            tv.tv_usec = 100000ll;
+
+            int nfds = ::select(s + 1, &rs, &ws, NULL, &tv);
+
+            if (nfds < 0) {
+                if (errno == EINTR) {
+                    continue;
+                }
+
+                result = -errno;
+                break;
+            }
+
+            if (FD_ISSET(s, &ws) && !FD_ISSET(s, &rs)) {
+                result = OK;
+                break;
+            }
+
+            if (FD_ISSET(s, &rs) || FD_ISSET(s, &ws)) {
+                // Get the pending error.
+                int error = 0;
+                socklen_t errorLen = sizeof(error);
+                if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &errorLen) == -1) {
+                    // Couldn't get the real error, so report why not.
+                    result = -errno;
+                } else {
+                    result = -error;
+                }
+                break;
+            }
+
+            // Timeout expired. Try again.
+        }
+    }
+
+    MakeSocketBlocking(s, true);
+
+    return result;
+}
+
 status_t HTTPStream::connect(const char *server, int port) {
     Mutex::Autolock autoLock(mLock);
 
@@ -82,7 +159,7 @@
     addr.sin_addr.s_addr = *(in_addr_t *)ent->h_addr;
     memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
 
-    int res = ::connect(s, (const struct sockaddr *)&addr, sizeof(addr));
+    status_t res = MyConnect(s, (const struct sockaddr *)&addr, sizeof(addr));
 
     mLock.lock();
 
@@ -90,12 +167,12 @@
         return UNKNOWN_ERROR;
     }
 
-    if (res < 0) {
+    if (res != OK) {
         close(mSocket);
         mSocket = -1;
 
         mState = READY;
-        return UNKNOWN_ERROR;
+        return res;
     }
 
     mState = CONNECTED;
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 52e04d7..41f9108 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -70,6 +70,9 @@
     <string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string>
     <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
 
+    <!-- Notifications use ringer volume -->
+    <bool name="def_notifications_use_ring_volume">true</bool>
+
     <!-- Default for Settings.System.VIBRATE_IN_SILENT -->
     <bool name="def_vibrate_in_silent">true</bool>
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index ad04bb4..f7ec294 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -1068,6 +1068,11 @@
     
             loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
                     R.bool.def_vibrate_in_silent);
+
+            // Set notification volume to follow ringer volume by default
+            loadBooleanSetting(stmt, Settings.System.NOTIFICATIONS_USE_RING_VOLUME,
+                    R.bool.def_notifications_use_ring_volume);
+
         } finally {
             if (stmt != null) stmt.close();
         }
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index b44fe00..ba39c57 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -411,7 +411,13 @@
             return mContext.getResources().getBoolean(
                     com.android.internal.R.bool.config_filterJumpyTouchEvents);
         }
-        
+
+        @SuppressWarnings("unused")
+        public int getVirtualKeyQuietTimeMillis() {
+            return mContext.getResources().getInteger(
+                    com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
+        }
+
         @SuppressWarnings("unused")
         public VirtualKeyDefinition[] getVirtualKeyDefinitions(String deviceName) {
             ArrayList<VirtualKeyDefinition> keys = new ArrayList<VirtualKeyDefinition>();
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index 7b68d68..cf87a9d 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -132,11 +132,12 @@
                                     Slog.e(TAG, String.format(
                                             "Error handling '%s'", event), ex);
                                 }
-                            }
-                            try {
-                                mResponseQueue.put(event);
-                            } catch (InterruptedException ex) {
-                                Slog.e(TAG, "Failed to put response onto queue", ex);
+                            } else {
+                                try {
+                                    mResponseQueue.put(event);
+                                } catch (InterruptedException ex) {
+                                    Slog.e(TAG, "Failed to put response onto queue", ex);
+                                }
                             }
                         } catch (NumberFormatException nfe) {
                             Slog.w(TAG, String.format("Bad msg (%s)", event));
@@ -219,6 +220,7 @@
      */
     public synchronized ArrayList<String> doCommand(String cmd)
             throws NativeDaemonConnectorException  {
+        mResponseQueue.clear();
         sendCommand(cmd);
 
         ArrayList<String> response = new ArrayList<String>();
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 39c7540..9b8a605 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -102,7 +102,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
-import java.lang.reflect.Array;
 import java.security.NoSuchAlgorithmException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -4396,8 +4395,6 @@
         }
     };
 
-    private static final boolean DEBUG_OBB = false;
-
     private static final void sendPackageBroadcast(String action, String pkg,
             Bundle extras, IIntentReceiver finishedReceiver) {
         IActivityManager am = ActivityManagerNative.getDefault();
@@ -4573,64 +4570,6 @@
         mHandler.sendMessage(msg);
     }
 
-    public void setPackageObbPaths(String packageName, String[] paths) {
-        if (DEBUG_OBB)
-            Log.v(TAG, "Setting .obb paths for " + packageName + " to: " + Arrays.toString(paths));
-        final int uid = Binder.getCallingUid();
-        final int permission = mContext.checkCallingPermission(
-                android.Manifest.permission.INSTALL_PACKAGES);
-        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
-        if (!allowedByPermission) {
-            throw new SecurityException("Permission denial: attempt to set .obb file from pid="
-                    + Binder.getCallingPid());
-        }
-        synchronized (mPackages) {
-            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
-            if (pkgSetting == null) {
-                throw new IllegalArgumentException("Unknown package: " + packageName);
-            }
-
-            if (paths != null) {
-                if (paths.length == 0) {
-                    // Don't bother storing an empty array.
-                    paths = null;
-                } else {
-                    // Don't allow the caller to manipulate our copy of the
-                    // list.
-                    paths = paths.clone();
-                }
-            }
-
-            // Only write settings file if the new and old settings are not the
-            // same.
-            if (!Arrays.equals(paths, pkgSetting.obbPathStrings)) {
-                pkgSetting.obbPathStrings = paths;
-                mSettings.writeLP();
-            }
-        }
-    }
-
-    public String[] getPackageObbPaths(String packageName) {
-        if (DEBUG_OBB)
-            Log.v(TAG, "Getting .obb paths for " + packageName);
-        final int uid = Binder.getCallingUid();
-        final int permission = mContext.checkCallingPermission(
-                android.Manifest.permission.INSTALL_PACKAGES);
-        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
-        synchronized (mPackages) {
-            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
-            if (pkgSetting == null) {
-                throw new IllegalArgumentException("Unknown package: " + packageName);
-            }
-            if (!allowedByPermission && (uid != pkgSetting.userId)) {
-                throw new SecurityException("Permission denial: attempt to set .obb file from pid="
-                        + Binder.getCallingPid() + ", uid=" + uid + ", package uid="
-                        + pkgSetting.userId);
-            }
-            return pkgSetting.obbPathStrings;
-        }
-    }
-
     private void processPendingInstall(final InstallArgs args, final int currentStatus) {
         // Queue up an async operation since the package installation may take a little while.
         mHandler.post(new Runnable() {
@@ -7200,7 +7139,6 @@
                     pw.print("    codePath="); pw.println(ps.codePathString);
                     pw.print("    resourcePath="); pw.println(ps.resourcePathString);
                     pw.print("    nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
-                    pw.print("    obbPaths="); pw.println(Arrays.toString(ps.obbPathStrings));
                     pw.print("    versionCode="); pw.println(ps.versionCode);
                     if (ps.pkg != null) {
                         pw.print("    versionName="); pw.println(ps.pkg.mVersionName);
@@ -7778,7 +7716,6 @@
         File resourcePath;
         String resourcePathString;
         String nativeLibraryPathString;
-        String[] obbPathStrings;
         long timeStamp;
         long firstInstallTime;
         long lastUpdateTime;
@@ -7824,11 +7761,6 @@
             resourcePath = base.resourcePath;
             resourcePathString = base.resourcePathString;
             nativeLibraryPathString = base.nativeLibraryPathString;
-
-            if (base.obbPathStrings != null) {
-                obbPathStrings = base.obbPathStrings.clone();
-            }
-
             timeStamp = base.timeStamp;
             firstInstallTime = base.firstInstallTime;
             lastUpdateTime = base.lastUpdateTime;
@@ -8887,16 +8819,6 @@
             if (pkg.installerPackageName != null) {
                 serializer.attribute(null, "installer", pkg.installerPackageName);
             }
-            if (pkg.obbPathStrings != null && pkg.obbPathStrings.length > 0) {
-                int N = pkg.obbPathStrings.length;
-                serializer.startTag(null, "obbs");
-                for (int i = 0; i < N; i++) {
-                    serializer.startTag(null, "obb");
-                    serializer.attribute(null, "path", pkg.obbPathStrings[i]);
-                    serializer.endTag(null, "obb");
-                }
-                serializer.endTag(null, "obbs");
-            }
             pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
             if ((pkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
                 serializer.startTag(null, "perms");
@@ -9489,8 +9411,6 @@
                         readGrantedPermissionsLP(parser,
                                 packageSetting.grantedPermissions);
                         packageSetting.permissionsFixed = true;
-                    } else if (tagName.equals("obbs")) {
-                        readObbPathsLP(packageSetting, parser);
                     } else {
                         reportSettingsProblem(Log.WARN,
                                 "Unknown element under <package>: "
@@ -9695,34 +9615,6 @@
             }
         }
 
-        private void readObbPathsLP(PackageSettingBase packageSetting, XmlPullParser parser)
-                throws XmlPullParserException, IOException {
-            final List<String> obbPaths = new ArrayList<String>();
-            final int outerDepth = parser.getDepth();
-            int type;
-            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
-                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
-                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
-                    continue;
-                }
-
-                final String tagName = parser.getName();
-                if (tagName.equals("obb")) {
-                    final String path = parser.getAttributeValue(null, "path");
-                    obbPaths.add(path);
-                } else {
-                    reportSettingsProblem(Log.WARN, "Unknown element under <obbs>: "
-                            + parser.getName());
-                }
-                XmlUtils.skipCurrentTag(parser);
-            }
-            if (obbPaths.size() == 0) {
-                return;
-            } else {
-                packageSetting.obbPathStrings = obbPaths.toArray(new String[obbPaths.size()]);
-            }
-        }
-
         // Returns -1 if we could not find an available UserId to assign
         private int newUserIdLP(Object obj) {
             // Let's be stupidly inefficient for now...
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index 1b885f5..2a25c2a 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -425,7 +425,7 @@
             // First collect stack traces from all threads of the system process.
             // Then kill this process so that the system will restart.
 
-            String name = (mCurrentMonitor != null) ?
+            final String name = (mCurrentMonitor != null) ?
                     mCurrentMonitor.getClass().getName() : "null";
             EventLog.writeEvent(EventLogTags.WATCHDOG, name);
 
@@ -434,7 +434,8 @@
             if (mPhonePid > 0) pids.add(mPhonePid);
             // Pass !waitedHalf so that just in case we somehow wind up here without having
             // dumped the halfway stacks, we properly re-initialize the trace file.
-            File stack = ActivityManagerService.dumpStackTraces(!waitedHalf, pids, null, null);
+            final File stack = ActivityManagerService.dumpStackTraces(
+                    !waitedHalf, pids, null, null);
 
             // Give some extra time to make sure the stack traces get written.
             // The system's been hanging for a minute, another second or two won't hurt much.
@@ -445,7 +446,19 @@
                 dumpKernelStackTraces();
             }
 
-            mActivity.addErrorToDropBox("watchdog", null, null, null, name, null, stack, null);
+            // Try to add the error to the dropbox, but assuming that the ActivityManager
+            // itself may be deadlocked.  (which has happened, causing this statement to
+            // deadlock and the watchdog as a whole to be ineffective)
+            Thread dropboxThread = new Thread("watchdogWriteToDropbox") {
+                    public void run() {
+                        mActivity.addErrorToDropBox(
+                                "watchdog", null, null, null, name, null, stack, null);
+                    }
+                };
+            dropboxThread.start();
+            try {
+                dropboxThread.join(2000);  // wait up to 2 seconds for it to return.
+            } catch (InterruptedException ignored) {}
 
             // Only kill the process if the debugger is not attached.
             if (!Debug.isDebuggerConnected()) {
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 693d630..171471e 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -55,6 +55,7 @@
     jmethodID checkInjectEventsPermission;
     jmethodID filterTouchEvents;
     jmethodID filterJumpyTouchEvents;
+    jmethodID getVirtualKeyQuietTimeMillis;
     jmethodID getVirtualKeyDefinitions;
     jmethodID getInputDeviceCalibration;
     jmethodID getExcludedDeviceNames;
@@ -183,6 +184,7 @@
             int32_t* width, int32_t* height, int32_t* orientation);
     virtual bool filterTouchEvents();
     virtual bool filterJumpyTouchEvents();
+    virtual nsecs_t getVirtualKeyQuietTime();
     virtual void getVirtualKeyDefinitions(const String8& deviceName,
             Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
     virtual void getInputDeviceCalibration(const String8& deviceName,
@@ -233,6 +235,7 @@
     // Cached filtering policies.
     int32_t mFilterTouchEvents;
     int32_t mFilterJumpyTouchEvents;
+    nsecs_t mVirtualKeyQuietTime;
 
     // Cached throttling policy.
     int32_t mMaxEventsPerSecond;
@@ -264,7 +267,7 @@
 // ----------------------------------------------------------------------------
 
 NativeInputManager::NativeInputManager(jobject callbacksObj) :
-    mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
+    mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
     mMaxEventsPerSecond(-1),
     mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(ROTATION_0) {
     JNIEnv* env = jniEnv();
@@ -451,6 +454,24 @@
     return mFilterJumpyTouchEvents;
 }
 
+nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
+    if (mVirtualKeyQuietTime < 0) {
+        JNIEnv* env = jniEnv();
+
+        jint result = env->CallIntMethod(mCallbacksObj,
+                gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
+        if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
+            result = 0;
+        }
+        if (result < 0) {
+            result = 0;
+        }
+
+        mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
+    }
+    return mVirtualKeyQuietTime;
+}
+
 void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
         Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
     outVirtualKeyDefinitions.clear();
@@ -1351,6 +1372,9 @@
     GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
             "filterJumpyTouchEvents", "()Z");
 
+    GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
+            "getVirtualKeyQuietTimeMillis", "()I");
+
     GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyDefinitions, gCallbacksClassInfo.clazz,
             "getVirtualKeyDefinitions",
             "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 4a18b3e..c5d45f5 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -489,18 +489,4 @@
     public boolean isSafeMode() {
         throw new UnsupportedOperationException();
     }
-
-    public void setPackageObbPath(String packageName, String path) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setPackageObbPaths(String packageName, String[] paths) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String[] getPackageObbPaths(String packageName) {
-        throw new UnsupportedOperationException();
-    }
 }