Merge "implement [2396050] Add ETC1 texture support to AGL"
diff --git a/api/current.xml b/api/current.xml
index 65aa5b6..9610f7b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -80924,6 +80924,17 @@
  visibility="public"
 >
 </field>
+<field name="TAG_GPS_DATESTAMP"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;GPSDateStamp&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TAG_GPS_LATITUDE"
  type="java.lang.String"
  transient="false"
@@ -80968,6 +80979,17 @@
  visibility="public"
 >
 </field>
+<field name="TAG_GPS_TIMESTAMP"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;GPSTimeStamp&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TAG_IMAGE_LENGTH"
  type="java.lang.String"
  transient="false"
@@ -110028,6 +110050,17 @@
  visibility="public"
 >
 </field>
+<field name="FROYO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="Bundle"
  extends="java.lang.Object"
@@ -117394,123 +117427,6 @@
 </parameter>
 </method>
 </class>
-<interface name="StorageEventListener"
- abstract="true"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="onMediaInserted"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="label" type="java.lang.String">
-</parameter>
-<parameter name="path" type="java.lang.String">
-</parameter>
-<parameter name="major" type="int">
-</parameter>
-<parameter name="minor" type="int">
-</parameter>
-</method>
-<method name="onMediaRemoved"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="label" type="java.lang.String">
-</parameter>
-<parameter name="path" type="java.lang.String">
-</parameter>
-<parameter name="major" type="int">
-</parameter>
-<parameter name="minor" type="int">
-</parameter>
-<parameter name="clean" type="boolean">
-</parameter>
-</method>
-<method name="onShareAvailabilityChanged"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="method" type="java.lang.String">
-</parameter>
-<parameter name="available" type="boolean">
-</parameter>
-</method>
-<method name="onVolumeStateChanged"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="label" type="java.lang.String">
-</parameter>
-<parameter name="path" type="java.lang.String">
-</parameter>
-<parameter name="oldState" type="java.lang.String">
-</parameter>
-<parameter name="newState" type="java.lang.String">
-</parameter>
-</method>
-</interface>
-<class name="StorageManager"
- extends="java.lang.Object"
- abstract="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<method name="registerListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.os.StorageEventListener">
-</parameter>
-</method>
-<method name="unregisterListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.os.StorageEventListener">
-</parameter>
-</method>
-</class>
 <class name="SystemClock"
  extends="java.lang.Object"
  abstract="false"
@@ -136182,6 +136098,126 @@
 </method>
 </interface>
 </package>
+<package name="android.storage"
+>
+<interface name="StorageEventListener"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onMediaInserted"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="label" type="java.lang.String">
+</parameter>
+<parameter name="path" type="java.lang.String">
+</parameter>
+<parameter name="major" type="int">
+</parameter>
+<parameter name="minor" type="int">
+</parameter>
+</method>
+<method name="onMediaRemoved"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="label" type="java.lang.String">
+</parameter>
+<parameter name="path" type="java.lang.String">
+</parameter>
+<parameter name="major" type="int">
+</parameter>
+<parameter name="minor" type="int">
+</parameter>
+<parameter name="clean" type="boolean">
+</parameter>
+</method>
+<method name="onShareAvailabilityChanged"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="method" type="java.lang.String">
+</parameter>
+<parameter name="available" type="boolean">
+</parameter>
+</method>
+<method name="onVolumeStateChanged"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="label" type="java.lang.String">
+</parameter>
+<parameter name="path" type="java.lang.String">
+</parameter>
+<parameter name="oldState" type="java.lang.String">
+</parameter>
+<parameter name="newState" type="java.lang.String">
+</parameter>
+</method>
+</interface>
+<class name="StorageManager"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="registerListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.storage.StorageEventListener">
+</parameter>
+</method>
+<method name="unregisterListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.storage.StorageEventListener">
+</parameter>
+</method>
+</class>
+</package>
 <package name="android.telephony"
 >
 <class name="CellLocation"
@@ -163137,6 +163173,22 @@
 <parameter name="handler" type="android.os.Handler">
 </parameter>
 </constructor>
+<constructor name="GestureDetector"
+ type="android.view.GestureDetector"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="listener" type="android.view.GestureDetector.OnGestureListener">
+</parameter>
+<parameter name="handler" type="android.os.Handler">
+</parameter>
+<parameter name="ignoreMultitouch" type="boolean">
+</parameter>
+</constructor>
 <method name="isLongpressEnabled"
  return="boolean"
  abstract="false"
@@ -168511,6 +168563,233 @@
 >
 </field>
 </class>
+<class name="ScaleGestureDetector"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="ScaleGestureDetector"
+ type="android.view.ScaleGestureDetector"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="listener" type="android.view.ScaleGestureDetector.OnScaleGestureListener">
+</parameter>
+</constructor>
+<method name="getCurrentSpan"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEventTime"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFocusX"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getFocusY"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getPreviousSpan"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getScaleFactor"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTimeDelta"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isInProgress"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onTouchEvent"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+</class>
+<interface name="ScaleGestureDetector.OnScaleGestureListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onScale"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detector" type="android.view.ScaleGestureDetector">
+</parameter>
+</method>
+<method name="onScaleBegin"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detector" type="android.view.ScaleGestureDetector">
+</parameter>
+</method>
+<method name="onScaleEnd"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detector" type="android.view.ScaleGestureDetector">
+</parameter>
+</method>
+</interface>
+<class name="ScaleGestureDetector.SimpleOnScaleGestureListener"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.view.ScaleGestureDetector.OnScaleGestureListener">
+</implements>
+<constructor name="ScaleGestureDetector.SimpleOnScaleGestureListener"
+ type="android.view.ScaleGestureDetector.SimpleOnScaleGestureListener"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="onScale"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detector" type="android.view.ScaleGestureDetector">
+</parameter>
+</method>
+<method name="onScaleBegin"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detector" type="android.view.ScaleGestureDetector">
+</parameter>
+</method>
+<method name="onScaleEnd"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detector" type="android.view.ScaleGestureDetector">
+</parameter>
+</method>
+</class>
 <class name="SoundEffectConstants"
  extends="java.lang.Object"
  abstract="false"
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 88a2b48..7455bac 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -81,10 +81,10 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.StorageManager;
 import android.os.StatFs;
 import android.os.Vibrator;
 import android.os.FileUtils.FileStatus;
+import android.storage.StorageManager;
 import android.telephony.TelephonyManager;
 import android.text.ClipboardManager;
 import android.util.AndroidRuntimeException;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index dae8e37..5aefe4c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1110,7 +1110,7 @@
      * @see #SENSOR_SERVICE
      * @see android.hardware.SensorManager
      * @see #STORAGE_SERVICE
-     * @see android.os.StorageManager
+     * @see android.storage.StorageManager
      * @see #VIBRATOR_SERVICE
      * @see android.os.Vibrator
      * @see #CONNECTIVITY_SERVICE
@@ -1243,11 +1243,11 @@
     
     /**
      * Use with {@link #getSystemService} to retrieve a {@link
-     * android.os.StorageManager} for accesssing system storage
+     * android.storage.StorageManager} for accesssing system storage
      * functions.
      *
      * @see #getSystemService
-     * @see android.os.StorageManager
+     * @see android.storage.StorageManager
      */
     public static final String STORAGE_SERVICE = "storage";
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 1e45f17..745628a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -615,13 +615,13 @@
     /**
      * Determines best place to install an application: either SD or internal FLASH.
      * Tweak the algorithm for best results.
-     * @param appInfo ApplicationInfo object og the package to install.
+     * @param appInfo ApplicationInfo object of the package to install.
      * Call utility method to obtain.
      * @param packageURI URI identifying the package's APK file.
-     * @return <code>INSTALL_ON_INTERNAL_FLASH</code> if it is best to install package on internal
-     * storage, <code>INSTALL_ON_SDCARD</code> if it is best to install package on SD card,
-     * and <code>INSTALL_FAILED_INSUFFICIENT_STORAGE</code> if insufficient space to safely install
-     * the application. <code>INSTALL_PARSE_FAILED_NOT_APK</code> Is returned if any input
+     * @return {@link INSTALL_ON_INTERNAL_FLASH} if it is best to install package on internal
+     * storage, {@link INSTALL_ON_SDCARD} if it is best to install package on SD card,
+     * and {@link INSTALL_FAILED_INSUFFICIENT_STORAGE} if insufficient space to safely install
+     * the application. {@link INSTALL_PARSE_FAILED_NOT_APK} Is returned if any input
      * parameter is <code>null</code>.
      * This recommendation does take into account the package's own flags.
      * @hide
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index fcd8f38..4c46b1d 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -178,6 +178,8 @@
          * January 2010: Android 2.1
          */
         public static final int ECLAIR_MR1 = 7;
+        
+        public static final int FROYO = 8;
     }
     
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/speech/RecognizerIntent.java b/core/java/android/speech/RecognizerIntent.java
index 49991bd..334b049 100644
--- a/core/java/android/speech/RecognizerIntent.java
+++ b/core/java/android/speech/RecognizerIntent.java
@@ -30,8 +30,14 @@
 
     /**
      * Starts an activity that will prompt the user for speech and sends it through a
-     * speech recognizer.  The results will be returned via activity results, or forwarded
-     * via a PendingIntent if one is provided.
+     * speech recognizer.  The results will be returned via activity results (in
+     * {@link Activity#onActivityResult}, if you start the intent using
+     * {@link Activity#startActivityForResult(Intent, int)}), or forwarded via a PendingIntent
+     * if one is provided.
+     * 
+     * <p>Starting this intent with just {@link Activity#startActivity(Intent)} is not supported.
+     * You must either use {@link Activity#startActivityForResult(Intent, int)}, or provide a
+     * PendingIntent, to receive recognition results.
      * 
      * <p>Required extras:
      * <ul>
@@ -47,7 +53,7 @@
      *   <li>{@link #EXTRA_RESULTS_PENDINGINTENT_BUNDLE}
      * </ul>
      * 
-     * <p> Result extras:
+     * <p> Result extras (returned in the result, not to be specified in the request):
      * <ul>
      *   <li>{@link #EXTRA_RESULTS}
      * </ul>
@@ -73,7 +79,7 @@
      *   <li>{@link #EXTRA_MAX_RESULTS}
      * </ul>
      * 
-     * <p> Result extras:
+     * <p> Result extras (returned in the result, not to be specified in the request):
      * <ul>
      *   <li>{@link #EXTRA_RESULTS}
      * </ul>
@@ -167,6 +173,7 @@
      */
     public static final String EXTRA_RESULTS_PENDINGINTENT = 
             "android.speech.extra.RESULTS_PENDINGINTENT";
+    
     /**
      * If you use {@link #EXTRA_RESULTS_PENDINGINTENT} to supply a forwarding intent, you can
      * also use this extra to supply additional extras for the final intent.  The search results
@@ -187,8 +194,10 @@
     public static final int RESULT_AUDIO_ERROR = Activity.RESULT_FIRST_USER + 4;
 
     /**
-     * An ArrayList<String> of the potential results when performing
-     * {@link #ACTION_RECOGNIZE_SPEECH}. Only present when {@link Activity#RESULT_OK} is returned.
+     * An ArrayList&lt;String&gt; of the recognition results when performing
+     * {@link #ACTION_RECOGNIZE_SPEECH}. Returned in the results; not to be specified in the
+     * recognition request. Only present when {@link Activity#RESULT_OK} is returned in
+     * an activity result. In a PendingIntent, the lack of this extra indicates failure.
      */
     public static final String EXTRA_RESULTS = "android.speech.extra.RESULTS";
     
diff --git a/core/java/android/speech/RecognizerResultsIntent.java b/core/java/android/speech/RecognizerResultsIntent.java
index 882f213..228258e 100644
--- a/core/java/android/speech/RecognizerResultsIntent.java
+++ b/core/java/android/speech/RecognizerResultsIntent.java
@@ -95,11 +95,11 @@
      * {@link #EXTRA_VOICE_SEARCH_RESULT_URLS}, if available, or else should execute a search of
      * its own choosing, based on the recognition result string.
      * 
-     * Currently this html content should be expected in the form of an "inline:" uri for the
-     * Browser. In the future this may change to a "content://" uri or some other identifier.
-     * Anyone who reads this extra should confirm that a result is in fact an "inline:" uri and
-     * back off to the urls or strings gracefully if it is not, thus maintaining future backwards
-     * compatibility if this changes.
+     * Currently this html content should be expected in the form of a uri with scheme
+     * {@link #URI_SCHEME_INLINE} for the Browser. In the future this may change to a "content://"
+     * uri or some other identifier. Anyone who reads this extra should confirm that a result is
+     * in fact an "inline:" uri and back off to the urls or strings gracefully if it is not, thus
+     * maintaining future backwards compatibility if this changes.
      * 
      * @hide not to be exposed immediately as the implementation details may change
      */
@@ -119,4 +119,11 @@
      */
     public static final String EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS =
             "android.speech.extras.VOICE_SEARCH_RESULT_HTML_BASE_URLS";
+    
+    /**
+     * The scheme used currently for html content in {@link #EXTRA_VOICE_SEARCH_RESULT_HTML}.
+     * 
+     * @hide not to be exposed immediately as the implementation details may change
+     */
+    public static final String URI_SCHEME_INLINE = "inline";
 }
diff --git a/core/java/android/os/StorageEventListener.java b/core/java/android/storage/StorageEventListener.java
similarity index 94%
rename from core/java/android/os/StorageEventListener.java
rename to core/java/android/storage/StorageEventListener.java
index f852f42..cd71090 100644
--- a/core/java/android/os/StorageEventListener.java
+++ b/core/java/android/storage/StorageEventListener.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.os;
+package android.storage;
 
 /**
  * Used for receiving notifications from the StorageManager
@@ -50,8 +50,8 @@
      * Called when a volume has changed state
      * @param label the system defined label for the volume.
      * @param path the filesystem path for the volume.
-     * @param oldState the old state as returned by {@link android.os.Environment.getExternalStorageState()}.
-     * @param newState the old state as returned by {@link android.os.Environment.getExternalStorageState()}.
+     * @param oldState the old state as returned by {@link android.os.Environment#getExternalStorageState()}.
+     * @param newState the old state as returned by {@link android.os.Environment#getExternalStorageState()}.
      */
     public void onVolumeStateChanged(String label, String path, String oldState, String newState);
 }
diff --git a/core/java/android/os/StorageManager.java b/core/java/android/storage/StorageManager.java
similarity index 95%
rename from core/java/android/os/StorageManager.java
rename to core/java/android/storage/StorageManager.java
index 764abe0..dd8bd63 100644
--- a/core/java/android/os/StorageManager.java
+++ b/core/java/android/storage/StorageManager.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.os;
+package android.storage;
 
 import android.content.Context;
 import android.os.Binder;
@@ -261,9 +261,9 @@
 
 
     /**
-     * Registers a {@link android.os.StorageEventListener StorageEventListener}.
+     * Registers a {@link android.storage.StorageEventListener StorageEventListener}.
      *
-     * @param listener A {@link android.os.StorageEventListener StorageEventListener} object.
+     * @param listener A {@link android.storage.StorageEventListener StorageEventListener} object.
      *
      */
     public void registerListener(StorageEventListener listener) {
@@ -277,9 +277,9 @@
     }
 
     /**
-     * Unregisters a {@link android.os.StorageEventListener StorageEventListener}.
+     * Unregisters a {@link android.storage.StorageEventListener StorageEventListener}.
      *
-     * @param listener A {@link android.os.StorageEventListener StorageEventListener} object.
+     * @param listener A {@link android.storage.StorageEventListener StorageEventListener} object.
      *
      */
     public void unregisterListener(StorageEventListener listener) {
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index 1e558be..3c79200 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -16,9 +16,10 @@
 
 package android.view;
 
+import android.content.Context;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
-import android.content.Context;
 
 /**
  * Detects various gestures and events using the supplied {@link MotionEvent}s.
@@ -231,6 +232,13 @@
     private float mLastMotionX;
 
     private boolean mIsLongpressEnabled;
+    
+    /**
+     * True if we are at a target API level of >= Froyo or the developer can
+     * explicitly set it. If true, input events with > 1 pointer will be ignored
+     * so we can work side by side with multitouch gesture detectors.
+     */
+    private boolean mIgnoreMultitouch;
 
     /**
      * Determines speed during touch scrolling
@@ -336,6 +344,26 @@
      * @throws NullPointerException if {@code listener} is null.
      */
     public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
+        this(context, listener, handler, context != null &&
+                context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.FROYO);
+    }
+    
+    /**
+     * Creates a GestureDetector with the supplied listener.
+     * You may only use this constructor from a UI thread (this is the usual situation).
+     * @see android.os.Handler#Handler()
+     *
+     * @param context the application's context
+     * @param listener the listener invoked for all the callbacks, this must
+     * not be null.
+     * @param handler the handler to use
+     * @param ignoreMultitouch whether events involving more than one pointer should
+     * be ignored.
+     *
+     * @throws NullPointerException if {@code listener} is null.
+     */
+    public GestureDetector(Context context, OnGestureListener listener, Handler handler,
+            boolean ignoreMultitouch) {
         if (handler != null) {
             mHandler = new GestureHandler(handler);
         } else {
@@ -345,14 +373,15 @@
         if (listener instanceof OnDoubleTapListener) {
             setOnDoubleTapListener((OnDoubleTapListener) listener);
         }
-        init(context);
+        init(context, ignoreMultitouch);
     }
 
-    private void init(Context context) {
+    private void init(Context context, boolean ignoreMultitouch) {
         if (mListener == null) {
             throw new NullPointerException("OnGestureListener must not be null");
         }
         mIsLongpressEnabled = true;
+        mIgnoreMultitouch = ignoreMultitouch;
 
         // Fallback to support pre-donuts releases
         int touchSlop, doubleTapSlop;
@@ -425,7 +454,26 @@
 
         boolean handled = false;
 
-        switch (action) {
+        switch (action & MotionEvent.ACTION_MASK) {
+        case MotionEvent.ACTION_POINTER_DOWN:
+            if (mIgnoreMultitouch) {
+                // Multitouch event - abort.
+                cancel();
+            }
+            break;
+
+        case MotionEvent.ACTION_POINTER_UP:
+            // Ending a multitouch gesture and going back to 1 finger
+            if (mIgnoreMultitouch && ev.getPointerCount() == 2) {
+                int id = (((action & MotionEvent.ACTION_POINTER_ID_MASK)
+                        >> MotionEvent.ACTION_POINTER_ID_SHIFT) == 0) ? 1 : 0;
+                mLastMotionX = ev.getX(id);
+                mLastMotionY = ev.getY(id);
+                mVelocityTracker.recycle();
+                mVelocityTracker = VelocityTracker.obtain();
+            }
+            break;
+
         case MotionEvent.ACTION_DOWN:
             if (mDoubleTapListener != null) {
                 boolean hadTapMessage = mHandler.hasMessages(TAP);
@@ -462,7 +510,7 @@
             break;
 
         case MotionEvent.ACTION_MOVE:
-            if (mInLongPress) {
+            if (mInLongPress || (mIgnoreMultitouch && ev.getPointerCount() > 1)) {
                 break;
             }
             final float scrollX = mLastMotionX - x;
@@ -525,21 +573,24 @@
             mHandler.removeMessages(LONG_PRESS);
             break;
         case MotionEvent.ACTION_CANCEL:
-            mHandler.removeMessages(SHOW_PRESS);
-            mHandler.removeMessages(LONG_PRESS);
-            mHandler.removeMessages(TAP);
-            mVelocityTracker.recycle();
-            mVelocityTracker = null;
-            mIsDoubleTapping = false;
-            mStillDown = false;
-            if (mInLongPress) {
-                mInLongPress = false;
-                break;
-            }
+            cancel();
         }
         return handled;
     }
 
+    private void cancel() {
+        mHandler.removeMessages(SHOW_PRESS);
+        mHandler.removeMessages(LONG_PRESS);
+        mHandler.removeMessages(TAP);
+        mVelocityTracker.recycle();
+        mVelocityTracker = null;
+        mIsDoubleTapping = false;
+        mStillDown = false;
+        if (mInLongPress) {
+            mInLongPress = false;
+        }
+    }
+
     private boolean isConsideredDoubleTap(MotionEvent firstDown, MotionEvent firstUp,
             MotionEvent secondDown) {
         if (!mAlwaysInBiggerTapRegion) {
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index f991df7..94ce640 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.util.DisplayMetrics;
-import android.util.Log;
 
 /**
  * Detects transformation gestures involving more than one pointer ("multitouch")
@@ -34,7 +33,6 @@
  *          {@link #onTouchEvent(MotionEvent)}. The methods defined in your
  *          callback will be executed when the events occur.
  * </ul>
- * @hide Pending API approval
  */
 public class ScaleGestureDetector {
     /**
@@ -82,8 +80,7 @@
 
         /**
          * Responds to the end of a scale gesture. Reported by existing
-         * pointers going up. If the end of a gesture would result in a fling,
-         * {@link onTransformFling()} is called instead.
+         * pointers going up.
          * 
          * Once a scale has ended, {@link ScaleGestureDetector#getFocusX()}
          * and {@link ScaleGestureDetector#getFocusY()} will return the location
@@ -103,7 +100,7 @@
      * {@link OnScaleGestureListener#onScaleBegin(ScaleGestureDetector)} return
      * {@code true}. 
      */
-    public class SimpleOnScaleGestureListener implements OnScaleGestureListener {
+    public static class SimpleOnScaleGestureListener implements OnScaleGestureListener {
 
         public boolean onScale(ScaleGestureDetector detector) {
             return true;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index a6b74c4..f2dab6e 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -464,7 +464,7 @@
     private int mHeldMotionless;
 
     // whether support multi-touch
-    private static boolean mSupportMultiTouch;
+    private boolean mSupportMultiTouch;
     // use the framework's ScaleGestureDetector to handle multi-touch
     private ScaleGestureDetector mScaleDetector;
     // minimum scale change during multi-touch zoom
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
new file mode 100644
index 0000000..b26e47d
--- /dev/null
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2008 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.renderscript;
+
+
+/**
+ * @hide
+ *
+ **/
+public class FieldPacker {
+    public FieldPacker(int len) {
+        mPos = 0;
+        mData = new byte[len];
+    }
+
+    public void align(int v) {
+        while ((mPos & (v - 1)) != 0) {
+            mData[mPos++] = 0;
+        }
+    }
+
+    void reset() {
+        mPos = 0;
+    }
+
+    void addI8(byte v) {
+        mData[mPos++] = v;
+    }
+
+    void addI16(short v) {
+        align(2);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)(v >> 8);
+    }
+
+    void addI32(int v) {
+        align(4);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)((v >> 8) & 0xff);
+        mData[mPos++] = (byte)((v >> 16) & 0xff);
+        mData[mPos++] = (byte)((v >> 24) & 0xff);
+    }
+
+    void addI64(long v) {
+        align(8);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)((v >> 8) & 0xff);
+        mData[mPos++] = (byte)((v >> 16) & 0xff);
+        mData[mPos++] = (byte)((v >> 24) & 0xff);
+        mData[mPos++] = (byte)((v >> 32) & 0xff);
+        mData[mPos++] = (byte)((v >> 40) & 0xff);
+        mData[mPos++] = (byte)((v >> 48) & 0xff);
+        mData[mPos++] = (byte)((v >> 56) & 0xff);
+    }
+
+    void addU8(short v) {
+        if ((v < 0) || (v > 0xff)) {
+            throw new IllegalArgumentException("Saving value out of range for type");
+        }
+        mData[mPos++] = (byte)v;
+    }
+
+    void addU16(int v) {
+        if ((v < 0) || (v > 0xffff)) {
+            throw new IllegalArgumentException("Saving value out of range for type");
+        }
+        align(2);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)(v >> 8);
+    }
+
+    void addU32(long v) {
+        if ((v < 0) || (v > 0xffffffff)) {
+            throw new IllegalArgumentException("Saving value out of range for type");
+        }
+        align(4);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)((v >> 8) & 0xff);
+        mData[mPos++] = (byte)((v >> 16) & 0xff);
+        mData[mPos++] = (byte)((v >> 24) & 0xff);
+    }
+
+    void addU64(long v) {
+        if (v < 0) {
+            throw new IllegalArgumentException("Saving value out of range for type");
+        }
+        align(8);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)((v >> 8) & 0xff);
+        mData[mPos++] = (byte)((v >> 16) & 0xff);
+        mData[mPos++] = (byte)((v >> 24) & 0xff);
+        mData[mPos++] = (byte)((v >> 32) & 0xff);
+        mData[mPos++] = (byte)((v >> 40) & 0xff);
+        mData[mPos++] = (byte)((v >> 48) & 0xff);
+        mData[mPos++] = (byte)((v >> 56) & 0xff);
+    }
+
+    void addF32(float v) {
+        addI32(Float.floatToRawIntBits(v));
+    }
+
+    void addF64(float v) {
+        addI64(Double.doubleToRawLongBits(v));
+    }
+
+    final byte[] getData() {
+        return mData;
+    }
+
+    private final byte mData[];
+    private int mPos;
+
+}
+
+
diff --git a/graphics/java/android/renderscript/Matrix2f.java b/graphics/java/android/renderscript/Matrix2f.java
new file mode 100644
index 0000000..4b5e61b
--- /dev/null
+++ b/graphics/java/android/renderscript/Matrix2f.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 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.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * @hide
+ *
+ **/
+public class Matrix2f {
+
+    public Matrix2f() {
+        mMat = new float[4];
+        loadIdentity();
+    }
+
+    public float get(int i, int j) {
+        return mMat[i*2 + j];
+    }
+
+    public void set(int i, int j, float v) {
+        mMat[i*2 + j] = v;
+    }
+
+    public void loadIdentity() {
+        mMat[0] = 1;
+        mMat[1] = 0;
+
+        mMat[2] = 0;
+        mMat[3] = 1;
+    }
+
+    public void load(Matrix2f src) {
+        System.arraycopy(mMat, 0, src, 0, 4);
+    }
+
+    final float[] mMat;
+}
+
+
+
diff --git a/graphics/java/android/renderscript/Matrix3f.java b/graphics/java/android/renderscript/Matrix3f.java
new file mode 100644
index 0000000..19d7b43
--- /dev/null
+++ b/graphics/java/android/renderscript/Matrix3f.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2009 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.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * @hide
+ *
+ **/
+public class Matrix3f {
+
+    public Matrix3f() {
+        mMat = new float[9];
+        loadIdentity();
+    }
+
+    public float get(int i, int j) {
+        return mMat[i*3 + j];
+    }
+
+    public void set(int i, int j, float v) {
+        mMat[i*3 + j] = v;
+    }
+
+    public void loadIdentity() {
+        mMat[0] = 1;
+        mMat[1] = 0;
+        mMat[2] = 0;
+
+        mMat[3] = 0;
+        mMat[4] = 1;
+        mMat[5] = 0;
+
+        mMat[6] = 0;
+        mMat[7] = 0;
+        mMat[8] = 1;
+    }
+
+    public void load(Matrix3f src) {
+        System.arraycopy(mMat, 0, src, 0, 9);
+    }
+
+    final float[] mMat;
+}
+
+
diff --git a/graphics/java/android/renderscript/Matrix.java b/graphics/java/android/renderscript/Matrix4f.java
similarity index 90%
rename from graphics/java/android/renderscript/Matrix.java
rename to graphics/java/android/renderscript/Matrix4f.java
index a266d6b..ebd5bde 100644
--- a/graphics/java/android/renderscript/Matrix.java
+++ b/graphics/java/android/renderscript/Matrix4f.java
@@ -24,9 +24,9 @@
  * @hide
  *
  **/
-public class Matrix {
+public class Matrix4f {
 
-    public Matrix() {
+    public Matrix4f() {
         mMat = new float[16];
         loadIdentity();
     }
@@ -49,7 +49,7 @@
         mMat[5] = 1;
         mMat[6] = 0;
         mMat[7] = 0;
-    
+
         mMat[8] = 0;
         mMat[9] = 0;
         mMat[10] = 1;
@@ -61,8 +61,8 @@
         mMat[15] = 1;
     }
 
-    public void load(Matrix src) {
-        mMat = src.mMat;
+    public void load(Matrix4f src) {
+        System.arraycopy(mMat, 0, src, 0, 16);
     }
 
     public void loadRotate(float rot, float x, float y, float z) {
@@ -77,7 +77,7 @@
         rot *= (float)(java.lang.Math.PI / 180.0f);
         c = (float)java.lang.Math.cos(rot);
         s = (float)java.lang.Math.sin(rot);
-    
+
         float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
         if (!(len != 1)) {
             float recipLen = 1.f / len;
@@ -91,7 +91,7 @@
         float zx = z * x;
         float xs = x * s;
         float ys = y * s;
-        float zs = z * s;		
+        float zs = z * s;
         mMat[ 0] = x*x*nc +  c;
         mMat[ 4] =  xy*nc - zs;
         mMat[ 8] =  zx*nc + ys;
@@ -109,7 +109,7 @@
         mMat[5] = y;
         mMat[10] = z;
     }
-    
+
     public void loadTranslate(float x, float y, float z) {
         loadIdentity();
         mMat[12] = x;
@@ -117,7 +117,7 @@
         mMat[14] = z;
     }
 
-    public void loadMultiply(Matrix lhs, Matrix rhs) {
+    public void loadMultiply(Matrix4f lhs, Matrix4f rhs) {
         for (int i=0 ; i<4 ; i++) {
             float ri0 = 0;
             float ri1 = 0;
@@ -159,31 +159,28 @@
         mMat[15]= 0;
     }
 
-    public void multiply(Matrix rhs) {
-        Matrix tmp = new Matrix();
+    public void multiply(Matrix4f rhs) {
+        Matrix4f tmp = new Matrix4f();
         tmp.loadMultiply(this, rhs);
         load(tmp);
     }
     public void rotate(float rot, float x, float y, float z) {
-        Matrix tmp = new Matrix();
+        Matrix4f tmp = new Matrix4f();
         tmp.loadRotate(rot, x, y, z);
         multiply(tmp);
     }
     public void scale(float x, float y, float z) {
-        Matrix tmp = new Matrix();
+        Matrix4f tmp = new Matrix4f();
         tmp.loadScale(x, y, z);
         multiply(tmp);
     }
     public void translate(float x, float y, float z) {
-        Matrix tmp = new Matrix();
+        Matrix4f tmp = new Matrix4f();
         tmp.loadTranslate(x, y, z);
         multiply(tmp);
     }
 
-
-
-    float[] mMat;
-
+    final float[] mMat;
 }
 
 
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 84f6f2d..1b155d7 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -96,16 +96,16 @@
         static final int PROJECTION_OFFSET = 16;
         static final int TEXTURE_OFFSET = 32;
 
-        Matrix mModel;
-        Matrix mProjection;
-        Matrix mTexture;
+        Matrix4f mModel;
+        Matrix4f mProjection;
+        Matrix4f mTexture;
 
         public Allocation mAlloc;
 
         public MatrixAllocation(RenderScript rs) {
-            mModel = new Matrix();
-            mProjection = new Matrix();
-            mTexture = new Matrix();
+            mModel = new Matrix4f();
+            mProjection = new Matrix4f();
+            mTexture = new Matrix4f();
 
             mAlloc = Allocation.createSized(rs, Element.createUser(rs, Element.DataType.FLOAT_32), 48);
             mAlloc.subData1D(MODELVIEW_OFFSET, 16, mModel.mMat);
@@ -118,17 +118,17 @@
             mAlloc = null;
         }
 
-        public void loadModelview(Matrix m) {
+        public void loadModelview(Matrix4f m) {
             mModel = m;
             mAlloc.subData1D(MODELVIEW_OFFSET, 16, m.mMat);
         }
 
-        public void loadProjection(Matrix m) {
+        public void loadProjection(Matrix4f m) {
             mProjection = m;
             mAlloc.subData1D(PROJECTION_OFFSET, 16, m.mMat);
         }
 
-        public void loadTexture(Matrix m) {
+        public void loadTexture(Matrix4f m) {
             mTexture = m;
             mAlloc.subData1D(TEXTURE_OFFSET, 16, m.mMat);
         }
@@ -152,8 +152,8 @@
 
         public void setupProjectionNormalized(int w, int h) {
             // range -1,1 in the narrow axis at z = 0.
-            Matrix m1 = new Matrix();
-            Matrix m2 = new Matrix();
+            Matrix4f m1 = new Matrix4f();
+            Matrix4f m2 = new Matrix4f();
 
             if(w > h) {
                 float aspect = ((float)w) / h;
diff --git a/graphics/java/android/renderscript/Vector2f.java b/graphics/java/android/renderscript/Vector2f.java
new file mode 100644
index 0000000..567d57fa
--- /dev/null
+++ b/graphics/java/android/renderscript/Vector2f.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 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.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * @hide
+ *
+ **/
+public class Vector2f {
+    public Vector2f() {
+    }
+
+    public float x;
+    public float y;
+}
+
+
+
+
diff --git a/graphics/java/android/renderscript/Vector3f.java b/graphics/java/android/renderscript/Vector3f.java
new file mode 100644
index 0000000..f2842f3
--- /dev/null
+++ b/graphics/java/android/renderscript/Vector3f.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 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.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * @hide
+ *
+ **/
+public class Vector3f {
+    public Vector3f() {
+    }
+
+    public float x;
+    public float y;
+    public float z;
+}
+
+
+
+
diff --git a/graphics/java/android/renderscript/Vector4f.java b/graphics/java/android/renderscript/Vector4f.java
new file mode 100644
index 0000000..fabd959
--- /dev/null
+++ b/graphics/java/android/renderscript/Vector4f.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 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.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * @hide
+ *
+ **/
+public class Vector4f {
+    public Vector4f() {
+    }
+
+    public float x;
+    public float y;
+    public float z;
+    public float w;
+}
+
+
+
diff --git a/include/media/stagefright/HTTPDataSource.h b/include/media/stagefright/HTTPDataSource.h
index 25a90bf..98ebc48 100644
--- a/include/media/stagefright/HTTPDataSource.h
+++ b/include/media/stagefright/HTTPDataSource.h
@@ -63,7 +63,6 @@
     void *mBuffer;
     size_t mBufferLength;
     off_t mBufferOffset;
-    bool mFirstRequest;
 
     bool mContentLengthValid;
     unsigned long long mContentLength;
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index ba7e9bb..e9d3372 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -41,6 +41,8 @@
     public static final String TAG_GPS_LONGITUDE = "GPSLongitude";
     public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
     public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
+    public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp";
+    public static final String TAG_GPS_DATESTAMP = "GPSDateStamp";
     public static final String TAG_WHITE_BALANCE = "WhiteBalance";
 
     // Constants used for the Orientation Exif tag.
@@ -62,8 +64,7 @@
     static {
         System.loadLibrary("exif");
         sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
-        //TODO: uncomment this when our EXIF datetime is encoded as UTC
-        //sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
+        sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
     }
 
     private String mFilename;
@@ -248,7 +249,7 @@
     }
 
     /**
-     * Returns number of milliseconds since Jan. 1, 1970, midnight GMT.
+     * Returns number of milliseconds since Jan. 1, 1970, midnight.
      * Returns -1 if the date time information if not available.
      * @hide
      */
@@ -258,9 +259,32 @@
 
         ParsePosition pos = new ParsePosition(0);
         try {
-            Date date = sFormatter.parse(dateTimeString, pos);
-            if (date == null) return -1;
-            return date.getTime();
+            Date datetime = sFormatter.parse(dateTimeString, pos);
+            if (datetime == null) return -1;
+            return datetime.getTime();
+        } catch (IllegalArgumentException ex) {
+            return -1;
+        }
+    }
+
+    /**
+     * Returns number of milliseconds since Jan. 1, 1970, midnight UTC.
+     * Returns -1 if the date time information if not available.
+     * @hide
+     */
+    public long getGpsDateTime() {
+        String date = mAttributes.get(TAG_GPS_DATESTAMP);
+        String time = mAttributes.get(TAG_GPS_TIMESTAMP);
+        if (date == null || time == null) return -1;
+
+        String dateTimeString = date + ' ' + time;
+        if (dateTimeString == null) return -1;
+
+        ParsePosition pos = new ParsePosition(0);
+        try {
+            Date datetime = sFormatter.parse(dateTimeString, pos);
+            if (datetime == null) return -1;
+            return datetime.getTime();
         } catch (IllegalArgumentException ex) {
             return -1;
         }
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index fcb02f4..8c1b0ea 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -744,7 +744,7 @@
                         values.put(Images.Media.LONGITUDE, latlng[1]);
                     }
 
-                    long time = exif.getDateTime();
+                    long time = exif.getGpsDateTime();
                     if (time != -1) {
                         values.put(Images.Media.DATE_TAKEN, time);
                     }
diff --git a/media/libstagefright/HTTPDataSource.cpp b/media/libstagefright/HTTPDataSource.cpp
index bb3b43c..4b630b9 100644
--- a/media/libstagefright/HTTPDataSource.cpp
+++ b/media/libstagefright/HTTPDataSource.cpp
@@ -34,7 +34,7 @@
         HTTPStream *http, const String8 &headers,
         string *host, string *path, int *port) {
     String8 request;
-    request.append("HEAD ");
+    request.append("GET ");
     request.append(path->c_str());
     request.append(" HTTP/1.1\r\n");
     request.append(headers);
@@ -142,7 +142,6 @@
     mBuffer = malloc(kBufferSize);
     mBufferLength = 0;
     mBufferOffset = 0;
-    mFirstRequest = true;
     mContentLengthValid = false;
 
     initHeaders(headers);
@@ -153,13 +152,15 @@
     LOGI("Connecting to host '%s', port %d, path '%s'",
          host.c_str(), port, path.c_str());
 
+    int numRedirectsRemaining = 5;
     do {
         mInitCheck = mHttp->connect(host.c_str(), port);
 
         if (mInitCheck != OK) {
             return;
         }
-    } while (PerformRedirectIfNecessary(mHttp, mHeaders, &host, &path, &port));
+    } while (PerformRedirectIfNecessary(mHttp, mHeaders, &host, &path, &port)
+             && numRedirectsRemaining-- > 0);
 
     string value;
     if (mHttp->find_header_value("Content-Length", &value)) {
@@ -280,14 +281,11 @@
     }
 
     ssize_t contentLength = 0;
-    if (mFirstRequest || offset != (off_t)(mBufferOffset + mBufferLength)) {
-        if (!mFirstRequest) {
-            LOGV("new range offset=%ld (old=%ld)",
-                 offset, mBufferOffset + mBufferLength);
+    if (offset != (off_t)(mBufferOffset + mBufferLength)) {
+        LOGV("new range offset=%ld (old=%ld)",
+             offset, mBufferOffset + mBufferLength);
 
-            mHttp->disconnect();
-        }
-        mFirstRequest = false;
+        mHttp->disconnect();
 
         contentLength = sendRangeRequest(offset);
 
@@ -306,6 +304,12 @@
 
     ssize_t num_bytes_received = mHttp->receive(mBuffer, contentLength);
 
+    if (num_bytes_received < 0) {
+        mBufferLength = 0;
+
+        return num_bytes_received;
+    }
+
     mBufferLength = (size_t)num_bytes_received;
 
     size_t copy = mBufferLength;
diff --git a/media/libstagefright/HTTPStream.cpp b/media/libstagefright/HTTPStream.cpp
index 02f9439..3711acac 100644
--- a/media/libstagefright/HTTPStream.cpp
+++ b/media/libstagefright/HTTPStream.cpp
@@ -52,7 +52,7 @@
 
     CHECK_EQ(mSocket, -1);
     mSocket = socket(AF_INET, SOCK_STREAM, 0);
-    
+
     if (mSocket < 0) {
         return UNKNOWN_ERROR;
     }
@@ -132,6 +132,14 @@
     return send(data, strlen(data));
 }
 
+// A certain application spawns a local webserver that sends invalid responses,
+// specifically it terminates header line with only a newline instead of the
+// CRLF (carriage-return followed by newline) required by the HTTP specs.
+// The workaround accepts both behaviours but could potentially break
+// legitimate responses that use a single newline to "fold" headers, which is
+// why it's not yet on by default.
+#define WORKAROUND_FOR_MISSING_CR       0
+
 status_t HTTPStream::receive_line(char *line, size_t size) {
     if (mState != CONNECTED) {
         return ERROR_NOT_CONNECTED;
@@ -157,16 +165,27 @@
             return ERROR_CONNECTION_LOST;
         }
 
-        if (saw_CR && c == '\n') {
+#if WORKAROUND_FOR_MISSING_CR
+        if (c == '\n') {
+            // We have a complete line.
+
+            line[saw_CR ? length - 1 : length] = '\0';
+            return OK;
+        }
+#else
+        if (saw_CR &&  c == '\n') {
             // We have a complete line.
 
             line[length - 1] = '\0';
             return OK;
         }
+#endif
 
         saw_CR = (c == '\r');
 
-        CHECK(length + 1 < size);
+        if (length + 1 >= size) {
+            return ERROR_MALFORMED;
+        }
         line[length++] = c;
     }
 }
@@ -175,7 +194,7 @@
     *http_status = -1;
     mHeaders.clear();
 
-    char line[1024];
+    char line[2048];
     status_t err = receive_line(line, sizeof(line));
     if (err != OK) {
         return err;
@@ -257,11 +276,11 @@
             }
 
             disconnect();
-            return ERROR_IO;
+            return total == 0 ? ERROR_IO : total;
         } else if (n == 0) {
             disconnect();
 
-            return ERROR_CONNECTION_LOST;
+            return total == 0 ? ERROR_CONNECTION_LOST : total;
         }
 
         total += (size_t)n;
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index aee4d15..2cf0ddf 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -38,7 +38,7 @@
     void stop();
     bool reachedEOS();
 
-    int64_t getDuration() const;
+    int64_t getDurationUs() const;
     void writeTrackHeader(int32_t trackID);
 
 private:
@@ -46,6 +46,7 @@
     sp<MetaData> mMeta;
     sp<MediaSource> mSource;
     volatile bool mDone;
+    int64_t mMaxTimeStampUs;
 
     pthread_t mThread;
 
@@ -140,7 +141,7 @@
          it != mTracks.end(); ++it) {
         (*it)->stop();
 
-        int64_t duration = (*it)->getDuration();
+        int64_t duration = (*it)->getDurationUs();
         if (duration > max_duration) {
             max_duration = duration;
         }
@@ -162,7 +163,7 @@
         writeInt32(now);           // creation time
         writeInt32(now);           // modification time
         writeInt32(1000);          // timescale
-        writeInt32(max_duration);
+        writeInt32(max_duration / 1000);
         writeInt32(0x10000);       // rate
         writeInt16(0x100);         // volume
         writeInt16(0);             // reserved
@@ -316,6 +317,7 @@
       mMeta(source->getFormat()),
       mSource(source),
       mDone(false),
+      mMaxTimeStampUs(0),
       mCodecSpecificData(NULL),
       mCodecSpecificDataSize(0),
       mReachedEOS(false) {
@@ -343,6 +345,7 @@
     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 
     mDone = false;
+    mMaxTimeStampUs = 0;
     mReachedEOS = false;
 
     pthread_create(&mThread, &attr, ThreadWrapper, this);
@@ -483,6 +486,10 @@
         int64_t timestampUs;
         CHECK(buffer->meta_data()->findInt64(kKeyTime, &timestampUs));
 
+        if (timestampUs > mMaxTimeStampUs) {
+            mMaxTimeStampUs = timestampUs;
+        }
+
         // Our timestamp is in ms.
         info.timestamp = (timestampUs + 500) / 1000;
 
@@ -495,8 +502,8 @@
     mReachedEOS = true;
 }
 
-int64_t MPEG4Writer::Track::getDuration() const {
-    return 10000;  // XXX
+int64_t MPEG4Writer::Track::getDurationUs() const {
+    return mMaxTimeStampUs;
 }
 
 void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) {
@@ -516,7 +523,7 @@
         mOwner->writeInt32(now);           // modification time
         mOwner->writeInt32(trackID);
         mOwner->writeInt32(0);             // reserved
-        mOwner->writeInt32(getDuration());
+        mOwner->writeInt32(getDurationUs() / 1000);
         mOwner->writeInt32(0);             // reserved
         mOwner->writeInt32(0);             // reserved
         mOwner->writeInt16(0);             // layer
@@ -555,7 +562,7 @@
           mOwner->writeInt32(now);           // creation time
           mOwner->writeInt32(now);           // modification time
           mOwner->writeInt32(1000);          // timescale
-          mOwner->writeInt32(getDuration());
+          mOwner->writeInt32(getDurationUs() / 1000);
           mOwner->writeInt16(0);             // language code XXX
           mOwner->writeInt16(0);             // predefined
         mOwner->endBox();
diff --git a/mms-common/java/com/android/common/CharacterSets.java b/mms-common/java/com/android/mmscommon/CharacterSets.java
similarity index 100%
rename from mms-common/java/com/android/common/CharacterSets.java
rename to mms-common/java/com/android/mmscommon/CharacterSets.java
diff --git a/mms-common/java/com/android/common/ContentType.java b/mms-common/java/com/android/mmscommon/ContentType.java
similarity index 100%
rename from mms-common/java/com/android/common/ContentType.java
rename to mms-common/java/com/android/mmscommon/ContentType.java
diff --git a/mms-common/java/com/android/common/EncodedStringValue.java b/mms-common/java/com/android/mmscommon/EncodedStringValue.java
similarity index 100%
rename from mms-common/java/com/android/common/EncodedStringValue.java
rename to mms-common/java/com/android/mmscommon/EncodedStringValue.java
diff --git a/mms-common/java/com/android/common/InvalidHeaderValueException.java b/mms-common/java/com/android/mmscommon/InvalidHeaderValueException.java
similarity index 100%
rename from mms-common/java/com/android/common/InvalidHeaderValueException.java
rename to mms-common/java/com/android/mmscommon/InvalidHeaderValueException.java
diff --git a/mms-common/java/com/android/common/MmsException.java b/mms-common/java/com/android/mmscommon/MmsException.java
similarity index 100%
rename from mms-common/java/com/android/common/MmsException.java
rename to mms-common/java/com/android/mmscommon/MmsException.java
diff --git a/mms-common/java/com/android/common/PduHeaders.java b/mms-common/java/com/android/mmscommon/PduHeaders.java
similarity index 100%
rename from mms-common/java/com/android/common/PduHeaders.java
rename to mms-common/java/com/android/mmscommon/PduHeaders.java
diff --git a/mms-common/java/com/android/common/mms/ContentType.java b/mms-common/java/com/android/mmscommon/mms/ContentType.java
similarity index 99%
rename from mms-common/java/com/android/common/mms/ContentType.java
rename to mms-common/java/com/android/mmscommon/mms/ContentType.java
index 0fdb46c..f21eba8 100644
--- a/mms-common/java/com/android/common/mms/ContentType.java
+++ b/mms-common/java/com/android/mmscommon/mms/ContentType.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package com.android.mms.mms;
+package com.android.mmscommon.mms;
 
 import java.util.ArrayList;
 
diff --git a/mms-common/java/com/android/common/mms/pdu/AcknowledgeInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/AcknowledgeInd.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/AcknowledgeInd.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/AcknowledgeInd.java
diff --git a/mms-common/java/com/android/common/mms/pdu/Base64.java b/mms-common/java/com/android/mmscommon/mms/pdu/Base64.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/Base64.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/Base64.java
diff --git a/mms-common/java/com/android/common/mms/pdu/DeliveryInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/DeliveryInd.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/DeliveryInd.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/DeliveryInd.java
diff --git a/mms-common/java/com/android/common/mms/pdu/GenericPdu.java b/mms-common/java/com/android/mmscommon/mms/pdu/GenericPdu.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/GenericPdu.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/GenericPdu.java
diff --git a/mms-common/java/com/android/common/mms/pdu/MultimediaMessagePdu.java b/mms-common/java/com/android/mmscommon/mms/pdu/MultimediaMessagePdu.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/MultimediaMessagePdu.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/MultimediaMessagePdu.java
diff --git a/mms-common/java/com/android/common/mms/pdu/NotificationInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/NotificationInd.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/NotificationInd.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/NotificationInd.java
diff --git a/mms-common/java/com/android/common/mms/pdu/NotifyRespInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/NotifyRespInd.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/NotifyRespInd.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/NotifyRespInd.java
diff --git a/mms-common/java/com/android/common/mms/pdu/PduBody.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduBody.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/PduBody.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/PduBody.java
diff --git a/mms-common/java/com/android/common/mms/pdu/PduComposer.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduComposer.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/PduComposer.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/PduComposer.java
diff --git a/mms-common/java/com/android/common/mms/pdu/PduContentTypes.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduContentTypes.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/PduContentTypes.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/PduContentTypes.java
diff --git a/mms-common/java/com/android/common/mms/pdu/PduParser.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/PduParser.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/PduParser.java
diff --git a/mms-common/java/com/android/common/mms/pdu/PduPart.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduPart.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/PduPart.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/PduPart.java
diff --git a/mms-common/java/com/android/common/mms/pdu/PduPersister.java b/mms-common/java/com/android/mmscommon/mms/pdu/PduPersister.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/PduPersister.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/PduPersister.java
diff --git a/mms-common/java/com/android/common/mms/pdu/QuotedPrintable.java b/mms-common/java/com/android/mmscommon/mms/pdu/QuotedPrintable.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/QuotedPrintable.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/QuotedPrintable.java
diff --git a/mms-common/java/com/android/common/mms/pdu/ReadOrigInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/ReadOrigInd.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/ReadOrigInd.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/ReadOrigInd.java
diff --git a/mms-common/java/com/android/common/mms/pdu/ReadRecInd.java b/mms-common/java/com/android/mmscommon/mms/pdu/ReadRecInd.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/ReadRecInd.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/ReadRecInd.java
diff --git a/mms-common/java/com/android/common/mms/pdu/RetrieveConf.java b/mms-common/java/com/android/mmscommon/mms/pdu/RetrieveConf.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/RetrieveConf.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/RetrieveConf.java
diff --git a/mms-common/java/com/android/common/mms/pdu/SendConf.java b/mms-common/java/com/android/mmscommon/mms/pdu/SendConf.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/SendConf.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/SendConf.java
diff --git a/mms-common/java/com/android/common/mms/pdu/SendReq.java b/mms-common/java/com/android/mmscommon/mms/pdu/SendReq.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/pdu/SendReq.java
rename to mms-common/java/com/android/mmscommon/mms/pdu/SendReq.java
diff --git a/mms-common/java/com/android/common/mms/util/AbstractCache.java b/mms-common/java/com/android/mmscommon/mms/util/AbstractCache.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/util/AbstractCache.java
rename to mms-common/java/com/android/mmscommon/mms/util/AbstractCache.java
diff --git a/mms-common/java/com/android/common/mms/util/PduCache.java b/mms-common/java/com/android/mmscommon/mms/util/PduCache.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/util/PduCache.java
rename to mms-common/java/com/android/mmscommon/mms/util/PduCache.java
diff --git a/mms-common/java/com/android/common/mms/util/PduCacheEntry.java b/mms-common/java/com/android/mmscommon/mms/util/PduCacheEntry.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/util/PduCacheEntry.java
rename to mms-common/java/com/android/mmscommon/mms/util/PduCacheEntry.java
diff --git a/mms-common/java/com/android/common/mms/telephony/TelephonyProvider.java b/mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
similarity index 100%
rename from mms-common/java/com/android/common/mms/telephony/TelephonyProvider.java
rename to mms-common/java/com/android/mmscommon/telephony/TelephonyProvider.java
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 62dcb08..ef184d2 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -157,7 +157,6 @@
     final Object mAgentConnectLock = new Object();
     IBackupAgent mConnectedAgent;
     volatile boolean mConnecting;
-    volatile boolean mBackupOrRestoreInProgress = false;
     volatile long mLastBackupPass;
     volatile long mNextBackupPass;
 
@@ -217,7 +216,6 @@
     // Persistently track the need to do a full init
     static final String INIT_SENTINEL_FILE_NAME = "_need_init_";
     HashSet<String> mPendingInits = new HashSet<String>();  // transport names
-    volatile boolean mInitInProgress = false;
 
     // ----- Asynchronous backup/restore handler thread -----
 
@@ -237,9 +235,6 @@
                 IBackupTransport transport = getTransport(mCurrentTransport);
                 if (transport == null) {
                     Log.v(TAG, "Backup requested but no transport available");
-                    synchronized (mQueueLock) {
-                        mBackupOrRestoreInProgress = false;
-                    }
                     mWakelock.release();
                     break;
                 }
@@ -267,9 +262,6 @@
                         (new PerformBackupTask(transport, queue, oldJournal)).run();
                     } else {
                         Log.v(TAG, "Backup requested but nothing pending");
-                        synchronized (mQueueLock) {
-                            mBackupOrRestoreInProgress = false;
-                        }
                         mWakelock.release();
                     }
                 }
@@ -440,13 +432,10 @@
                             // can't really do more than bail here
                         }
                     } else {
-                        // Don't run backups now if we're disabled, not yet
-                        // fully set up, in the middle of a backup already,
-                        // or racing with an initialize pass.
-                        if (mEnabled && mProvisioned
-                                && !mBackupOrRestoreInProgress && !mInitInProgress) {
+                        // Don't run backups now if we're disabled or not yet
+                        // fully set up.
+                        if (mEnabled && mProvisioned) {
                             if (DEBUG) Log.v(TAG, "Running a backup pass");
-                            mBackupOrRestoreInProgress = true;
 
                             // Acquire the wakelock and pass it to the backup thread.  it will
                             // be released once backup concludes.
@@ -455,8 +444,7 @@
                             Message msg = mBackupHandler.obtainMessage(MSG_RUN_BACKUP);
                             mBackupHandler.sendMessage(msg);
                         } else {
-                            Log.w(TAG, "Backup pass but e=" + mEnabled + " p=" + mProvisioned
-                                    + " b=" + mBackupOrRestoreInProgress + " i=" + mInitInProgress);
+                            Log.w(TAG, "Backup pass but e=" + mEnabled + " p=" + mProvisioned);
                         }
                     }
                 }
@@ -469,7 +457,6 @@
             if (RUN_INITIALIZE_ACTION.equals(intent.getAction())) {
                 synchronized (mQueueLock) {
                     if (DEBUG) Log.v(TAG, "Running a device init");
-                    mInitInProgress = true;
 
                     // Acquire the wakelock and pass it to the init thread.  it will
                     // be released once init concludes.
@@ -1133,7 +1120,7 @@
                 if (status == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
                     // The backend reports that our dataset has been wiped.  We need to
                     // reset all of our bookkeeping and instead run a new backup pass for
-                    // everything.  This must come after mBackupOrRestoreInProgress is cleared.
+                    // everything.
                     EventLog.writeEvent(EventLogTags.BACKUP_RESET, mTransport.transportDirName());
                     resetBackupState(mStateDir);
                 }
@@ -1166,14 +1153,8 @@
                     Log.e(TAG, "Unable to remove backup journal file " + mJournal);
                 }
 
-                // Only once we're entirely finished do we indicate our completion
-                // and release the wakelock
-                synchronized (mQueueLock) {
-                    mBackupOrRestoreInProgress = false;
-                }
-
+                // Only once we're entirely finished do we release the wakelock
                 if (status == BackupConstants.TRANSPORT_NOT_INITIALIZED) {
-                    // This must come after mBackupOrRestoreInProgress is cleared.
                     backupNow();
                 }
 
@@ -1635,9 +1616,6 @@
                 }
 
                 // done; we can finally release the wakelock
-                synchronized (mQueueLock) {
-                    mBackupOrRestoreInProgress = false;
-                }
                 mWakelock.release();
             }
         }
@@ -1762,9 +1740,6 @@
                 }
 
                 // Last but not least, release the cpu
-                synchronized (mQueueLock) {
-                    mBackupOrRestoreInProgress = false;
-                }
                 mWakelock.release();
             }
         }
@@ -1826,10 +1801,7 @@
             } catch (Exception e) {
                 Log.e(TAG, "Unexpected error performing init", e);
             } finally {
-                // Done; indicate that we're finished and release the wakelock
-                synchronized (mQueueLock) {
-                    mInitInProgress = false;
-                }
+                // Done; release the wakelock
                 mWakelock.release();
             }
         }
@@ -2220,16 +2192,9 @@
             }
 
             synchronized (mQueueLock) {
-                if (mBackupOrRestoreInProgress) {
-                    Log.e(TAG, "Backup pass in progress, restore aborted");
-                    return -1;
-                }
-
                 for (int i = 0; i < mRestoreSets.length; i++) {
                     if (token == mRestoreSets[i].token) {
                         long oldId = Binder.clearCallingIdentity();
-                        // Suppress backups until the restore operation is finished
-                        mBackupOrRestoreInProgress = true;
                         mWakelock.acquire();
                         Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
                         msg.obj = new RestoreParams(mRestoreTransport, observer, token);
@@ -2276,9 +2241,7 @@
         synchronized (mQueueLock) {
             pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")
                     + " / " + (!mProvisioned ? "not " : "") + "provisioned / "
-                    + (!mBackupOrRestoreInProgress ? "not " : "") + "in progress / "
-                    + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init / "
-                    + (!mInitInProgress ? "not " : "") + "initializing");
+                    + (this.mPendingInits.size() == 0 ? "not " : "") + "pending init");
             pw.println("Last backup pass: " + mLastBackupPass
                     + " (now = " + System.currentTimeMillis() + ')');
             pw.println("  next scheduled: " + mNextBackupPass);
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 2caccf7..b07a10b 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -11,5 +11,7 @@
 LOCAL_JAVA_LIBRARIES := android.test.runner services
 LOCAL_PACKAGE_NAME := FrameworksServicesTests
 
+LOCAL_CERTIFICATE := platform
+
 include $(BUILD_PACKAGE)
 
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 9856c6d..5ce109f 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -16,15 +16,10 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.frameworks.servicestests">
-    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
-    <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
 
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     
     <application>
         <uses-library android:name="android.test.runner" />