Merge change 9684

* changes:
  Add a DISCONNECTING call state.
diff --git a/Android.mk b/Android.mk
index 728ae46..275807a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -332,7 +332,13 @@
 
 framework_docs_LOCAL_MODULE_CLASS := JAVA_LIBRARIES
 framework_docs_LOCAL_DROIDDOC_HTML_DIR := docs/html
+# The since flag (-since N.xml API_LEVEL) is used to add API Level information
+# to the reference documentation. Must be in order of oldest to newest.
 framework_docs_LOCAL_DROIDDOC_OPTIONS := \
+    -since ./frameworks/base/api/1.xml 1 \
+    -since ./frameworks/base/api/2.xml 2 \
+    -since ./frameworks/base/api/3.xml 3 \
+    -since ./frameworks/base/api/current.xml Donut \
 		-error 1 -error 2 -warning 3 -error 4 -error 6 -error 8 \
 		-overview $(LOCAL_PATH)/core/java/overview.html
 
diff --git a/api/current.xml b/api/current.xml
index b0b9ce65..f65b5ce 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -186298,6 +186298,211 @@
 </parameter>
 </method>
 </class>
+<class name="ZoomButtonsController"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.view.View.OnTouchListener">
+</implements>
+<constructor name="ZoomButtonsController"
+ type="android.widget.ZoomButtonsController"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="ownerView" type="android.view.View">
+</parameter>
+</constructor>
+<method name="getContainer"
+ return="android.view.ViewGroup"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getZoomControls"
+ return="android.view.View"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isAutoDismissed"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isVisible"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onTouch"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="v" type="android.view.View">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+<method name="setAutoDismissed"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="autoDismiss" type="boolean">
+</parameter>
+</method>
+<method name="setFocusable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="focusable" type="boolean">
+</parameter>
+</method>
+<method name="setOnZoomListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.widget.ZoomButtonsController.OnZoomListener">
+</parameter>
+</method>
+<method name="setVisible"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="visible" type="boolean">
+</parameter>
+</method>
+<method name="setZoomInEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="enabled" type="boolean">
+</parameter>
+</method>
+<method name="setZoomOutEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="enabled" type="boolean">
+</parameter>
+</method>
+<method name="setZoomSpeed"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="speed" type="long">
+</parameter>
+</method>
+</class>
+<interface name="ZoomButtonsController.OnZoomListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onVisibilityChanged"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="visible" type="boolean">
+</parameter>
+</method>
+<method name="onZoom"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="zoomIn" type="boolean">
+</parameter>
+</method>
+</interface>
 <class name="ZoomControls"
  extends="android.widget.LinearLayout"
  abstract="false"
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 18e4a528..1d53eab 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -899,16 +899,15 @@
                 return;
             }
             try {
+                // First stop the existing search before starting voice search, or else we'll end
+                // up showing the search dialog again once we return to the app.
+                ((SearchManager) getContext().getSystemService(Context.SEARCH_SERVICE)).
+                        stopSearch();
+                
                 if (mSearchable.getVoiceSearchLaunchWebSearch()) {
                     getContext().startActivity(mVoiceWebSearchIntent);
                 } else if (mSearchable.getVoiceSearchLaunchRecognizer()) {
-                    Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent);
-                    
-                    // Stop the existing search before starting voice search, or else we'll end
-                    // up showing the search dialog again once we return to the app.
-                    ((SearchManager) getContext().getSystemService(Context.SEARCH_SERVICE)).
-                            stopSearch();
-                    
+                    Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent);                    
                     getContext().startActivity(appSearchIntent);
                 }
             } catch (ActivityNotFoundException e) {
diff --git a/core/java/android/net/http/EventHandler.java b/core/java/android/net/http/EventHandler.java
index 830d1f1..a035c19 100644
--- a/core/java/android/net/http/EventHandler.java
+++ b/core/java/android/net/http/EventHandler.java
@@ -141,7 +141,10 @@
      * SSL certificate error callback. Handles SSL error(s) on the way
      * up to the user. The callback has to make sure that restartConnection() is called,
      * otherwise the connection will be suspended indefinitely.
+     * @return True if the callback can handle the error, which means it will
+     *              call restartConnection() to unblock the thread later,
+     *              otherwise return false.
      */
-    public void handleSslErrorRequest(SslError error);
+    public boolean handleSslErrorRequest(SslError error);
 
 }
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
index 55b733f..8a69d0d 100644
--- a/core/java/android/net/http/HttpsConnection.java
+++ b/core/java/android/net/http/HttpsConnection.java
@@ -323,7 +323,10 @@
                 mSuspended = true;
             }
             // don't hold the lock while calling out to the event handler
-            eventHandler.handleSslErrorRequest(error);
+            boolean canHandle = eventHandler.handleSslErrorRequest(error);
+            if(!canHandle) {
+                throw new IOException("failed to handle "+ error);
+            }
             synchronized (mSuspendLock) {
                 if (mSuspended) {
                     try {
diff --git a/core/java/android/net/http/LoggingEventHandler.java b/core/java/android/net/http/LoggingEventHandler.java
index 1b18651..bdafa0b 100644
--- a/core/java/android/net/http/LoggingEventHandler.java
+++ b/core/java/android/net/http/LoggingEventHandler.java
@@ -82,9 +82,11 @@
         }
     }
 
-    public void handleSslErrorRequest(SslError error) {
+    public boolean handleSslErrorRequest(SslError error) {
         if (HttpLog.LOGV) {
             HttpLog.v("LoggingEventHandler: handleSslErrorRequest():" + error);
         }
+        // return false so that the caller thread won't wait forever
+        return false;
     }
 }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 227c675..a7c76a0 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -80,6 +80,62 @@
         }
     }
 
+    /**
+     * Generic columns for use by sync adapters. The specific functions of
+     * these columns are private to the sync adapter. Other clients of the API
+     * should not attempt to either read or write this column.
+     */
+    private interface BaseSyncColumns {
+
+        /** Generic column for use by sync adapters. */
+        public static final String SYNC1 = "sync1";
+        /** Generic column for use by sync adapters. */
+        public static final String SYNC2 = "sync2";
+        /** Generic column for use by sync adapters. */
+        public static final String SYNC3 = "sync3";
+        /** Generic column for use by sync adapters. */
+        public static final String SYNC4 = "sync4";
+    }
+
+    /**
+     * Columns that appear when each row of a table belongs to a specific
+     * account, including sync information that an account may need.
+     */
+    private interface SyncColumns extends BaseSyncColumns {
+        /**
+         * The name of the account instance to which this row belongs.
+         * <P>Type: TEXT</P>
+         */
+        public static final String ACCOUNT_NAME = "account_name";
+
+        /**
+         * The type of account to which this row belongs, which when paired with
+         * {@link #ACCOUNT_NAME} identifies a specific account.
+         * <P>Type: TEXT</P>
+         */
+        public static final String ACCOUNT_TYPE = "account_type";
+
+        /**
+         * String that uniquely identifies this row to its source account.
+         * <P>Type: TEXT</P>
+         */
+        public static final String SOURCE_ID = "sourceid";
+
+        /**
+         * Version number that is updated whenever this row or its related data
+         * changes.
+         * <P>Type: INTEGER</P>
+         */
+        public static final String VERSION = "version";
+
+        /**
+         * Flag indicating that {@link #VERSION} has changed, and this row needs
+         * to be synchronized by its owning account.
+         * <P>Type: INTEGER (boolean)</P>
+         */
+        public static final String DIRTY = "dirty";
+    }
+
     public interface ContactOptionsColumns {
         /**
          * The number of times a person has been contacted
@@ -169,14 +225,12 @@
         public static final String PRIMARY_PHONE_NUMBER = CommonDataKinds.Phone.NUMBER;
     }
 
-
     /**
      * Constants for the contacts table, which contains a record per group
      * of raw contact representing the same person.
      */
-    // TODO make final once renaming is complete
-    public static /*final*/ class Contacts implements BaseColumns, ContactsColumns,
-            ContactOptionsColumns {
+    public static class Contacts implements BaseColumns, ContactsColumns,
+            ContactOptionsColumns, SyncColumns {
         /**
          * This utility class cannot be instantiated
          */
@@ -238,7 +292,7 @@
          * A sub-directory of a single contact that contains all of the constituent raw contact
          * {@link Data} rows.
          */
-        public static final class Data implements BaseColumns, DataColumns {
+        public static final class Data implements BaseColumns, DataColumns, BaseSyncColumns {
             /**
              * no public constructor since this is a utility class
              */
@@ -271,54 +325,14 @@
              * suggestions.
              * <p>
              * Type: INTEGER
+             *
+             * @deprecated Please use the "limit" parameter
              */
+            @Deprecated
             public static final String MAX_SUGGESTIONS = "max_suggestions";
         }
     }
 
-    @Deprecated
-    public static final class Aggregates extends Contacts {}
-
-    /**
-     * Columns that appear when each row of a table belongs to a specific
-     * account, including sync information that an account may need.
-     */
-    private interface SyncColumns {
-        /**
-         * The name of the account instance to which this row belongs.
-         * <P>Type: TEXT</P>
-         */
-        public static final String ACCOUNT_NAME = "account_name";
-
-        /**
-         * The type of account to which this row belongs, which when paired with
-         * {@link #ACCOUNT_NAME} identifies a specific account.
-         * <P>Type: TEXT</P>
-         */
-        public static final String ACCOUNT_TYPE = "account_type";
-
-        /**
-         * String that uniquely identifies this row to its source account.
-         * <P>Type: TEXT</P>
-         */
-        public static final String SOURCE_ID = "sourceid";
-
-        /**
-         * Version number that is updated whenever this row or its related data
-         * changes.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String VERSION = "version";
-
-        /**
-         * Flag indicating that {@link #VERSION} has changed, and this row needs
-         * to be synchronized by its owning account.
-         * <P>Type: INTEGER (boolean)</P>
-         */
-        public static final String DIRTY = "dirty";
-
-    }
-
     private interface RawContactsColumns {
         /**
          * A reference to the {@link android.provider.ContactsContract.Contacts#_ID} that this
@@ -360,7 +374,7 @@
      * are the primary consumers of this API.
      */
     public static final class RawContacts implements BaseColumns, RawContactsColumns,
-            SyncColumns, ContactOptionsColumns {
+            ContactOptionsColumns, SyncColumns  {
         /**
          * This utility class cannot be instantiated
          */
@@ -508,6 +522,13 @@
         public static final String DATA14 = "data14";
         /** Generic data column, the meaning is {@link #MIMETYPE} specific */
         public static final String DATA15 = "data15";
+
+        /**
+         * An optional update or insert URI parameter that determines if the
+         * corresponding raw contact should be marked as dirty. The default
+         * value is true.
+         */
+        public static final String MARK_AS_DIRTY = "mark_as_dirty";
     }
 
     /**
@@ -516,7 +537,7 @@
      * definition and some generic columns. Each data type can define the meaning for each of
      * the generic columns.
      */
-    public static final class Data implements BaseColumns, DataColumns {
+    public static final class Data implements BaseColumns, DataColumns, BaseSyncColumns {
         /**
          * This utility class cannot be instantiated
          */
@@ -693,9 +714,6 @@
              * The {@link RawContacts#_ID} that this data belongs to.
              */
             public static final String RAW_CONTACT_ID = "raw_contact_id";
-
-            @Deprecated
-            public static final String CONTACT_ID = RAW_CONTACT_ID;
         }
 
         /**
@@ -855,6 +873,18 @@
             public static final int TYPE_FAX_HOME = 5;
             public static final int TYPE_PAGER = 6;
             public static final int TYPE_OTHER = 7;
+            public static final int TYPE_CALLBACK = 8;
+            public static final int TYPE_CAR = 9;
+            public static final int TYPE_COMPANY_MAIN = 10;
+            public static final int TYPE_ISDN = 11;
+            public static final int TYPE_MAIN = 12;
+            public static final int TYPE_OTHER_FAX = 13;
+            public static final int TYPE_RADIO = 14;
+            public static final int TYPE_TELEX = 15;
+            public static final int TYPE_TTY_TDD = 16;
+            public static final int TYPE_WORK_MOBILE = 17;
+            public static final int TYPE_WORK_PAGER = 18;
+            public static final int TYPE_ASSISTANT = 19;
 
             /**
              * The phone number as the user entered it.
diff --git a/core/java/android/provider/Im.java b/core/java/android/provider/Im.java
index ef4ff51..a054132 100644
--- a/core/java/android/provider/Im.java
+++ b/core/java/android/provider/Im.java
@@ -1614,6 +1614,12 @@
         /** specifies whether or not to show as away when device is idle */
         public static final String SETTING_SHOW_AWAY_ON_IDLE = "show_away_on_idle";
 
+        /** specifies whether or not to upload heartbeat stat upon login */
+        public static final String SETTING_UPLOAD_HEARTBEAT_STAT = "upload_heartbeat_stat";
+
+        /** specifies the last heartbeat interval received from the server */
+        public static final String SETTING_HEARTBEAT_INTERVAL = "heartbeat_interval";
+
         /**
          * Used for reliable message queue (RMQ). This is for storing the last rmq id received
          * from the GTalk server
@@ -1833,6 +1839,28 @@
             putBooleanValue(contentResolver, providerId, SETTING_SHOW_AWAY_ON_IDLE, showAway);
         }
 
+        /**
+         * A convenience method to set whether or not to upload heartbeat stat.
+         *
+         * @param contentResolver The ContentResolver to use to access the setting table.
+         * @param uploadStat Whether or not to upload heartbeat stat.
+         */
+        public static void setUploadHeartbeatStat(ContentResolver contentResolver,
+                long providerId, boolean uploadStat) {
+            putBooleanValue(contentResolver, providerId, SETTING_UPLOAD_HEARTBEAT_STAT, uploadStat);
+        }
+
+        /**
+         * A convenience method to set the heartbeat interval last received from the server.
+         *
+         * @param contentResolver The ContentResolver to use to access the setting table.
+         * @param interval The heartbeat interval last received from the server.
+         */
+        public static void setHeartbeatInterval(ContentResolver contentResolver,
+                long providerId, long interval) {
+            putLongValue(contentResolver, providerId, SETTING_HEARTBEAT_INTERVAL, interval);
+        }
+
         public static class QueryMap extends ContentQueryMap {
             private ContentResolver mContentResolver;
             private long mProviderId;
@@ -1982,6 +2010,43 @@
             }
 
             /**
+             * Set whether or not to upload heartbeat stat.
+             *
+             * @param uploadStat whether or not to upload heartbeat stat.
+             */
+            public void setUploadHeartbeatStat(boolean uploadStat) {
+                ProviderSettings.setUploadHeartbeatStat(mContentResolver, mProviderId, uploadStat);
+            }
+
+            /**
+             * Get whether or not to upload heartbeat stat.
+             *
+             * @return Whether or not to upload heartbeat stat.
+             */
+            public boolean getUploadHeartbeatStat() {
+                return getBoolean(SETTING_UPLOAD_HEARTBEAT_STAT,
+                        false /* by default do not upload */);
+            }
+
+            /**
+             * Set the last received heartbeat interval from the server.
+             *
+             * @param interval the last received heartbeat interval from the server.
+             */
+            public void setHeartbeatInterval(long interval) {
+                ProviderSettings.setHeartbeatInterval(mContentResolver, mProviderId, interval);
+            }
+
+            /**
+             * Get the last received heartbeat interval from the server.
+             *
+             * @return the last received heartbeat interval from the server.
+             */
+            public long getHeartbeatInterval() {
+                return getLong(SETTING_HEARTBEAT_INTERVAL, 0L /* an invalid default interval */);
+            }
+
+            /**
              * Convenience function for retrieving a single settings value
              * as a boolean.
              *
@@ -2019,6 +2084,19 @@
                 ContentValues values = getValues(name);
                 return values != null ? values.getAsInteger(VALUE) : def;
             }
+
+            /**
+             * Convenience function for retrieving a single settings value
+             * as a Long.
+             *
+             * @param name The name of the setting to retrieve.
+             * @param def The value to return if the setting is not defined.
+             * @return The setting's current value or 'def' if it is not defined.
+             */
+            private long getLong(String name, long def) {
+                ContentValues values = getValues(name);
+                return values != null ? values.getAsLong(VALUE) : def;
+            }
         }
 
     }
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index fb6ae28..96ce9d6 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -375,6 +375,10 @@
     }
 
     private synchronized void onSinkPropertyChanged(String path, String []propValues) {
+        if (!mBluetoothService.isEnabled()) {
+            return;
+        }
+
         String name = propValues[0];
         String address = mBluetoothService.getAddressFromObjectPath(path);
         if (address == null) {
@@ -382,15 +386,16 @@
             return;
         }
 
-        if (mAudioDevices.get(address) == null) {
-            // Ignore this state change, since it means we have got it after
-            // bluetooth has been disabled.
-            return;
-        }
         if (name.equals(PROPERTY_STATE)) {
             int state = convertBluezSinkStringtoState(propValues[1]);
-            int prevState = mAudioDevices.get(address);
-            handleSinkStateChange(address, prevState, state);
+            if (mAudioDevices.get(address) == null) {
+                // This is for an incoming connection for a device not known to us.
+                // We have authorized it and bluez state has changed.
+                addAudioSink(address);
+            } else {
+                int prevState = mAudioDevices.get(address);
+                handleSinkStateChange(address, prevState, state);
+            }
         }
     }
 
@@ -437,7 +442,6 @@
         return sinks;
     }
 
-
     @Override
     protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (mAudioDevices.isEmpty()) return;
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index afe4757..d2b4447 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -804,6 +804,15 @@
         return mBondState.getBondState(address.toUpperCase());
     }
 
+    /*package*/ boolean isRemoteDeviceInCache(String address) {
+        return (mRemoteDeviceProperties.get(address) != null);
+    }
+
+    /*package*/ String[] getRemoteDeviceProperties(String address) {
+        String objectPath = getObjectPathFromAddress(address);
+        return (String [])getDevicePropertiesNative(objectPath);
+    }
+
     /*package*/ synchronized String getRemoteDeviceProperty(String address, String property) {
         Map<String, String> properties = mRemoteDeviceProperties.get(address);
         if (properties != null) {
@@ -812,8 +821,7 @@
             // Query for remote device properties, again.
             // We will need to reload the cache when we switch Bluetooth on / off
             // or if we crash.
-            String objectPath = getObjectPathFromAddress(address);
-            String propValues[] = (String [])getDevicePropertiesNative(objectPath);
+            String[] propValues = getRemoteDeviceProperties(address);
             if (propValues != null) {
                 addRemoteDeviceProperties(address, propValues);
                 return getRemoteDeviceProperty(address, property);
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index d982777..1704733 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -122,33 +122,41 @@
         return isEventLoopRunningNative();
     }
 
+    private void addDevice(String address, String[] properties) {
+        mBluetoothService.addRemoteDeviceProperties(address, properties);
+        String rssi = mBluetoothService.getRemoteDeviceProperty(address, "RSSI");
+        String classValue = mBluetoothService.getRemoteDeviceProperty(address, "Class");
+        String name = mBluetoothService.getRemoteDeviceProperty(address, "Name");
+        short rssiValue;
+        // For incoming connections, we don't get the RSSI value. Use a default of MIN_VALUE.
+        // If we accept the pairing, we will automatically show it at the top of the list.
+        if (rssi != null) {
+            rssiValue = (short)Integer.valueOf(rssi).intValue();
+        } else {
+            rssiValue = Short.MIN_VALUE;
+        }
+        if (classValue != null) {
+            Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
+            intent.putExtra(BluetoothIntent.ADDRESS, address);
+            intent.putExtra(BluetoothIntent.CLASS, Integer.valueOf(classValue));
+            intent.putExtra(BluetoothIntent.RSSI, rssiValue);
+            intent.putExtra(BluetoothIntent.NAME, name);
+
+            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+        } else {
+            log ("ClassValue: " + classValue + " for remote device: " + address + " is null");
+        }
+    }
+
     private void onDeviceFound(String address, String[] properties) {
         if (properties == null) {
             Log.e(TAG, "ERROR: Remote device properties are null");
             return;
         }
-        mBluetoothService.addRemoteDeviceProperties(address, properties);
-        String rssi = mBluetoothService.getRemoteDeviceProperty(address, "RSSI");
-        String classValue = mBluetoothService.getRemoteDeviceProperty(address, "Class");
-        String name = mBluetoothService.getRemoteDeviceProperty(address, "Name");
-
-        if (rssi != null && classValue != null) {
-            Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_FOUND_ACTION);
-            intent.putExtra(BluetoothIntent.ADDRESS, address);
-            intent.putExtra(BluetoothIntent.CLASS, Integer.valueOf(classValue));
-            intent.putExtra(BluetoothIntent.RSSI, (short)Integer.valueOf(rssi).intValue());
-            intent.putExtra(BluetoothIntent.NAME, name);
-
-            mContext.sendBroadcast(intent, BLUETOOTH_PERM);
-        } else {
-            log ("RSSI: " + rssi + " or ClassValue: " + classValue +
-                    " for remote device: " + address + " is null");
-        }
+        addDevice(address, properties);
     }
 
     private void onDeviceDisappeared(String address) {
-        mBluetoothService.removeRemoteDeviceProperties(address);
-
         Intent intent = new Intent(BluetoothIntent.REMOTE_DEVICE_DISAPPEARED_ACTION);
         intent.putExtra(BluetoothIntent.ADDRESS, address);
         mContext.sendBroadcast(intent, BLUETOOTH_PERM);
@@ -208,7 +216,14 @@
     }
 
     private void onDeviceCreated(String deviceObjectPath) {
-        // do nothing.
+        String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
+        if (!mBluetoothService.isRemoteDeviceInCache(address)) {
+            // Incoming connection, we haven't seen this device, add to cache.
+            String[] properties = mBluetoothService.getRemoteDeviceProperties(address);
+            if (properties != null) {
+                addDevice(address, properties);
+            }
+        }
         return;
     }
 
@@ -316,6 +331,13 @@
                 }
             }
             mBluetoothService.setRemoteDeviceProperty(address, name, uuid);
+        } else if (name.equals("Paired")) {
+            if (propValues[1].equals("true")) {
+                mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
+            } else {
+                mBluetoothService.getBondState().setBondState(address,
+                        BluetoothDevice.BOND_NOT_BONDED);
+            }
         }
     }
 
@@ -403,7 +425,8 @@
         boolean authorized = false;
         UUID uuid = UUID.fromString(deviceUuid);
         if (mBluetoothService.isEnabled() &&
-                (BluetoothUuid.isAudioSink(uuid) || BluetoothUuid.isAvrcpController(uuid))) {
+                (BluetoothUuid.isAudioSink(uuid) || BluetoothUuid.isAvrcpController(uuid)
+                        || BluetoothUuid.isAdvAudioDist(uuid))) {
             BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
             authorized = a2dp.getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF;
             if (authorized) {
diff --git a/core/java/android/test/AndroidTestCase.java b/core/java/android/test/AndroidTestCase.java
index de0587a..1015506 100644
--- a/core/java/android/test/AndroidTestCase.java
+++ b/core/java/android/test/AndroidTestCase.java
@@ -30,6 +30,7 @@
 public class AndroidTestCase extends TestCase {
 
     protected Context mContext;
+    private Context mTestContext;
 
     @Override
     protected void setUp() throws Exception {
@@ -43,7 +44,7 @@
 
     public void testAndroidTestCaseSetupProperly() {
         assertNotNull("Context is null. setContext should be called before tests are run",
-                mContext);        
+                mContext);
     }
 
     public void setContext(Context context) {
@@ -55,6 +56,25 @@
     }
 
     /**
+     * Test context can be used to access resources from the test's own package
+     * as opposed to the resources from the test target package. Access to the
+     * latter is provided by the context set with the {@link #setContext}
+     * method.
+     *
+     * @hide
+     */
+    public void setTestContext(Context context) {
+        mTestContext = context;
+    }
+
+    /**
+     * @hide
+     */
+    public Context getTestContext() {
+        return mTestContext;
+    }
+
+    /**
      * Asserts that launching a given activity is protected by a particular permission by
      * attempting to start the activity and validating that a {@link SecurityException}
      * is thrown that mentions the permission in its error message.
@@ -125,9 +145,9 @@
      * to scrub out any class variables.  This protects against memory leaks in the case where a
      * test case creates a non-static inner class (thus referencing the test case) and gives it to
      * someone else to hold onto.
-     * 
+     *
      * @param testCaseClass The class of the derived TestCase implementation.
-     * 
+     *
      * @throws IllegalAccessException
      */
     protected void scrubClass(final Class<?> testCaseClass)
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 829f68e..1dd0096 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6913,7 +6913,7 @@
 
     /**
      * Set the background to a given resource. The resource should refer to
-     * a Drawable object.
+     * a Drawable object or 0 to remove the background.
      * @param resid The identifier of the resource.
      * @attr ref android.R.styleable#View_background
      */
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 7b91724..d188a39 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -23,9 +23,12 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
 
 /**
  * CookieManager manages cookies according to RFC2109 spec.
@@ -190,6 +193,31 @@
         }
     }
 
+    private static final CookieComparator COMPARATOR = new CookieComparator();
+
+    private static final class CookieComparator implements Comparator<Cookie> {
+        public int compare(Cookie cookie1, Cookie cookie2) {
+            // According to RFC 2109, multiple cookies are ordered in a way such
+            // that those with more specific Path attributes precede those with
+            // less specific. Ordering with respect to other attributes (e.g.,
+            // Domain) is unspecified.
+            // As Set is not modified if the two objects are same, we do want to
+            // assign different value for each cookie.
+            int diff = cookie2.path.length() - cookie1.path.length();
+            if (diff == 0) {
+                diff = cookie2.domain.length() - cookie1.domain.length();
+                if (diff == 0) {
+                    diff = cookie2.name.hashCode() - cookie1.name.hashCode();
+                    if (diff == 0) {
+                        Log.w(LOGTAG, "Found two cookies with the same value." +
+                                "cookie1=" + cookie1 + " , cookie2=" + cookie2);
+                    }
+                }
+            }
+            return diff;
+        }
+    }
+
     private CookieManager() {
     }
 
@@ -401,8 +429,8 @@
         long now = System.currentTimeMillis();
         boolean secure = HTTPS.equals(uri.mScheme);
         Iterator<Cookie> iter = cookieList.iterator();
-        StringBuilder ret = new StringBuilder(256);
 
+        SortedSet<Cookie> cookieSet = new TreeSet<Cookie>(COMPARATOR);
         while (iter.hasNext()) {
             Cookie cookie = iter.next();
             if (cookie.domainMatch(hostAndPath[0]) &&
@@ -413,19 +441,26 @@
                     && (!cookie.secure || secure)
                     && cookie.mode != Cookie.MODE_DELETED) {
                 cookie.lastAcessTime = now;
-
-                if (ret.length() > 0) {
-                    ret.append(SEMICOLON);
-                    // according to RC2109, SEMICOLON is office separator,
-                    // but when log in yahoo.com, it needs WHITE_SPACE too.
-                    ret.append(WHITE_SPACE);
-                }
-
-                ret.append(cookie.name);
-                ret.append(EQUAL);
-                ret.append(cookie.value);
+                cookieSet.add(cookie);
             }
         }
+
+        StringBuilder ret = new StringBuilder(256);
+        Iterator<Cookie> setIter = cookieSet.iterator();
+        while (setIter.hasNext()) {
+            Cookie cookie = setIter.next();
+            if (ret.length() > 0) {
+                ret.append(SEMICOLON);
+                // according to RC2109, SEMICOLON is official separator,
+                // but when log in yahoo.com, it needs WHITE_SPACE too.
+                ret.append(WHITE_SPACE);
+            }
+
+            ret.append(cookie.name);
+            ret.append(EQUAL);
+            ret.append(cookie.value);
+        }
+
         if (ret.length() > 0) {
             if (DebugFlags.COOKIE_MANAGER) {
                 Log.v(LOGTAG, "getCookie: uri: " + uri + " value: " + ret);
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 50436d8..7fff014 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -104,6 +104,7 @@
     private String   mErrorDescription;
     private SslError mSslError;
     private RequestHandle mRequestHandle;
+    private RequestHandle mSslErrorRequestHandle;
 
     // Request data. It is only valid when we are doing a load from the
     // cache. It is needed if the cache returns a redirect
@@ -673,7 +674,7 @@
      * IMPORTANT: as this is called from network thread, can't call native
      * directly
      */
-    public void handleSslErrorRequest(SslError error) {
+    public boolean handleSslErrorRequest(SslError error) {
         if (DebugFlags.LOAD_LISTENER) {
             Log.v(LOGTAG,
                     "LoadListener.handleSslErrorRequest(): url:" + url() +
@@ -681,6 +682,15 @@
                     " certificate: " + error.getCertificate());
         }
         sendMessageInternal(obtainMessage(MSG_SSL_ERROR, error));
+        // if it has been canceled, return false so that the network thread
+        // won't be blocked. If it is not canceled, save the mRequestHandle
+        // so that if it is canceled when MSG_SSL_ERROR is handled, we can
+        // still call handleSslErrorResponse which will call restartConnection
+        // to unblock the network thread.
+        if (!mCancelled) {
+            mSslErrorRequestHandle = mRequestHandle;
+        }
+        return !mCancelled;
     }
 
     // Handle the ssl error on the WebCore thread.
@@ -688,7 +698,10 @@
         if (!mCancelled) {
             mSslError = error;
             Network.getInstance(mContext).handleSslErrorRequest(this);
+        } else if (mSslErrorRequestHandle != null) {
+            mSslErrorRequestHandle.handleSslErrorResponse(true);
         }
+        mSslErrorRequestHandle = null;
     }
 
     /**
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index b56f167..e5813e6 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -157,12 +157,20 @@
     private boolean         mBlockNetworkLoads;
     private boolean         mJavaScriptEnabled = false;
     private boolean         mPluginsEnabled = false;
-    private long            mWebStorageDefaultQuota = 0;
     private boolean         mJavaScriptCanOpenWindowsAutomatically = false;
     private boolean         mUseDoubleTree = false;
     private boolean         mUseWideViewport = false;
     private boolean         mSupportMultipleWindows = false;
     private boolean         mShrinksStandaloneImagesToFit = false;
+    // HTML5 API flags
+    private boolean         mAppCacheEnabled = false;
+    private boolean         mDatabaseEnabled = false;
+    private boolean         mDomStorageEnabled = false;
+    private boolean         mWorkersEnabled = false;  // only affects V8.
+    // HTML5 configuration parameters
+    private long            mAppCacheMaxSize = Long.MAX_VALUE;
+    private String          mAppCachePath = "";
+    private String          mDatabasePath = "";
     // Don't need to synchronize the get/set methods as they
     // are basic types, also none of these values are used in
     // native WebCore code.
@@ -177,12 +185,6 @@
     private boolean         mSupportZoom = true;
     private boolean         mBuiltInZoomControls = false;
     private boolean         mAllowFileAccess = true;
-    private String          mDatabasePath = "";
-    private boolean         mDatabaseEnabled = false;
-    private String          mAppCachePath = "";
-    private boolean         mAppCacheEnabled = false;
-    private long            mAppCacheMaxSize = Long.MAX_VALUE;
-    private boolean         mDomStorageEnabled = false;
 
     // Class to handle messages before WebCore is ready.
     private class EventHandler {
@@ -945,18 +947,6 @@
     }
 
     /**
-     * @hide
-     * Set the default quota for WebStorage DBs
-     * @param quota the default quota in bytes
-     */
-    public synchronized void setWebStorageDefaultQuota(long quota) {
-        if (mWebStorageDefaultQuota != quota) {
-            mWebStorageDefaultQuota = quota;
-            postSync();
-        }
-    }
-
-    /**
      * Set the path to where database storage API databases should be saved.
      * This will update WebCore when the Sync runs in the C++ side.
      * @param databasePath String path to the directory where databases should
@@ -1061,6 +1051,20 @@
     }
 
     /**
+     * Tell the WebView to enable WebWorkers API.
+     * @param flag True if the WebView should enable WebWorkers.
+     * Note that this flag only affects V8. JSC does not have
+     * an equivalent setting.
+     * @hide pending api council approval
+     */
+    public synchronized void setWorkersEnabled(boolean flag) {
+        if (mWorkersEnabled != flag) {
+            mWorkersEnabled = flag;
+            postSync();
+        }
+    }
+
+    /**
      * Return true if javascript is enabled. <b>Note: The default is false.</b>
      * @return True if javascript is enabled.
      */
@@ -1084,15 +1088,6 @@
     }
 
     /**
-     * @hide
-     * Return the default quota for WebStorage DBs
-     * @return the default quota in bytes
-     */
-    public synchronized long getWebStorageDefaultQuota() {
-        return mWebStorageDefaultQuota;
-    }
-
-    /**
      * Tell javascript to open windows automatically. This applies to the
      * javascript function window.open().
      * @param flag True if javascript can open windows automatically.
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 2f9e153..7cfe5b5 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1164,6 +1164,7 @@
 
                         case SET_JS_FLAGS:
                             nativeSetJsFlags((String)msg.obj);
+                            break;
 
                         case GEOLOCATION_PERMISSIONS_PROVIDE:
                             GeolocationPermissionsData data =
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index bae4dad..a41e2e3 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -69,7 +69,6 @@
  * {@link #setVisible(boolean) setVisible(false)} from the
  * {@link View#onDetachedFromWindow}.
  *
- * @hide
  */
 public class ZoomButtonsController implements View.OnTouchListener {
 
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 94d4edc..ccb537a 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -225,9 +225,10 @@
             c = mContentResolver.query(Uri.withAppendedPath(
                     RawContacts.CONTENT_FILTER_EMAIL_URI, Uri.encode(emailAddress)),
                     EMAIL_LOOKUP_PROJECTION, null, null, null);
-            c.moveToFirst();
-            long contactId = c.getLong(EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX);
-            bindFromContactId(contactId);
+            if (c.moveToFirst()) {
+                long contactId = c.getLong(EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX);
+                bindFromContactId(contactId);
+            }
         } finally {
             if (c != null) {
                 c.close();
@@ -248,9 +249,10 @@
         try {
             c = mContentResolver.query(Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number),
                     PHONE_LOOKUP_PROJECTION, null, null, null);
-            c.moveToFirst();
-            long contactId = c.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
-            bindFromContactId(contactId);
+            if (c.moveToFirst()) {
+                long contactId = c.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
+                bindFromContactId(contactId);
+            }
         } finally {
             if (c != null) {
                 c.close();
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 53be891..cfcf111 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -581,14 +581,14 @@
                     mInProgressX = x;
                     mInProgressY = y;
 
-                    if (mPatternInProgress) {
+                    if (mPatternInProgress && patternSize > 0) {
                         final ArrayList<Cell> pattern = mPattern;
                         final float radius = mSquareWidth * mDiameterFactor * 0.5f;
 
-                        Cell cell = pattern.get(patternSize - 1);
+                        final Cell lastCell = pattern.get(patternSize - 1);
 
-                        float startX = getCenterXForColumn(cell.column);
-                        float startY = getCenterYForRow(cell.row);
+                        float startX = getCenterXForColumn(lastCell.column);
+                        float startY = getCenterYForRow(lastCell.row);
 
                         float left;
                         float top;
diff --git a/core/java/com/google/android/gdata2/client/AndroidGDataClient.java b/core/java/com/google/android/gdata2/client/AndroidGDataClient.java
index b55ade3..6ba791d 100644
--- a/core/java/com/google/android/gdata2/client/AndroidGDataClient.java
+++ b/core/java/com/google/android/gdata2/client/AndroidGDataClient.java
@@ -15,6 +15,8 @@
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.StatusLine;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.BasicHttpParams;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
@@ -211,7 +213,7 @@
         HttpResponse response = null;
         int status = 500;
         int redirectsLeft = MAX_REDIRECTS;
-
+        
         URI uri;
         try {
             uri = new URI(uriString);
@@ -238,12 +240,16 @@
             // while by default we have a 2.0 in this variable, it is possible to construct
             // a client that has an empty version field, to work with 1.0 services. 
             if (!TextUtils.isEmpty(mGDataVersion)) {
-                request.addHeader("GData-Version", mGDataVersion);
+                request.addHeader("GDataVersion", mGDataVersion);
             }
 
             // if we have a passed down eTag value, we need to add several headers
             if (!TextUtils.isEmpty(eTag)) { 
                 String method = request.getMethod();
+                Header overrideMethodHeader = request.getFirstHeader(X_HTTP_METHOD_OVERRIDE);
+                if (overrideMethodHeader != null) {
+                    method = overrideMethodHeader.getValue();
+                }
                 if ("GET".equals(method)) {
                     // add the none match header, if the resource is not changed
                     // this request will result in a 304 now.
@@ -252,13 +258,12 @@
                            || "PUT".equals(method)) {
                     // now we send an if-match, but only if the passed in eTag is a strong eTag
                     // as this only makes sense for a strong eTag
-                     if (eTag.startsWith("W/") == false) {
-                         request.addHeader("If-Match", eTag);
-                     }
+                    if (!eTag.startsWith("W/")) {
+                        request.addHeader("If-Match", eTag);
+                    }
                 }
             }
 
-
             if (LOCAL_LOGV) {
                 for (Header h : request.getAllHeaders()) {
                     Log.v(TAG, h.getName() + ": " + h.getValue());
diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp
index 70b7da1..38f3fda 100644
--- a/core/jni/android_net_wifi_Wifi.cpp
+++ b/core/jni/android_net_wifi_Wifi.cpp
@@ -324,6 +324,13 @@
     // number we're interested in.  if we're associating, it returns "OK".
     // beware - <SSID> can contain spaces.
     if (strcmp(reply, "OK") != 0) {
+        // beware of trailing spaces
+        char* end = reply + strlen(reply);
+        while (end > reply && end[-1] == ' ') {
+            end--;
+        }
+        *end = 0;
+
         char* lastSpace = strrchr(reply, ' ');
         // lastSpace should be preceded by "rssi" and followed by the value
         if (lastSpace && !strncmp(lastSpace - 4, "rssi", 4)) {
diff --git a/core/res/res/values-ko/donottranslate-cldr.xml b/core/res/res/values-ko/donottranslate-cldr.xml
index 47f8c03..6b792c6 100644
--- a/core/res/res/values-ko/donottranslate-cldr.xml
+++ b/core/res/res/values-ko/donottranslate-cldr.xml
@@ -101,16 +101,16 @@
     <string name="numeric_date_template">"%s. %s. %s."</string>
     <string name="month_day_year">%Y년 %-m월 %-e일</string>
     <string name="time_of_day">%p %-l:%M:%S</string>
-    <string name="date_and_time">%Y. %-m. %-e. %p %-l:%M:%S</string>
+    <string name="date_and_time">%Y년 %-m월 %-e일 %p %-l:%M:%S</string>
     <string name="date_time">%1$s %2$s</string>
     <string name="time_date">%3$s %1$s</string>
-    <string name="abbrev_month_day_year">%Y. %-m. %-e.</string>
+    <string name="abbrev_month_day_year">%Y년 %-m월 %-e일</string>
     <string name="month_day">%B %-e일</string>
     <string name="month">%-B</string>
     <string name="month_year">%Y년 %B</string>
-    <string name="abbrev_month_day">%-m. %-e.</string>
+    <string name="abbrev_month_day">%-m월 %-e일</string>
     <string name="abbrev_month">%-m월</string>
-    <string name="abbrev_month_year">%Y. %-m.</string>
+    <string name="abbrev_month_year">%Y년 %-m월</string>
     <string name="time1_time2">%1$s ~ %2$s</string>
     <string name="date1_date2">%2$s ~ %5$s</string>
     <string name="numeric_md1_md2">%2$s. %3$s ~ %7$s. %8$s</string>
diff --git a/core/res/res/values-ru/donottranslate-cldr.xml b/core/res/res/values-ru/donottranslate-cldr.xml
index 7745944..4870124 100644
--- a/core/res/res/values-ru/donottranslate-cldr.xml
+++ b/core/res/res/values-ru/donottranslate-cldr.xml
@@ -27,18 +27,18 @@
     <string name="month_long_november">ноября</string>
     <string name="month_long_december">декабря</string>
 
-    <string name="month_medium_january">янв.</string>
-    <string name="month_medium_february">февр.</string>
-    <string name="month_medium_march">марта</string>
-    <string name="month_medium_april">апр.</string>
-    <string name="month_medium_may">мая</string>
-    <string name="month_medium_june">июня</string>
-    <string name="month_medium_july">июля</string>
-    <string name="month_medium_august">авг.</string>
-    <string name="month_medium_september">сент.</string>
-    <string name="month_medium_october">окт.</string>
-    <string name="month_medium_november">нояб.</string>
-    <string name="month_medium_december">дек.</string>
+    <string name="month_medium_january">янв</string>
+    <string name="month_medium_february">фев</string>
+    <string name="month_medium_march">мар</string>
+    <string name="month_medium_april">апр</string>
+    <string name="month_medium_may">май</string>
+    <string name="month_medium_june">июн</string>
+    <string name="month_medium_july">июл</string>
+    <string name="month_medium_august">авг</string>
+    <string name="month_medium_september">сен</string>
+    <string name="month_medium_october">окт</string>
+    <string name="month_medium_november">ноя</string>
+    <string name="month_medium_december">дек</string>
 
     <string name="month_shortest_january">Я</string>
     <string name="month_shortest_february">Ф</string>
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 1327328..3b6571a 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -90,14 +90,14 @@
             mRS.nAdapter1DData(mID, d);
         }
 
-        public void subData(int off, int count, int[] d) {
-            mRS.nAdapter1DSubData(mID, off, count, d);
-        }
-
         public void data(float[] d) {
             mRS.nAdapter1DData(mID, d);
         }
 
+        public void subData(int off, int count, int[] d) {
+            mRS.nAdapter1DSubData(mID, off, count, d);
+        }
+
         public void subData(int off, int count, float[] d) {
             mRS.nAdapter1DSubData(mID, off, count, d);
         }
@@ -112,6 +112,46 @@
     }
 
 
+    public class Adapter2D extends BaseObj {
+        Adapter2D(int id, RenderScript rs) {
+            super(rs);
+            mID = id;
+        }
+
+        public void destroy() {
+            mRS.nAdapter2DDestroy(mID);
+            mID = 0;
+        }
+
+        public void setConstraint(Dimension dim, int value) {
+            mRS.nAdapter2DSetConstraint(mID, dim.mID, value);
+        }
+
+        public void data(int[] d) {
+            mRS.nAdapter2DData(mID, d);
+        }
+
+        public void data(float[] d) {
+            mRS.nAdapter2DData(mID, d);
+        }
+
+        public void subData(int xoff, int yoff, int w, int h, int[] d) {
+            mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
+        }
+
+        public void subData(int xoff, int yoff, int w, int h, float[] d) {
+            mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d);
+        }
+    }
+
+    public Adapter2D createAdapter2D() {
+        int id = mRS.nAdapter2DCreate();
+        if (id != 0) {
+            mRS.nAdapter2DBindAllocation(id, mID);
+        }
+        return new Adapter2D(id, mRS);
+    }
+
 
     // creation
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index dc87b6a..365d053 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -113,11 +113,20 @@
     native void nAdapter1DBindAllocation(int ad, int alloc);
     native void nAdapter1DSetConstraint(int ad, int dim, int value);
     native void nAdapter1DData(int ad, int[] d);
-    native void nAdapter1DSubData(int ad, int off, int count, int[] d);
     native void nAdapter1DData(int ad, float[] d);
+    native void nAdapter1DSubData(int ad, int off, int count, int[] d);
     native void nAdapter1DSubData(int ad, int off, int count, float[] d);
     native int  nAdapter1DCreate();
 
+    native void nAdapter2DDestroy(int id);
+    native void nAdapter2DBindAllocation(int ad, int alloc);
+    native void nAdapter2DSetConstraint(int ad, int dim, int value);
+    native void nAdapter2DData(int ad, int[] d);
+    native void nAdapter2DData(int ad, float[] d);
+    native void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, int[] d);
+    native void nAdapter2DSubData(int ad, int xoff, int yoff, int w, int h, float[] d);
+    native int  nAdapter2DCreate();
+
     native void nScriptDestroy(int script);
     native void nScriptBindAllocation(int vtm, int alloc, int slot);
     native void nScriptCBegin();
@@ -207,7 +216,6 @@
     }
 
 
-
     public enum DepthFunc {
         ALWAYS (0),
         LESS (1),
@@ -343,105 +351,6 @@
     }
 
     //////////////////////////////////////////////////////////////////////////////////
-    // Script
-
-    public class Script extends BaseObj {
-        Script(int id) {
-            super(RenderScript.this);
-            mID = id;
-        }
-
-        public void destroy() {
-            nScriptDestroy(mID);
-            mID = 0;
-        }
-
-        public void bindAllocation(Allocation va, int slot) {
-            nScriptBindAllocation(mID, va.mID, slot);
-        }
-    }
-
-    public void scriptCBegin() {
-        nScriptCBegin();
-    }
-
-    public void scriptCSetTimeZone(String timeZone) {
-        try {
-            byte[] bytes = timeZone.getBytes("UTF-8");
-            nScriptCSetTimeZone(bytes);
-        } catch (java.io.UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public void scriptCSetClearColor(float r, float g, float b, float a) {
-        nScriptCSetClearColor(r, g, b, a);
-    }
-
-    public void scriptCSetClearDepth(float d) {
-        nScriptCSetClearDepth(d);
-    }
-
-    public void scriptCSetClearStencil(int stencil) {
-        nScriptCSetClearStencil(stencil);
-    }
-
-    public void scriptCAddType(Type t) {
-        nScriptCAddType(t.mID);
-    }
-
-    public void scriptCSetRoot(boolean r) {
-        nScriptCSetRoot(r);
-    }
-
-    public void scriptCSetScript(String s) {
-        try {
-            byte[] bytes = s.getBytes("UTF-8");
-            nScriptCSetScript(bytes, 0, bytes.length);
-        } catch (java.io.UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public void scriptCSetScript(Resources resources, int id) {
-        InputStream is = resources.openRawResource(id);
-        try {
-            try {
-                scriptCSetScript(is);
-            } finally {
-                is.close();
-            }
-        } catch(IOException e) {
-            throw new Resources.NotFoundException();
-        }
-    }
-
-    public void  scriptCSetScript(InputStream is) throws IOException {
-        byte[] buf = new byte[1024];
-        int currentPos = 0;
-        while(true) {
-            int bytesLeft = buf.length - currentPos;
-            if (bytesLeft == 0) {
-                byte[] buf2 = new byte[buf.length * 2];
-                System.arraycopy(buf, 0, buf2, 0, buf.length);
-                buf = buf2;
-                bytesLeft = buf.length - currentPos;
-            }
-            int bytesRead = is.read(buf, currentPos, bytesLeft);
-            if (bytesRead <= 0) {
-                break;
-            }
-            currentPos += bytesRead;
-        }
-        nScriptCSetScript(buf, 0, currentPos);
-    }
-
-    public Script scriptCCreate() {
-        int id = nScriptCCreate();
-        return new Script(id);
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
     // ProgramVertex
 
     public class ProgramVertex extends BaseObj {
@@ -720,19 +629,6 @@
         nContextBindProgramVertex(pf.mID);
     }
 
-/*
-    RsAdapter2D rsAdapter2DCreate ();
-    void rsAdapter2DBindAllocation (RsAdapter2D adapt, RsAllocation alloc);
-    void rsAdapter2DDestroy (RsAdapter2D adapter);
-    void rsAdapter2DSetConstraint (RsAdapter2D adapter, RsDimension dim, uint32_t value);
-    void rsAdapter2DData (RsAdapter2D adapter, const void * data);
-    void rsAdapter2DSubData (RsAdapter2D adapter, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void * data);
-    void rsSamplerBegin ();
-    void rsSamplerSet (RsSamplerParam p, RsSamplerValue value);
-    RsSampler rsSamplerCreate ();
-    void rsSamplerBind (RsSampler sampler, RsAllocation alloc);
-*/
-
 }
 
 
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
new file mode 100644
index 0000000..e7bb7a5
--- /dev/null
+++ b/graphics/java/android/renderscript/Script.java
@@ -0,0 +1,91 @@
+/*
+ * 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 Script extends BaseObj {
+    boolean mIsRoot;
+
+    Script(int id, RenderScript rs) {
+        super(rs);
+        mID = id;
+    }
+
+    public void destroy() {
+        mRS.nScriptDestroy(mID);
+        mID = 0;
+    }
+
+    public void bindAllocation(Allocation va, int slot) {
+        mRS.nScriptBindAllocation(mID, va.mID, slot);
+    }
+
+    public void setClearColor(float r, float g, float b, float a) {
+        //mRS.nScriptCSetClearColor(r, g, b, a);
+    }
+
+    public void setClearDepth(float d) {
+        //mRS.nScriptCSetClearDepth(d);
+    }
+
+    public void setClearStencil(int stencil) {
+        //mRS.nScriptCSetClearStencil(stencil);
+    }
+
+
+    public static class Builder {
+        RenderScript mRS;
+        boolean mIsRoot = false;
+        byte[] mTimeZone;
+
+        Builder(RenderScript rs) {
+            mRS = rs;
+        }
+
+        public void addType(Type t) {
+            mRS.nScriptCAddType(t.mID);
+        }
+
+        void transferCreate() {
+            if(mTimeZone != null) {
+                mRS.nScriptCSetTimeZone(mTimeZone);
+            }
+            mRS.nScriptCSetRoot(mIsRoot);
+        }
+
+        void transferObject(Script s) {
+            s.mIsRoot = mIsRoot;
+        }
+
+        public void setTimeZone(String timeZone) {
+            try {
+                mTimeZone = timeZone.getBytes("UTF-8");
+            } catch (java.io.UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void setRoot(boolean r) {
+            mIsRoot = r;
+        }
+
+    }
+
+}
+
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
new file mode 100644
index 0000000..0592f5d
--- /dev/null
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -0,0 +1,106 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import android.content.res.Resources;
+
+
+/**
+ * @hide
+ **/
+public class ScriptC extends Script {
+    ScriptC(int id, RenderScript rs) {
+        super(id, rs);
+    }
+
+
+
+
+    public static class Builder extends Script.Builder {
+        byte[] mProgram;
+        int mProgramLength;
+
+        public Builder(RenderScript rs) {
+            super(rs);
+        }
+
+        public void setScript(String s) {
+            try {
+                mProgram = s.getBytes("UTF-8");
+                mProgramLength = mProgram.length;
+            } catch (java.io.UnsupportedEncodingException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void setScript(Resources resources, int id) {
+            InputStream is = resources.openRawResource(id);
+            try {
+                try {
+                    setScript(is);
+                } finally {
+                    is.close();
+                }
+            } catch(IOException e) {
+                throw new Resources.NotFoundException();
+            }
+        }
+
+        public void  setScript(InputStream is) throws IOException {
+            byte[] buf = new byte[1024];
+            int currentPos = 0;
+            while(true) {
+                int bytesLeft = buf.length - currentPos;
+                if (bytesLeft == 0) {
+                    byte[] buf2 = new byte[buf.length * 2];
+                    System.arraycopy(buf, 0, buf2, 0, buf.length);
+                    buf = buf2;
+                    bytesLeft = buf.length - currentPos;
+                }
+                int bytesRead = is.read(buf, currentPos, bytesLeft);
+                if (bytesRead <= 0) {
+                    break;
+                }
+                currentPos += bytesRead;
+            }
+            mProgram = buf;
+            mProgramLength = currentPos;
+        }
+
+        static synchronized ScriptC internalCreate(Builder b) {
+            b.mRS.nScriptCBegin();
+            b.transferCreate();
+
+            b.mRS.nScriptCSetScript(b.mProgram, 0, b.mProgramLength);
+
+
+            int id = b.mRS.nScriptCCreate();
+            ScriptC obj = new ScriptC(id, b.mRS);
+            b.transferObject(obj);
+            return obj;
+        }
+
+        public ScriptC create() {
+            return internalCreate(this);
+        }
+    }
+
+}
+
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index a02abca..f5227a0 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -551,6 +551,86 @@
 // -----------------------------------
 
 static void
+nAdapter2DDestroy(JNIEnv *_env, jobject _this, jint adapter)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAdapter2DDestroy, con(%p), adapter(%p)", con, (RsAdapter2D)adapter);
+    rsAdapter2DDestroy((RsAdapter2D)adapter);
+}
+
+static void
+nAdapter2DBindAllocation(JNIEnv *_env, jobject _this, jint adapter, jint alloc)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAdapter2DBindAllocation, con(%p), adapter(%p), alloc(%p)", con, (RsAdapter2D)adapter, (RsAllocation)alloc);
+    rsAdapter2DBindAllocation((RsAdapter2D)adapter, (RsAllocation)alloc);
+}
+
+static void
+nAdapter2DSetConstraint(JNIEnv *_env, jobject _this, jint adapter, jint dim, jint value)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAdapter2DSetConstraint, con(%p), adapter(%p), dim(%i), value(%i)", con, (RsAdapter2D)adapter, dim, value);
+    rsAdapter2DSetConstraint((RsAdapter2D)adapter, (RsDimension)dim, value);
+}
+
+static void
+nAdapter2DData_i(JNIEnv *_env, jobject _this, jint adapter, jintArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAdapter2DData_i, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
+    jint *ptr = _env->GetIntArrayElements(data, NULL);
+    rsAdapter2DData((RsAdapter2D)adapter, ptr);
+    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
+}
+
+static void
+nAdapter2DData_f(JNIEnv *_env, jobject _this, jint adapter, jfloatArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAdapter2DData_f, con(%p), adapter(%p), len(%i)", con, (RsAdapter2D)adapter, len);
+    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
+    rsAdapter2DData((RsAdapter2D)adapter, ptr);
+    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
+}
+
+static void
+nAdapter2DSubData_i(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jintArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAdapter2DSubData_i, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
+            con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
+    jint *ptr = _env->GetIntArrayElements(data, NULL);
+    rsAdapter2DSubData((RsAdapter2D)adapter, xoff, yoff, w, h, ptr);
+    _env->ReleaseIntArrayElements(data, ptr, 0/*JNI_ABORT*/);
+}
+
+static void
+nAdapter2DSubData_f(JNIEnv *_env, jobject _this, jint adapter, jint xoff, jint yoff, jint w, jint h, jfloatArray data)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    jint len = _env->GetArrayLength(data);
+    LOG_API("nAdapter2DSubData_f, con(%p), adapter(%p), xoff(%i), yoff(%i), w(%i), h(%i), len(%i)",
+            con, (RsAdapter2D)adapter, xoff, yoff, w, h, len);
+    jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
+    rsAdapter2DSubData((RsAdapter1D)adapter, xoff, yoff, w, h, ptr);
+    _env->ReleaseFloatArrayElements(data, ptr, 0/*JNI_ABORT*/);
+}
+
+static jint
+nAdapter2DCreate(JNIEnv *_env, jobject _this)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nAdapter2DCreate, con(%p)", con);
+    return (jint)rsAdapter2DCreate();
+}
+
+// -----------------------------------
+
+static void
 nScriptDestroy(JNIEnv *_env, jobject _this, jint script)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -1058,11 +1138,20 @@
 {"nAdapter1DBindAllocation",       "(II)V",                                (void*)nAdapter1DBindAllocation },
 {"nAdapter1DSetConstraint",        "(III)V",                               (void*)nAdapter1DSetConstraint },
 {"nAdapter1DData",                 "(I[I)V",                               (void*)nAdapter1DData_i },
-{"nAdapter1DSubData",              "(III[I)V",                             (void*)nAdapter1DSubData_i },
 {"nAdapter1DData",                 "(I[F)V",                               (void*)nAdapter1DData_f },
+{"nAdapter1DSubData",              "(III[I)V",                             (void*)nAdapter1DSubData_i },
 {"nAdapter1DSubData",              "(III[F)V",                             (void*)nAdapter1DSubData_f },
 {"nAdapter1DCreate",               "()I",                                  (void*)nAdapter1DCreate },
 
+{"nAdapter2DDestroy",              "(I)V",                                 (void*)nAdapter2DDestroy },
+{"nAdapter2DBindAllocation",       "(II)V",                                (void*)nAdapter2DBindAllocation },
+{"nAdapter2DSetConstraint",        "(III)V",                               (void*)nAdapter2DSetConstraint },
+{"nAdapter2DData",                 "(I[I)V",                               (void*)nAdapter2DData_i },
+{"nAdapter2DData",                 "(I[F)V",                               (void*)nAdapter2DData_f },
+{"nAdapter2DSubData",              "(IIIII[I)V",                           (void*)nAdapter2DSubData_i },
+{"nAdapter2DSubData",              "(IIIII[F)V",                           (void*)nAdapter2DSubData_f },
+{"nAdapter2DCreate",               "()I",                                  (void*)nAdapter2DCreate },
+
 {"nScriptDestroy",                 "(I)V",                                 (void*)nScriptDestroy },
 {"nScriptBindAllocation",          "(III)V",                               (void*)nScriptBindAllocation },
 {"nScriptCBegin",                  "()V",                                  (void*)nScriptCBegin },
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 6b11a25..375cf6c 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -90,6 +90,7 @@
 	rsObjectBase.cpp \
 	rsMatrix.cpp \
         rsMesh.cpp \
+	rsNoise.cpp \
 	rsProgram.cpp \
 	rsProgramFragment.cpp \
 	rsProgramFragmentStore.cpp \
diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java
index 777a7cf..a9eaead 100644
--- a/libs/rs/java/Film/src/com/android/film/FilmRS.java
+++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java
@@ -28,6 +28,9 @@
 import android.renderscript.RenderScript;
 import android.renderscript.Element;
 import android.renderscript.Allocation;
+import android.renderscript.Dimension;
+import android.renderscript.ScriptC;
+import android.renderscript.Script;
 
 public class FilmRS {
     private final int POS_TRANSLATE = 0;
@@ -65,8 +68,8 @@
 
     private Resources mRes;
     private RenderScript mRS;
-    private RenderScript.Script mScriptStrip;
-    private RenderScript.Script mScriptImage;
+    private Script mScriptStrip;
+    private Script mScriptImage;
     private Element mElementVertex;
     private Element mElementIndex;
     private RenderScript.Sampler mSampler;
@@ -175,7 +178,23 @@
         mImages[11] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p12, ie, true);
         mImages[12] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p13, ie, true);
 
+        int black[] = new int[1024];
         for(int ct=0; ct < mImages.length; ct++) {
+            Allocation.Adapter2D a = mImages[ct].createAdapter2D();
+
+            int size = 512;
+            int mip = 0;
+            while(size >= 2) {
+                a.subData(0, 0, 2, size, black);
+                a.subData(size-2, 0, 2, size, black);
+                a.subData(0, 0, size, 2, black);
+                a.subData(0, size-2, size, 2, black);
+                size >>= 1;
+                mip++;
+                a.setConstraint(Dimension.LOD, mip);
+            }
+            a.destroy();
+
             mImages[ct].uploadToTexture(1);
             mBufferIDs[ct] = mImages[ct].getID();
         }
@@ -210,11 +229,11 @@
 
         Log.e("rs", "Done loading named");
 
-        mRS.scriptCBegin();
-        mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-        mRS.scriptCSetScript(mRes, R.raw.filmstrip);
-        mRS.scriptCSetRoot(true);
-        mScriptStrip = mRS.scriptCCreate();
+        ScriptC.Builder sb = new ScriptC.Builder(mRS);
+        sb.setScript(mRes, R.raw.filmstrip);
+        sb.setRoot(true);
+        mScriptStrip = sb.create();
+        mScriptStrip.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 
         mAllocPos = Allocation.createSized(mRS,
             Element.USER_FLOAT, mBufferPos.length);
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
index 7123bf7..c8d02c1 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -29,6 +29,8 @@
 import android.renderscript.ProgramVertexAlloc;
 import android.renderscript.Element;
 import android.renderscript.Allocation;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
 
 public class FountainRS {
 
@@ -57,7 +59,7 @@
     private Allocation mIntAlloc;
     private Allocation mPartAlloc;
     private Allocation mVertAlloc;
-    private RenderScript.Script mScript;
+    private Script mScript;
     private RenderScript.ProgramFragmentStore mPFS;
     private RenderScript.ProgramFragment mPF;
 
@@ -98,11 +100,11 @@
         }
         mPartAlloc.data(t2);
 
-        mRS.scriptCBegin();
-        mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-        mRS.scriptCSetScript(mRes, R.raw.fountain);
-        mRS.scriptCSetRoot(true);
-        mScript = mRS.scriptCCreate();
+        ScriptC.Builder sb = new ScriptC.Builder(mRS);
+        sb.setScript(mRes, R.raw.fountain);
+        sb.setRoot(true);
+        mScript = sb.create();
+        mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 
         mScript.bindAllocation(mIntAlloc, 0);
         mScript.bindAllocation(mPartAlloc, 1);
diff --git a/libs/rs/java/Grass/res/drawable-hdpi/aa.png b/libs/rs/java/Grass/res/drawable-hdpi/aa.png
new file mode 100644
index 0000000..34cd891
--- /dev/null
+++ b/libs/rs/java/Grass/res/drawable-hdpi/aa.png
Binary files differ
diff --git a/libs/rs/java/Grass/res/raw/grass.c b/libs/rs/java/Grass/res/raw/grass.c
index 79cf483..83c8fed 100644
--- a/libs/rs/java/Grass/res/raw/grass.c
+++ b/libs/rs/java/Grass/res/raw/grass.c
@@ -17,22 +17,22 @@
 #pragma stateFragment(PFBackground)
 #pragma stateFragmentStore(PFSBackground)
 
-#define WVGA_PORTRAIT_WIDTH 480.0f
-#define WVGA_PORTRAIT_HEIGHT 762.0f
-
 #define RSID_STATE 0
 #define RSID_FRAME_COUNT 0
 #define RSID_BLADES_COUNT 1
+#define RSID_WIDTH 2
+#define RSID_HEIGHT 3
 
-#define RSID_SKY_TEXTURES 1
+#define RSID_TEXTURES 1
 #define RSID_SKY_TEXTURE_NIGHT 0
 #define RSID_SKY_TEXTURE_SUNRISE 1
 #define RSID_SKY_TEXTURE_NOON 2
 #define RSID_SKY_TEXTURE_SUNSET 3
+#define RSID_GRASS_TEXTURE 4
 
 #define RSID_BLADES 2
 #define BLADE_STRUCT_FIELDS_COUNT 12
-#define BLADE_STRUCT_DEGREE 0
+#define BLADE_STRUCT_ANGLE 0
 #define BLADE_STRUCT_SIZE 1
 #define BLADE_STRUCT_XPOS 2
 #define BLADE_STRUCT_YPOS 3
@@ -45,6 +45,10 @@
 #define BLADE_STRUCT_S 10
 #define BLADE_STRUCT_B 11
 
+#define TESSELATION 2.0f
+
+#define MAX_BEND 0.09f
+
 #define MIDNIGHT 0.0f
 #define MORNING 0.375f
 #define AFTERNOON 0.6f
@@ -67,31 +71,30 @@
     color(1.0f, 1.0f, 1.0f, a);
 }
 
-void drawNight() {
-    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_NIGHT));
-    // NOTE: Hacky way to draw the night sky
-    drawRect(WVGA_PORTRAIT_WIDTH - 512.0f, -32.0f, WVGA_PORTRAIT_WIDTH, 1024.0f - 32.0f, 0.0f);
+void drawNight(int width, int height) {
+    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_NIGHT));
+    drawRect(width - 512.0f, -32.0f, width, 1024.0f - 32.0f, 0.0f);
 }
 
-void drawSunrise() {
-    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_SUNRISE));
-    drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
+void drawSunrise(int width, int height) {
+    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_SUNRISE));
+    drawRect(0.0f, 0.0f, width, height, 0.0f);
 }
 
-void drawNoon() {
-    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_NOON));
-    drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
+void drawNoon(int width, int height) {
+    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_NOON));
+    drawRect(0.0f, 0.0f, width, height, 0.0f);
 }
 
-void drawSunset() {
-    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_SKY_TEXTURES, RSID_SKY_TEXTURE_SUNSET));
-    drawRect(0.0f, 0.0f, WVGA_PORTRAIT_WIDTH, WVGA_PORTRAIT_HEIGHT, 0.0f);
+void drawSunset(int width, int height) {
+    bindTexture(NAMED_PFBackground, 0, loadI32(RSID_TEXTURES, RSID_SKY_TEXTURE_SUNSET));
+    drawRect(0.0f, 0.0f, width, height, 0.0f);
 }
 
-void drawBlade(int index, float now) {
+void drawBlade(int index, float now, int frameCount) {
     float offset = loadF(RSID_BLADES, index + BLADE_STRUCT_OFFSET);
     float scale = loadF(RSID_BLADES, index + BLADE_STRUCT_SCALE);
-    float degree = loadF(RSID_BLADES, index + BLADE_STRUCT_DEGREE);
+    float angle = loadF(RSID_BLADES, index + BLADE_STRUCT_ANGLE);
     float hardness = loadF(RSID_BLADES, index + BLADE_STRUCT_HARDNESS);
     
     float xpos = loadF(RSID_BLADES, index + BLADE_STRUCT_XPOS);
@@ -121,75 +124,84 @@
 
     hsb(h, s, lerpf(0, b, newB), 1.0f);
 
-    float targetDegree = 0.0f; // TODO Compute
-    degree += (targetDegree - degree) * 0.3f;
+    float newAngle = turbulencef2(xpos * 0.006f, frameCount * 0.006f, 4.0f) - 0.5f;
+    newAngle /= 2.0f;
+    angle = clampf(angle + (newAngle + offset - angle) * 0.15f, -MAX_BEND, MAX_BEND);
 
-    float angle = PI / 2.0f;
-    
-    float currentX = xpos;
-    float currentY = ypos;
-    
-    int i = size;
+    float currentAngle = PI / 2.0f;
+
+    float bottomX = xpos;
+    float bottomY = ypos;
+
+    int i = size * TESSELATION;
+    float lx = lengthX / TESSELATION;
+    float ly = lengthY / TESSELATION;
+    float ss = 4.0f / i + scale / TESSELATION;
+    float sh = 0.5f / TESSELATION;
+    float d = angle * hardness / TESSELATION;
 
     for ( ; i > 0; i--) {
-        float nextX = currentX - cosf(angle) * size * lengthX;
-        float nextY = currentY - sinf(angle) * size * lengthY;
-        angle += degree * hardness;
+        float topX = bottomX - cosf(currentAngle) * size * lx;
+        float topY = bottomY - sinf(currentAngle) * size * ly;
+        currentAngle += d;
 
-        drawQuad(nextX + (i - 1) * scale, nextY, 0.0f,
-                 nextX - (i - 1) * scale, nextY, 0.0f,
-                 currentX - i * scale, currentY + 0.7f, 0.0f,
-                 currentX + i * scale, currentY + 0.7f, 0.0f);
+        float spi = (i - 1) * ss;
+        float si = i * ss;
 
-        currentX = nextX;
-        currentY = nextY;
+        drawQuad(topX + spi, topY, 0.0f,
+                 topX - spi, topY, 0.0f,
+                 bottomX - si, bottomY + sh, 0.0f,
+                 bottomX + si, bottomY + sh, 0.0f);
+
+        bottomX = topX;
+        bottomY = topY;
     }
-    
-    storeF(RSID_BLADES, index + BLADE_STRUCT_DEGREE, degree);
+
+    storeF(RSID_BLADES, index + BLADE_STRUCT_ANGLE, angle);
 }
 
-void drawBlades(float now) {
-    bindTexture(NAMED_PFBackground, 0, 0);    
+void drawBlades(float now, int frameCount) {
+    // For anti-aliasing
+    bindProgramFragmentStore(NAMED_PFSGrass);
+    bindProgramFragment(NAMED_PFGrass);
+    bindTexture(NAMED_PFGrass, 0, loadI32(RSID_TEXTURES, RSID_GRASS_TEXTURE));
 
     int bladesCount = loadI32(RSID_STATE, RSID_BLADES_COUNT);
     int count = bladesCount * BLADE_STRUCT_FIELDS_COUNT;
 
     int i = 0;
     for ( ; i < count; i += BLADE_STRUCT_FIELDS_COUNT) {
-        drawBlade(i, now);
+        drawBlade(i, now, frameCount);
     }
 }
 
 int main(int launchID) {
+    int width = loadI32(RSID_STATE, RSID_WIDTH);
+    int height = loadI32(RSID_STATE, RSID_HEIGHT);
+
     int frameCount = loadI32(RSID_STATE, RSID_FRAME_COUNT);
     float now = time(frameCount);
     alpha(1.0f);
 
     if (now >= MIDNIGHT && now < MORNING) {
-        drawNight();
+        drawNight(width, height);
         alpha(normf(MIDNIGHT, MORNING, now));
-        drawSunrise();
-    }
-    
-    if (now >= MORNING && now < AFTERNOON) {
-        drawSunrise();
+        drawSunrise(width, height);
+    } else if (now >= MORNING && now < AFTERNOON) {
+        drawSunrise(width, height);
         alpha(normf(MORNING, AFTERNOON, now));
-        drawNoon();
+        drawNoon(width, height);
+    } else if (now >= AFTERNOON && now < DUSK) {
+        drawNoon(width, height);
+        alpha(normf(AFTERNOON, DUSK, now));
+        drawSunset(width, height);
+    } else if (now >= DUSK) {
+        drawNight(width, height);
+        alpha(1.0f - normf(DUSK, 1.0f, now));
+        drawSunset(width, height);
     }
 
-    if (now >= AFTERNOON && now < DUSK) {
-        drawNoon();
-        alpha(normf(AFTERNOON, DUSK, now));
-        drawSunset();
-    }
-    
-    if (now >= DUSK) {
-        drawNight();
-        alpha(1.0f - normf(DUSK, 1.0f, now));
-        drawSunset();
-    }
-    
-    drawBlades(now);
+    drawBlades(now, frameCount);
 
     frameCount++;
     storeI32(RSID_STATE, RSID_FRAME_COUNT, frameCount);
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
index 435b5ce..7092133 100644
--- a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
@@ -24,12 +24,14 @@
 import static android.renderscript.RenderScript.BlendSrcFunc;
 import static android.renderscript.RenderScript.BlendDstFunc;
 import android.renderscript.RenderScript;
-import android.renderscript.Element;
 import android.renderscript.Allocation;
 import android.renderscript.ProgramVertexAlloc;
 import static android.renderscript.Element.*;
-
 import static android.util.MathUtils.*;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
 
 import java.util.TimeZone;
 
@@ -37,14 +39,16 @@
     private static final int RSID_STATE = 0;
     private static final int RSID_STATE_FRAMECOUNT = 0;
     private static final int RSID_STATE_BLADES_COUNT = 1;
+    private static final int RSID_STATE_WIDTH = 2;
+    private static final int RSID_STATE_HEIGHT = 3;
 
     private static final int RSID_SKY_TEXTURES = 1;
-    private static final int SKY_TEXTURES_COUNT = 4;
-    
-    private static final int RSID_BLADES = 2;    
+    private static final int SKY_TEXTURES_COUNT = 5;
+
+    private static final int RSID_BLADES = 2;
     private static final int BLADES_COUNT = 100;
     private static final int BLADE_STRUCT_FIELDS_COUNT = 12;
-    private static final int BLADE_STRUCT_DEGREE = 0;
+    private static final int BLADE_STRUCT_ANGLE = 0;
     private static final int BLADE_STRUCT_SIZE = 1;
     private static final int BLADE_STRUCT_XPOS = 2;
     private static final int BLADE_STRUCT_YPOS = 3;
@@ -56,15 +60,16 @@
     private static final int BLADE_STRUCT_H = 9;
     private static final int BLADE_STRUCT_S = 10;
     private static final int BLADE_STRUCT_B = 11;
-    
+
     private Resources mResources;
     private RenderScript mRS;
-    
+    private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
+
     private final int mWidth;
     private final int mHeight;
 
     @SuppressWarnings({"FieldCanBeLocal"})
-    private RenderScript.Script mScript;
+    private Script mScript;
     @SuppressWarnings({"FieldCanBeLocal"})
     private RenderScript.Sampler mSampler;
     @SuppressWarnings({"FieldCanBeLocal"})
@@ -72,24 +77,30 @@
     @SuppressWarnings({"FieldCanBeLocal"})
     private RenderScript.ProgramFragmentStore mPfsBackground;
     @SuppressWarnings({"FieldCanBeLocal"})
-    private RenderScript.ProgramVertex mPvBackground;    
+    private RenderScript.ProgramVertex mPvBackground;
     @SuppressWarnings({"FieldCanBeLocal"})
     private ProgramVertexAlloc mPvOrthoAlloc;
 
     @SuppressWarnings({"FieldCanBeLocal"})
-    private Allocation mSkyTexturesIDs;
+    private Allocation mTexturesIDs;
     @SuppressWarnings({"FieldCanBeLocal"})
-    private Allocation[] mSkyTextures;
+    private Allocation[] mTextures;
     @SuppressWarnings({"FieldCanBeLocal"})
-    private int[] mSkyBufferIDs;
+    private int[] mTextureBufferIDs;
     @SuppressWarnings({"FieldCanBeLocal"})
     private Allocation mState;
     @SuppressWarnings({"FieldCanBeLocal"})
     private Allocation mBlades;
+    @SuppressWarnings({"FieldCanBeLocal"})
+    private RenderScript.ProgramFragment mPfGrass;
+    @SuppressWarnings({"FieldCanBeLocal"})
+    private RenderScript.ProgramFragmentStore mPfsGrass;
 
     public GrassRS(int width, int height) {
         mWidth = width;
         mHeight = height;
+        mBitmapOptions.inScaled = false;
+        mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
     }
 
     public void init(RenderScript rs, Resources res) {
@@ -104,27 +115,28 @@
         createProgramFragment();
         createScriptStructures();
 
-        mRS.scriptCBegin();
-        mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-        mRS.scriptCSetScript(mResources, R.raw.grass);
-        mRS.scriptCSetTimeZone(TimeZone.getDefault().getID());
-        mRS.scriptCSetRoot(true);
-
-        mScript = mRS.scriptCCreate();
+        ScriptC.Builder sb = new ScriptC.Builder(mRS);
+        sb.setScript(mResources, R.raw.grass);
+        sb.setTimeZone(TimeZone.getDefault().getID());
+        sb.setRoot(true);
+        mScript = sb.create();
+        mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 
         loadSkyTextures();
         mScript.bindAllocation(mState, RSID_STATE);
-        mScript.bindAllocation(mSkyTexturesIDs, RSID_SKY_TEXTURES);
+        mScript.bindAllocation(mTexturesIDs, RSID_SKY_TEXTURES);
         mScript.bindAllocation(mBlades, RSID_BLADES);
 
         mRS.contextBindRootScript(mScript);
     }
 
     private void createScriptStructures() {
-        final int[] data = new int[2];
+        final int[] data = new int[4];
         mState = Allocation.createSized(mRS, USER_I32, data.length);
         data[RSID_STATE_FRAMECOUNT] = 0;
         data[RSID_STATE_BLADES_COUNT] = BLADES_COUNT;
+        data[RSID_STATE_WIDTH] = mWidth;
+        data[RSID_STATE_HEIGHT] = mHeight;
         mState.data(data);
 
         final float[] blades = new float[BLADES_COUNT * BLADE_STRUCT_FIELDS_COUNT];
@@ -137,7 +149,7 @@
 
     private void createBlade(float[] blades, int index) {
         //noinspection PointlessArithmeticExpression
-        blades[index + BLADE_STRUCT_DEGREE] = 0.0f;
+        blades[index + BLADE_STRUCT_ANGLE] = 0.0f;
         blades[index + BLADE_STRUCT_SIZE] = random(4.0f) + 4.0f;
         blades[index + BLADE_STRUCT_XPOS] = random(mWidth);
         blades[index + BLADE_STRUCT_YPOS] = mHeight;
@@ -146,23 +158,24 @@
         blades[index + BLADE_STRUCT_LENGTHX] = random(4.5f) + 3.0f;
         blades[index + BLADE_STRUCT_LENGTHY] = random(5.5f) + 2.0f;
         blades[index + BLADE_STRUCT_HARDNESS] = random(1.0f) + 0.2f;
-        blades[index + BLADE_STRUCT_H] = (51.0f + random(5.0f)) / 255.0f;
-        blades[index + BLADE_STRUCT_S] = (200.0f + random(55.0f)) / 255.0f;
-        blades[index + BLADE_STRUCT_B] = (90.0f + random(165.0f)) / 255.0f;
+        blades[index + BLADE_STRUCT_H] = random(0.02f) + 0.2f;
+        blades[index + BLADE_STRUCT_S] = random(0.22f) + 0.78f;
+        blades[index + BLADE_STRUCT_B] = random(0.65f) + 0.35f;
     }
 
     private void loadSkyTextures() {
-        mSkyBufferIDs = new int[SKY_TEXTURES_COUNT];
-        mSkyTextures = new Allocation[SKY_TEXTURES_COUNT];
-        mSkyTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT);
+        mTextureBufferIDs = new int[SKY_TEXTURES_COUNT];
+        mTextures = new Allocation[SKY_TEXTURES_COUNT];
+        mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT);
 
-        final Allocation[] textures = mSkyTextures;
+        final Allocation[] textures = mTextures;
         textures[0] = loadTexture(R.drawable.night, "night");
         textures[1] = loadTexture(R.drawable.sunrise, "sunrise");
         textures[2] = loadTexture(R.drawable.sky, "sky");
         textures[3] = loadTexture(R.drawable.sunset, "sunset");
+        textures[4] = loadTextureARGB(R.drawable.aa, "aa");
 
-        final int[] bufferIds = mSkyBufferIDs;
+        final int[] bufferIds = mTextureBufferIDs;
         final int count = textures.length;
 
         for (int i = 0; i < count; i++) {
@@ -171,12 +184,21 @@
             bufferIds[i] = texture.getID();
         }
 
-        mSkyTexturesIDs.data(bufferIds);
+        mTexturesIDs.data(bufferIds);
     }
 
     private Allocation loadTexture(int id, String name) {
-        Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources, id,
-                Element.RGB_565, false);
+        final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources,
+                id, RGB_565, false);
+        allocation.setName(name);
+        return allocation;
+    }
+
+    private Allocation loadTextureARGB(int id, String name) {
+        // Forces ARGB 32 bits, because pngcrush sometimes optimize our PNGs to
+        // indexed pictures, which are not well supported
+        final Bitmap b = BitmapFactory.decodeResource(mResources, id, mBitmapOptions);
+        final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888, false);
         allocation.setName(name);
         return allocation;
     }
@@ -195,6 +217,13 @@
         mPfBackground = mRS.programFragmentCreate();
         mPfBackground.setName("PFBackground");
         mPfBackground.bindSampler(mSampler, 0);
+
+        mRS.programFragmentBegin(null, null);
+        mRS.programFragmentSetTexEnable(0, true);
+        mRS.programFragmentSetTexEnvMode(0, MODULATE);
+        mPfGrass = mRS.programFragmentCreate();
+        mPfGrass.setName("PFGrass");
+        mPfGrass.bindSampler(mSampler, 0);
     }
 
     private void createProgramFragmentStore() {
@@ -205,6 +234,14 @@
         mRS.programFragmentStoreDepthMask(false);
         mPfsBackground = mRS.programFragmentStoreCreate();
         mPfsBackground.setName("PFSBackground");
+
+        mRS.programFragmentStoreBegin(null, null);
+        mRS.programFragmentStoreDepthFunc(ALWAYS);
+        mRS.programFragmentStoreBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+        mRS.programFragmentStoreDitherEnable(true);
+        mRS.programFragmentStoreDepthMask(false);
+        mPfsGrass = mRS.programFragmentStoreCreate();
+        mPfsGrass.setName("PFSGrass");
     }
 
     private void createProgramVertex() {
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
index cb3dd51..578c225 100644
--- a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
@@ -22,6 +22,8 @@
 import android.renderscript.ProgramVertexAlloc;
 import android.renderscript.Element;
 import android.renderscript.Allocation;
+import android.renderscript.Script;
+import android.renderscript.ScriptC;
 
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -90,7 +92,7 @@
 
     private Resources mRes;
     private RenderScript mRS;
-    private RenderScript.Script mScript;
+    private Script mScript;
     private RenderScript.Sampler mSampler;
     private RenderScript.Sampler mSamplerText;
     private RenderScript.ProgramFragmentStore mPFSBackground;
@@ -313,12 +315,12 @@
 
 
     private void initRS() {
-        mRS.scriptCBegin();
-        mRS.scriptCSetClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-        mRS.scriptCSetScript(mRes, R.raw.rollo);
-        //mRS.scriptCSetScript(mRes, R.raw.rollo2);
-        mRS.scriptCSetRoot(true);
-        mScript = mRS.scriptCCreate();
+        ScriptC.Builder sb = new ScriptC.Builder(mRS);
+        sb.setScript(mRes, R.raw.rollo);
+        //sb.setScript(mRes, R.raw.rollo2);
+        sb.setRoot(true);
+        mScript = sb.create();
+        mScript.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
         mAllocStateBuf = new int[] {0, 0, 0, 8, 0, 0, -1, 0, mAllocIconIDBuf.length, 0, 0};
         mAllocState = Allocation.createSized(mRS,
diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp
index 7ac2aed..25f3340 100644
--- a/libs/rs/rsAdapter.cpp
+++ b/libs/rs/rsAdapter.cpp
@@ -61,8 +61,8 @@
 
 void Adapter1D::data(const void *data)
 {
-    memcpy(getElement(0), 
-           data, 
+    memcpy(getElement(0),
+           data,
            mAllocation.get()->getType()->getSizeBytes());
 }
 
@@ -71,7 +71,9 @@
 
 RsAdapter1D rsi_Adapter1DCreate(Context *rsc)
 {
-    return new Adapter1D();
+    Adapter1D *a = new Adapter1D();
+    a->incRef();
+    return a;
 }
 
 void rsi_Adapter1DDestroy(Context *rsc, RsAdapter1D va)
@@ -176,8 +178,8 @@
 
 void Adapter2D::data(const void *data)
 {
-    memcpy(getElement(0,0), 
-           data, 
+    memcpy(getElement(0,0),
+           data,
            mAllocation.get()->getType()->getSizeBytes());
 }
 
@@ -188,7 +190,9 @@
 
 RsAdapter2D rsi_Adapter2DCreate(Context *rsc)
 {
-    return new Adapter2D();
+    Adapter2D *a = new Adapter2D();
+    a->incRef();
+    return a;
 }
 
 void rsi_Adapter2DDestroy(Context *rsc, RsAdapter2D va)
diff --git a/libs/rs/rsNoise.cpp b/libs/rs/rsNoise.cpp
new file mode 100644
index 0000000..764dc1a
--- /dev/null
+++ b/libs/rs/rsNoise.cpp
@@ -0,0 +1,256 @@
+/*
+ * This implementation of the noise functions was ported from the Java
+ * implementation by Jerry Huxtable (http://www.jhlabs.com) under
+ * Apache License 2.0 (see http://jhlabs.com/ip/filters/download.html)
+ *
+ * Original header:
+ *
+ * Copyright 2006 Jerry Huxtable
+ *
+ * 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.
+ */
+
+#include "rsNoise.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <time.h>
+
+namespace android {
+namespace renderscript {
+
+#define B 0x100
+#define BM 0xff
+#define N 0x1000
+
+static int p[B + B + 2];
+static float g3[B + B + 2][3];
+static float g2[B + B + 2][2];
+static float g1[B + B + 2];
+static bool noise_start = true;
+
+#define lerpf(start, stop, amount) start + (stop - start) * amount
+
+static inline float noise_sCurve(float t)
+{
+    return t * t * (3.0f - 2.0f * t);
+}
+
+inline void SC_normalizef2(float v[])
+{
+    float s = (float)sqrtf(v[0] * v[0] + v[1] * v[1]);
+    v[0] = v[0] / s;
+    v[1] = v[1] / s;
+}
+
+inline void SC_normalizef3(float v[])
+{
+    float s = (float)sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+    v[0] = v[0] / s;
+    v[1] = v[1] / s;
+    v[2] = v[2] / s;
+}
+
+static void noise_init()
+{
+    int i, j, k;
+    
+    for (i = 0; i < B; i++) {
+        p[i] = i;
+        
+        g1[i] = (float)((rand() % (B + B)) - B) / B;
+        
+        for (j = 0; j < 2; j++)
+            g2[i][j] = (float)((rand() % (B + B)) - B) / B;
+        SC_normalizef2(g2[i]);
+        
+        for (j = 0; j < 3; j++)
+            g3[i][j] = (float)((rand() % (B + B)) - B) / B;
+        SC_normalizef3(g3[i]);
+    }
+    
+    for (i = B-1; i >= 0; i--) {
+        k = p[i];
+        p[i] = p[j = rand() % B];
+        p[j] = k;
+    }
+    
+    for (i = 0; i < B + 2; i++) {
+        p[B + i] = p[i];
+        g1[B + i] = g1[i];
+        for (j = 0; j < 2; j++)
+            g2[B + i][j] = g2[i][j];
+        for (j = 0; j < 3; j++)
+            g3[B + i][j] = g3[i][j];
+    }
+}
+
+float SC_noisef(float x)
+{
+    srand(time(NULL));
+    int bx0, bx1;
+    float rx0, rx1, sx, t, u, v;
+    
+    if (noise_start) {
+        noise_start = false;
+        noise_init();
+    }
+    
+    t = x + N;
+    bx0 = ((int)t) & BM;
+    bx1 = (bx0+1) & BM;
+    rx0 = t - (int)t;
+    rx1 = rx0 - 1.0f;
+    
+    sx = noise_sCurve(rx0);
+    
+    u = rx0 * g1[p[bx0]];
+    v = rx1 * g1[p[bx1]];
+    return 2.3f * lerpf(u, v, sx);
+}
+
+float SC_noisef2(float x, float y)
+{
+    srand(time(NULL));
+    int bx0, bx1, by0, by1, b00, b10, b01, b11;
+    float rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v;
+    float *q;
+    int i, j;
+    
+    if (noise_start) {
+        noise_start = false;
+        noise_init();
+    }
+    
+    t = x + N;
+    bx0 = ((int)t) & BM;
+    bx1 = (bx0+1) & BM;
+    rx0 = t - (int)t;
+    rx1 = rx0 - 1.0f;
+	
+    t = y + N;
+    by0 = ((int)t) & BM;
+    by1 = (by0+1) & BM;
+    ry0 = t - (int)t;
+    ry1 = ry0 - 1.0f;
+	
+    i = p[bx0];
+    j = p[bx1];
+    
+    b00 = p[i + by0];
+    b10 = p[j + by0];
+    b01 = p[i + by1];
+    b11 = p[j + by1];
+    
+    sx = noise_sCurve(rx0);
+    sy = noise_sCurve(ry0);
+    
+    q = g2[b00]; u = rx0 * q[0] + ry0 * q[1];
+    q = g2[b10]; v = rx1 * q[0] + ry0 * q[1];
+    a = lerpf(u, v, sx);
+    
+    q = g2[b01]; u = rx0 * q[0] + ry1 * q[1];
+    q = g2[b11]; v = rx1 * q[0] + ry1 * q[1];
+    b = lerpf(u, v, sx);
+    
+    return 1.5f*lerpf(a, b, sy);
+}
+
+float SC_noisef3(float x, float y, float z)
+{
+    srand(time(NULL));
+    int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
+    float rx0, rx1, ry0, ry1, rz0, rz1, sy, sz, a, b, c, d, t, u, v;
+    float *q;
+    int i, j;
+    
+    if (noise_start) {
+        noise_start = false;
+        noise_init();
+    }
+    
+    t = x + N;
+    bx0 = ((int)t) & BM;
+    bx1 = (bx0+1) & BM;
+    rx0 = t - (int)t;
+    rx1 = rx0 - 1.0f;
+    
+    t = y + N;
+    by0 = ((int)t) & BM;
+    by1 = (by0+1) & BM;
+    ry0 = t - (int)t;
+    ry1 = ry0 - 1.0f;
+	
+    t = z + N;
+    bz0 = ((int)t) & BM;
+    bz1 = (bz0+1) & BM;
+    rz0 = t - (int)t;
+    rz1 = rz0 - 1.0f;
+	
+    i = p[bx0];
+    j = p[bx1];
+    
+    b00 = p[i + by0];
+    b10 = p[j + by0];
+    b01 = p[i + by1];
+    b11 = p[j + by1];
+    
+    t  = noise_sCurve(rx0);
+    sy = noise_sCurve(ry0);
+    sz = noise_sCurve(rz0);
+    
+    q = g3[b00 + bz0]; u = rx0 * q[0] + ry0 * q[1] + rz0 * q[2];
+    q = g3[b10 + bz0]; v = rx1 * q[0] + ry0 * q[1] + rz0 * q[2];
+    a = lerpf(u, v, t);
+    
+    q = g3[b01 + bz0]; u = rx0 * q[0] + ry1 * q[1] + rz0 * q[2];
+    q = g3[b11 + bz0]; v = rx1 * q[0] + ry1 * q[1] + rz0 * q[2];
+    b = lerpf(u, v, t);
+    
+    c = lerpf(a, b, sy);
+    
+    q = g3[b00 + bz1]; u = rx0 * q[0] + ry0 * q[1] + rz1 * q[2];
+    q = g3[b10 + bz1]; v = rx1 * q[0] + ry0 * q[1] + rz1 * q[2];
+    a = lerpf(u, v, t);
+    
+    q = g3[b01 + bz1]; u = rx0 * q[0] + ry1 * q[1] + rz1 * q[2];
+    q = g3[b11 + bz1]; v = rx1 * q[0] + ry1 * q[1] + rz1 * q[2];
+    b = lerpf(u, v, t);
+    
+    d = lerpf(a, b, sy);
+    
+    return 1.5f*lerpf(c, d, sz);
+}
+
+float SC_turbulencef2(float x, float y, float octaves)
+{
+    srand(time(NULL));
+    float t = 0.0f;
+    
+    for (float f = 1.0f; f <= octaves; f *= 2)
+        t += fabs(SC_noisef2(f * x, f * y)) / f;
+    return t;
+}
+
+float SC_turbulencef3(float x, float y, float z, float octaves)
+{
+    srand(time(NULL));
+    float t = 0.0f;
+    
+    for (float f = 1.0f; f <= octaves; f *= 2)
+        t += fabs(SC_noisef3(f * x, f * y, f * z)) / f;
+    return t;
+}
+
+}
+}
\ No newline at end of file
diff --git a/libs/rs/rsNoise.h b/libs/rs/rsNoise.h
new file mode 100644
index 0000000..9040751
--- /dev/null
+++ b/libs/rs/rsNoise.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_RS_NOISE_H
+#define ANDROID_RS_NOISE_H
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+void SC_normalizef2(float v[]);
+void SC_normalizef3(float v[]);
+float SC_noisef(float x);
+float SC_noisef2(float x, float y);
+float SC_noisef3(float x, float y, float z);
+float SC_turbulencef2(float x, float y, float octaves);
+float SC_turbulencef3(float x, float y, float z, float octaves);
+
+}
+}
+
+#endif
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index e4979ea..561cde6 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -17,6 +17,7 @@
 #include "rsContext.h"
 #include "rsScriptC.h"
 #include "rsMatrix.h"
+#include "rsNoise.h"
 
 #include "acc/acc.h"
 #include "utils/String8.h"
@@ -748,6 +749,16 @@
         "float", "(float, float, float)" },
     { "mapf", (void *)&SC_mapf,
         "float", "(float, float, float, float, float)" },
+    { "noisef", (void *)&SC_noisef,
+        "float", "(float)" },
+    { "noisef2", (void *)&SC_noisef2,
+        "float", "(float, float)" },
+    { "noisef3", (void *)&SC_noisef3,
+        "float", "(float, float, float)" },
+    { "turbulencef2", (void *)&SC_turbulencef2,
+        "float", "(float, float, float)" },
+    { "turbulencef3", (void *)&SC_turbulencef3,
+        "float", "(float, float, float, float)" },
 
     // time
     { "second", (void *)&SC_second,
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
index ff49c87..5221fed 100644
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -178,6 +178,7 @@
 {
     Mutex::Autolock _l(mLock);
     surface_info_t* info = mInfo;
+    mBuffer.clear(); // free buffer before allocating a new one
     sp<Buffer> buffer = new Buffer(mWidth, mHeight, mFormat, mFlags);
     status_t err = buffer->initCheck();
     if (LIKELY(err == NO_ERROR)) {
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 3a49a5f..c6a9ae8 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -35,6 +35,7 @@
 {
     static {
         System.loadLibrary("media_jni");
+        native_init();
     }
 
     // The field below is accessed by native methods
@@ -211,7 +212,8 @@
      * allocated internally.
      */
     public native void release();
-    private native void native_setup(); 
+    private native void native_setup();
+    private static native void native_init();
 
     private native final void native_finalize();
 
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index a23f535..a8689f2 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -466,6 +466,7 @@
 
     static {
         System.loadLibrary("media_jni");
+        native_init();
     }
 
     private final static String TAG = "MediaPlayer";
@@ -1109,6 +1110,7 @@
      */
     private native final int native_setMetadataFilter(Parcel request);
 
+    private static native final void native_init();
     private native final void native_setup(Object mediaplayer_this);
     private native final void native_finalize();
 
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index be4b489..46ede7f 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -57,6 +57,7 @@
 {
     static {
         System.loadLibrary("media_jni");
+        native_init();
     }
     private final static String TAG = "MediaRecorder";
 
@@ -655,6 +656,8 @@
      */
     public native void release();
 
+    private static native final void native_init();
+
     private native final void native_setup(Object mediarecorder_this) throws IllegalStateException;
 
     private native final void native_finalize();
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index d5801f7..71af909 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -99,6 +99,7 @@
 {
     static {
         System.loadLibrary("media_jni");
+        native_init();
     }
 
     private final static String TAG = "MediaScanner";
@@ -680,6 +681,26 @@
                 }
                 values.put(MediaStore.MediaColumns.TITLE, title);
             }
+            String album = values.getAsString(Audio.Media.ALBUM);
+            if (MediaFile.UNKNOWN_STRING.equals(album)) {
+                album = values.getAsString(MediaStore.MediaColumns.DATA);
+                // extract last path segment before file name
+                int lastSlash = album.lastIndexOf('/');
+                if (lastSlash >= 0) {
+                    int previousSlash = 0;
+                    while (true) {
+                        int idx = album.indexOf('/', previousSlash + 1);
+                        if (idx < 0 || idx >= lastSlash) {
+                            break;
+                        }
+                        previousSlash = idx;
+                    }
+                    if (previousSlash != 0) {
+                        album = album.substring(previousSlash + 1, lastSlash);
+                        values.put(Audio.Media.ALBUM, album);
+                    }
+                }
+            }
             if (isAudio) {
                 values.put(Audio.Media.IS_RINGTONE, ringtones);
                 values.put(Audio.Media.IS_NOTIFICATION, notifications);
@@ -1404,6 +1425,7 @@
 
     public native byte[] extractAlbumArt(FileDescriptor fd);
 
+    private static native final void native_init();
     private native final void native_setup();
     private native final void native_finalize();
     @Override
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 1f37111..49a82e6 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -12,11 +12,9 @@
 
 LOCAL_SHARED_LIBRARIES := \
     libopencore_player \
-    libopencore_author \
     libomx_amrenc_sharedlibrary \
     libandroid_runtime \
     libnativehelper \
-    libcutils \
     libutils \
     libbinder \
     libmedia \
diff --git a/media/jni/android_media_AmrInputStream.cpp b/media/jni/android_media_AmrInputStream.cpp
index 51cb6c7..c4dd07e 100644
--- a/media/jni/android_media_AmrInputStream.cpp
+++ b/media/jni/android_media_AmrInputStream.cpp
@@ -169,13 +169,6 @@
 int register_android_media_AmrInputStream(JNIEnv *env)
 {
     const char* const kClassPathName = "android/media/AmrInputStream";
-    jclass clazz;
-
-    clazz = env->FindClass(kClassPathName);
-    if (clazz == NULL) {
-        LOGE("Can't find %s", kClassPathName);
-        return -1;
-    }
 
     return AndroidRuntime::registerNativeMethods(env,
             kClassPathName, gMethods, NELEM(gMethods));
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 4624a18..49f8cdd 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -40,6 +40,7 @@
 
 static fields_t fields;
 static Mutex sLock;
+static const char* const kClassPathName = "android/media/MediaMetadataRetriever";
 
 static void process_media_retriever_call(JNIEnv *env, status_t opStatus, const char* exception, const char *message)
 {
@@ -269,6 +270,36 @@
     android_media_MediaMetadataRetriever_release(env, thiz);
 }
 
+// This function gets a field ID, which in turn causes class initialization.
+// It is called from a static block in MediaMetadataRetriever, which won't run until the
+// first time an instance of this class is used.
+static void android_media_MediaMetadataRetriever_native_init(JNIEnv *env)
+{
+    jclass clazz = env->FindClass(kClassPathName);
+    if (clazz == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaMetadataRetriever");
+        return;
+    }
+
+    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+    if (fields.context == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaMetadataRetriever.mNativeContext");
+        return;
+    }
+
+    fields.bitmapClazz = env->FindClass("android/graphics/Bitmap");
+    if (fields.bitmapClazz == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/graphics/Bitmap");
+        return;
+    }
+
+    fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(IZ[B)V");
+    if (fields.bitmapConstructor == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find Bitmap constructor");
+        return;
+    }
+}
+
 static void android_media_MediaMetadataRetriever_native_setup(JNIEnv *env, jobject thiz)
 {
     LOGV("native_setup");
@@ -292,36 +323,13 @@
         {"release",         "()V", (void *)android_media_MediaMetadataRetriever_release},
         {"native_finalize", "()V", (void *)android_media_MediaMetadataRetriever_native_finalize},
         {"native_setup",    "()V", (void *)android_media_MediaMetadataRetriever_native_setup},
+        {"native_init",     "()V", (void *)android_media_MediaMetadataRetriever_native_init},
 };
 
-// Register native mehtods with Android runtime environment
+// This function only registers the native methods, and is called from
+// JNI_OnLoad in android_media_MediaPlayer.cpp
 int register_android_media_MediaMetadataRetriever(JNIEnv *env)
 {
-    static const char* const kClassPathName = "android/media/MediaMetadataRetriever";
-    jclass clazz = env->FindClass(kClassPathName);
-    if (clazz == NULL) {
-        LOGE("Can't find class: %s", kClassPathName);
-        return -1;
-    }
-
-    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
-    if (fields.context == NULL) {
-        LOGE("Can't find MediaMetadataRetriever.mNativeContext");
-        return -1;
-    }
-
-    fields.bitmapClazz = env->FindClass("android/graphics/Bitmap");
-    if (fields.bitmapClazz == NULL) {
-        LOGE("Bitmap class is not found");
-        return -1;
-    }
-
-    fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(IZ[B)V");
-    if (fields.bitmapConstructor == NULL) {
-        LOGE("Bitmap constructor is not found");
-        return -1;
-    }
-
     return AndroidRuntime::registerNativeMethods
-    (env, kClassPathName, nativeMethods, NELEM(nativeMethods));
+        (env, kClassPathName, nativeMethods, NELEM(nativeMethods));
 }
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index d26d039..df98de5 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -511,6 +511,51 @@
     return media_player->getMetadata(update_only, apply_filter, metadata) == OK;
 }
 
+// This function gets some field IDs, which in turn causes class initialization.
+// It is called from a static block in MediaPlayer, which won't run until the
+// first time an instance of this class is used.
+static void
+android_media_MediaPlayer_native_init(JNIEnv *env)
+{
+    jclass clazz;
+
+    clazz = env->FindClass("android/media/MediaPlayer");
+    if (clazz == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaPlayer");
+        return;
+    }
+
+    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+    if (fields.context == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.mNativeContext");
+        return;
+    }
+
+    fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
+                                               "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+    if (fields.post_event == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.postEventFromNative");
+        return;
+    }
+
+    fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
+    if (fields.surface == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaPlayer.mSurface");
+        return;
+    }
+
+    jclass surface = env->FindClass("android/view/Surface");
+    if (surface == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/view/Surface");
+        return;
+    }
+
+    fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
+    if (fields.surface_native == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find Surface.mSurface");
+        return;
+    }
+}
 
 static void
 android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
@@ -576,53 +621,16 @@
     {"native_invoke",       "(Landroid/os/Parcel;Landroid/os/Parcel;)I",(void *)android_media_MediaPlayer_invoke},
     {"native_setMetadataFilter", "(Landroid/os/Parcel;)I",      (void *)android_media_MediaPlayer_setMetadataFilter},
     {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z",          (void *)android_media_MediaPlayer_getMetadata},
+    {"native_init",         "()V",                              (void *)android_media_MediaPlayer_native_init},
     {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},
     {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},
 };
 
 static const char* const kClassPathName = "android/media/MediaPlayer";
 
+// This function only registers the native methods
 static int register_android_media_MediaPlayer(JNIEnv *env)
 {
-    jclass clazz;
-
-    clazz = env->FindClass("android/media/MediaPlayer");
-    if (clazz == NULL) {
-        LOGE("Can't find android/media/MediaPlayer");
-        return -1;
-    }
-
-    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
-    if (fields.context == NULL) {
-        LOGE("Can't find MediaPlayer.mNativeContext");
-        return -1;
-    }
-
-    fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
-                                               "(Ljava/lang/Object;IIILjava/lang/Object;)V");
-    if (fields.post_event == NULL) {
-        LOGE("Can't find MediaPlayer.postEventFromNative");
-        return -1;
-    }
-
-    fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
-    if (fields.surface == NULL) {
-        LOGE("Can't find MediaPlayer.mSurface");
-        return -1;
-    }
-
-    jclass surface = env->FindClass("android/view/Surface");
-    if (surface == NULL) {
-        LOGE("Can't find android/view/Surface");
-        return -1;
-    }
-
-    fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
-    if (fields.surface_native == NULL) {
-        LOGE("Can't find Surface fields");
-        return -1;
-    }
-
     return AndroidRuntime::registerNativeMethods(env,
                 "android/media/MediaPlayer", gMethods, NELEM(gMethods));
 }
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 304f521..cad65b3 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -371,6 +371,53 @@
     }
 }
 
+// This function gets some field IDs, which in turn causes class initialization.
+// It is called from a static block in MediaRecorder, which won't run until the
+// first time an instance of this class is used.
+static void
+android_media_MediaRecorder_native_init(JNIEnv *env)
+{
+    jclass clazz;
+
+    clazz = env->FindClass("android/media/MediaRecorder");
+    if (clazz == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaRecorder");
+        return;
+    }
+
+    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+    if (fields.context == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaRecorder.mNativeContext");
+        return;
+    }
+
+    fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
+    if (fields.surface == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaRecorder.mSurface");
+        return;
+    }
+
+    jclass surface = env->FindClass("android/view/Surface");
+    if (surface == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/view/Surface");
+        return;
+    }
+
+    fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
+    if (fields.surface_native == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find Surface.mSurface");
+        return;
+    }
+
+    fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
+                                               "(Ljava/lang/Object;IIILjava/lang/Object;)V");
+    if (fields.post_event == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "MediaRecorder.postEventFromNative");
+        return;
+    }
+}
+
+
 static void
 android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
 {
@@ -418,55 +465,19 @@
     {"getMaxAmplitude",      "()I",                             (void *)android_media_MediaRecorder_native_getMaxAmplitude},
     {"start",                "()V",                             (void *)android_media_MediaRecorder_start},
     {"stop",                 "()V",                             (void *)android_media_MediaRecorder_stop},
-    {"native_reset",                "()V",                             (void *)android_media_MediaRecorder_native_reset},
+    {"native_reset",         "()V",                             (void *)android_media_MediaRecorder_native_reset},
     {"release",              "()V",                             (void *)android_media_MediaRecorder_release},
+    {"native_init",          "()V",                             (void *)android_media_MediaRecorder_native_init},
     {"native_setup",         "(Ljava/lang/Object;)V",           (void *)android_media_MediaRecorder_native_setup},
     {"native_finalize",      "()V",                             (void *)android_media_MediaRecorder_native_finalize},
 };
 
 static const char* const kClassPathName = "android/media/MediaRecorder";
 
+// This function only registers the native methods, and is called from
+// JNI_OnLoad in android_media_MediaPlayer.cpp
 int register_android_media_MediaRecorder(JNIEnv *env)
 {
-    jclass clazz;
-
-    clazz = env->FindClass("android/media/MediaRecorder");
-    if (clazz == NULL) {
-        LOGE("Can't find android/media/MediaRecorder");
-        return -1;
-    }
-
-    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
-    if (fields.context == NULL) {
-        LOGE("Can't find MediaRecorder.mNativeContext");
-        return -1;
-    }
-
-    fields.surface = env->GetFieldID(clazz, "mSurface", "Landroid/view/Surface;");
-    if (fields.surface == NULL) {
-        LOGE("Can't find MediaRecorder.mSurface");
-        return -1;
-    }
-
-    jclass surface = env->FindClass("android/view/Surface");
-    if (surface == NULL) {
-        LOGE("Can't find android/view/Surface");
-        return -1;
-    }
-
-    fields.surface_native = env->GetFieldID(surface, "mSurface", "I");
-    if (fields.surface_native == NULL) {
-        LOGE("Can't find Surface fields");
-        return -1;
-    }
-
-    fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
-                                               "(Ljava/lang/Object;IIILjava/lang/Object;)V");
-    if (fields.post_event == NULL) {
-        LOGE("Can't find MediaRecorder.postEventFromNative");
-        return -1;
-    }
-
     return AndroidRuntime::registerNativeMethods(env,
                 "android/media/MediaRecorder", gMethods, NELEM(gMethods));
 }
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 8764a70..97de486 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -241,6 +241,27 @@
     return array;
 }
 
+// This function gets a field ID, which in turn causes class initialization.
+// It is called from a static block in MediaScanner, which won't run until the
+// first time an instance of this class is used.
+static void
+android_media_MediaScanner_native_init(JNIEnv *env)
+{
+     jclass clazz;
+
+    clazz = env->FindClass("android/media/MediaScanner");
+    if (clazz == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find android/media/MediaScanner");
+        return;
+    }
+
+    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
+    if (fields.context == NULL) {
+        jniThrowException(env, "java/lang/RuntimeException", "Can't find MediaScanner.mNativeContext");
+        return;
+    }
+}
+
 static void
 android_media_MediaScanner_native_setup(JNIEnv *env, jobject thiz)
 {
@@ -275,28 +296,17 @@
                                                         (void *)android_media_MediaScanner_processFile},
     {"setLocale",         "(Ljava/lang/String;)V",      (void *)android_media_MediaScanner_setLocale},
     {"extractAlbumArt",   "(Ljava/io/FileDescriptor;)[B",     (void *)android_media_MediaScanner_extractAlbumArt},
+    {"native_init",        "()V",                      (void *)android_media_MediaScanner_native_init},
     {"native_setup",        "()V",                      (void *)android_media_MediaScanner_native_setup},
     {"native_finalize",     "()V",                      (void *)android_media_MediaScanner_native_finalize},
 };
 
 static const char* const kClassPathName = "android/media/MediaScanner";
 
+// This function only registers the native methods, and is called from
+// JNI_OnLoad in android_media_MediaPlayer.cpp
 int register_android_media_MediaScanner(JNIEnv *env)
 {
-    jclass clazz;
-
-    clazz = env->FindClass("android/media/MediaScanner");
-    if (clazz == NULL) {
-        LOGE("Can't find android/media/MediaScanner");
-        return -1;
-    }
-
-    fields.context = env->GetFieldID(clazz, "mNativeContext", "I");
-    if (fields.context == NULL) {
-        LOGE("Can't find MediaScanner.mNativeContext");
-        return -1;
-    }
-
     return AndroidRuntime::registerNativeMethods(env,
                 "android/media/MediaScanner", gMethods, NELEM(gMethods));
 }
diff --git a/media/jni/android_media_ResampleInputStream.cpp b/media/jni/android_media_ResampleInputStream.cpp
index 0247cdb..f248557 100644
--- a/media/jni/android_media_ResampleInputStream.cpp
+++ b/media/jni/android_media_ResampleInputStream.cpp
@@ -128,13 +128,6 @@
 int register_android_media_ResampleInputStream(JNIEnv *env)
 {
     const char* const kClassPathName = "android/media/ResampleInputStream";
-    jclass clazz;
-
-    clazz = env->FindClass(kClassPathName);
-    if (clazz == NULL) {
-        LOGE("Can't find %s", kClassPathName);
-        return -1;
-    }
 
     return AndroidRuntime::registerNativeMethods(env,
             kClassPathName, gMethods, NELEM(gMethods));
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 67f3816..77ba914 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -307,36 +307,42 @@
         mEverStored = new File(mBaseStateDir, "processed");
         File tempProcessedFile = new File(mBaseStateDir, "processed.new");
         try {
-            RandomAccessFile temp = new RandomAccessFile(tempProcessedFile, "rw");
-            mEverStoredStream = new RandomAccessFile(mEverStored, "r");
+            // If there are previous contents, parse them out then start a new
+            // file to continue the recordkeeping.
+            if (mEverStored.exists()) {
+                RandomAccessFile temp = new RandomAccessFile(tempProcessedFile, "rw");
+                mEverStoredStream = new RandomAccessFile(mEverStored, "r");
 
-            // parse its existing contents
-            mEverStoredStream.seek(0);
-            temp.seek(0);
-            try {
-                while (true) {
-                    PackageInfo info;
-                    String pkg = mEverStoredStream.readUTF();
-                    try {
-                        info = mPackageManager.getPackageInfo(pkg, 0);
-                        mEverStoredApps.add(pkg);
-                        temp.writeUTF(pkg);
-                        if (DEBUG) Log.v(TAG, "   + " + pkg);
-                    } catch (NameNotFoundException e) {
-                        // nope, this package was uninstalled; don't include it
-                        if (DEBUG) Log.v(TAG, "   - " + pkg);
+                // parse its existing contents
+                mEverStoredStream.seek(0);
+                temp.seek(0);
+                try {
+                    while (true) {
+                        PackageInfo info;
+                        String pkg = mEverStoredStream.readUTF();
+                        try {
+                            info = mPackageManager.getPackageInfo(pkg, 0);
+                            mEverStoredApps.add(pkg);
+                            temp.writeUTF(pkg);
+                            if (DEBUG) Log.v(TAG, "   + " + pkg);
+                        } catch (NameNotFoundException e) {
+                            // nope, this package was uninstalled; don't include it
+                            if (DEBUG) Log.v(TAG, "   - " + pkg);
+                        }
                     }
+                } catch (EOFException e) {
+                    // now we're at EOF
                 }
-            } catch (EOFException e) {
-                // now we're at EOF
-            }
 
-            // Once we've rewritten the backup history log, atomically replace the
-            // old one with the new one then reopen the file for continuing use.
-            temp.close();
-            mEverStoredStream.close();
-            tempProcessedFile.renameTo(mEverStored);
+                // Once we've rewritten the backup history log, atomically replace the
+                // old one with the new one then reopen the file for continuing use.
+                temp.close();
+                mEverStoredStream.close();
+                tempProcessedFile.renameTo(mEverStored);
+            }
+            // This will create the file if it doesn't exist
             mEverStoredStream = new RandomAccessFile(mEverStored, "rwd");
+            mEverStoredStream.seek(mEverStoredStream.length());
         } catch (IOException e) {
             Log.e(TAG, "Unable to open known-stored file!");
             mEverStoredStream = null;
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index aac7124..5dad8d0 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -96,7 +96,7 @@
     private Vibrator mVibrator = new Vibrator();
 
     // adb
-    private int mBatteryPlugged;
+    private boolean mUsbConnected;
     private boolean mAdbEnabled = false;
     private boolean mAdbNotificationShown = false;
     private Notification mAdbNotification;
@@ -310,8 +310,11 @@
                     mBatteryFull = batteryFull;
                     updateLights();
                 }
-                
-                mBatteryPlugged = intent.getIntExtra("plugged", 0);
+            } else if (action.equals(Intent.ACTION_UMS_CONNECTED)) {
+                mUsbConnected = true;
+                updateAdbNotification();
+            } else if (action.equals(Intent.ACTION_UMS_DISCONNECTED)) {
+                mUsbConnected = false;
                 updateAdbNotification();
             } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
                     || action.equals(Intent.ACTION_PACKAGE_RESTARTED)) {
@@ -380,6 +383,8 @@
         // register for battery changed notifications
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+        filter.addAction(Intent.ACTION_UMS_CONNECTED);
+        filter.addAction(Intent.ACTION_UMS_DISCONNECTED);
         filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
         mContext.registerReceiver(mIntentReceiver, filter);
@@ -954,7 +959,7 @@
     // security feature that we don't want people customizing the platform
     // to accidentally lose.
     private void updateAdbNotification() {
-        if (mAdbEnabled && mBatteryPlugged == BatteryManager.BATTERY_PLUGGED_USB) {
+        if (mAdbEnabled && mUsbConnected) {
             if ("0".equals(SystemProperties.get("persist.adb.notify"))) {
                 return;
             }
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index a3c3436..447e9fa 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -765,15 +765,17 @@
         switch (type)
         {
             case PowerManager.FULL_WAKE_LOCK:
-                return "FULL_WAKE_LOCK         ";
+                return "FULL_WAKE_LOCK                ";
             case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
-                return "SCREEN_BRIGHT_WAKE_LOCK";
+                return "SCREEN_BRIGHT_WAKE_LOCK       ";
             case PowerManager.SCREEN_DIM_WAKE_LOCK:
-                return "SCREEN_DIM_WAKE_LOCK   ";
+                return "SCREEN_DIM_WAKE_LOCK          ";
             case PowerManager.PARTIAL_WAKE_LOCK:
-                return "PARTIAL_WAKE_LOCK      ";
+                return "PARTIAL_WAKE_LOCK             ";
+            case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:
+                return "PROXIMITY_SCREEN_OFF_WAKE_LOCK";
             default:
-                return "???                    ";
+                return "???                           ";
         }
     }
 
diff --git a/services/jni/com_android_server_HardwareService.cpp b/services/jni/com_android_server_HardwareService.cpp
index b0aab59..22d4bd8 100644
--- a/services/jni/com_android_server_HardwareService.cpp
+++ b/services/jni/com_android_server_HardwareService.cpp
@@ -133,7 +133,7 @@
 
 static JNINativeMethod method_table[] = {
     { "init_native", "()I", (void*)init_native },
-    { "finalize_native", "(I)V", (void*)init_native },
+    { "finalize_native", "(I)V", (void*)finalize_native },
     { "setLight_native", "(IIIIII)V", (void*)setLight_native },
     { "vibratorOn", "(J)V", (void*)vibratorOn },
     { "vibratorOff", "()V", (void*)vibratorOff }
diff --git a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
index 44958e9..4b88057 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SignalToneUtil.java
@@ -35,7 +35,12 @@
     static public final int IS95_CONST_IR_ALERT_MED = 0;
     static public final int IS95_CONST_IR_ALERT_HIGH = 1;
     static public final int IS95_CONST_IR_ALERT_LOW = 2;
-    static public final int TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN = 255;
+
+    // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal,
+    // set TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN to 0 to avoid
+    // the alert pitch to be involved in hash calculation for
+    // signal type other than IS54B.
+    static public final int TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN = 0;
 
     // public final int int IS95_CONST_IR_SIGNAL_TYPE;
     static public final int IS95_CONST_IR_SIG_ISDN_NORMAL = 0;
@@ -81,6 +86,15 @@
                 (alertPitch < 0) || (signal > 256) || (signal < 0)) {
             return new Integer(CDMA_INVALID_TONE);
         }
+        // Based on 3GPP2 C.S0005-E, seciton 3.7.5.5 Signal,
+        // the alert pitch field is ignored by the mobile station unless
+        // SIGNAL_TYPE is '10',IS-54B Alerting.
+        // Set alert pitch to TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN
+        // so the alert pitch is not involved in hash calculation
+        // when signal type is not IS-54B.
+        if (signalType != IS95_CONST_IR_SIGNAL_IS54B) {
+            alertPitch = TAPIAMSSCDMA_SIGNAL_PITCH_UNKNOWN;
+        }
         return new Integer(signalType * 256 * 256 + alertPitch * 256 + signal);
     }
 
diff --git a/test-runner/android/test/AndroidTestRunner.java b/test-runner/android/test/AndroidTestRunner.java
index 79cedb0..00440b43 100644
--- a/test-runner/android/test/AndroidTestRunner.java
+++ b/test-runner/android/test/AndroidTestRunner.java
@@ -158,16 +158,18 @@
             mTestResult.addListener(testListener);
         }
 
+        Context testContext = mInstrumentation.getContext();
         for (TestCase testCase : mTestCases) {
-            setContextIfAndroidTestCase(testCase, mContext);
+            setContextIfAndroidTestCase(testCase, mContext, testContext);
             setInstrumentationIfInstrumentationTestCase(testCase, mInstrumentation);
             testCase.run(mTestResult);
         }
     }
 
-    private void setContextIfAndroidTestCase(Test test, Context context) {
+    private void setContextIfAndroidTestCase(Test test, Context context, Context testContext) {
         if (AndroidTestCase.class.isAssignableFrom(test.getClass())) {
             ((AndroidTestCase) test).setContext(context);
+            ((AndroidTestCase) test).setTestContext(testContext);
         }
     }
 
diff --git a/test-runner/android/test/TestRunner.java b/test-runner/android/test/TestRunner.java
index efa2480..012df35 100644
--- a/test-runner/android/test/TestRunner.java
+++ b/test-runner/android/test/TestRunner.java
@@ -39,7 +39,7 @@
  * and you probably will not need to instantiate, extend, or call this
  * class yourself. See the full {@link android.test} package description
  * to learn more about testing Android applications.
- * 
+ *
  * {@hide} Not needed for 1.0 SDK.
  */
 public class TestRunner implements PerformanceTestCase.Intermediates {
@@ -84,6 +84,7 @@
             super();
         }
 
+        @Override
         public void run(TestResult result) {
             result.addListener(this);
             super.run(result);
@@ -301,7 +302,7 @@
                     if (mMode == PERFORMANCE) {
                         runInPerformanceMode(test, className, false, className);
                     } else if (mMode == PROFILING) {
-                        //Need a way to mark a test to be run in profiling mode or not. 
+                        //Need a way to mark a test to be run in profiling mode or not.
                         startProfiling();
                         test.run();
                         finishProfiling();
@@ -337,6 +338,7 @@
                         AndroidTestCase testcase = (AndroidTestCase) test;
                         try {
                             testcase.setContext(mContext);
+                            testcase.setTestContext(mContext);
                         } catch (Exception ex) {
                             Log.i("TestHarness", ex.toString());
                         }
@@ -700,7 +702,7 @@
             }
         } catch (ClassNotFoundException e) {
             return 1; // this gets the count right, because either this test
-            // is missing, and it will fail when run or it is a single Junit test to be run. 
+            // is missing, and it will fail when run or it is a single Junit test to be run.
         }
         return 0;
     }
diff --git a/tests/CoreTests/android/core/TestEventHandler.java b/tests/CoreTests/android/core/TestEventHandler.java
index 4cfcade..45f2f69 100644
--- a/tests/CoreTests/android/core/TestEventHandler.java
+++ b/tests/CoreTests/android/core/TestEventHandler.java
@@ -497,7 +497,7 @@
      * SSL certificate error callback. Handles SSL error(s) on the way
      * up to the user.
      */
-    public void handleSslErrorRequest(SslError error) {
+    public boolean handleSslErrorRequest(SslError error) {
       int primaryError = error.getPrimaryError();
 
       if (Config.LOGV) {
@@ -527,6 +527,9 @@
 
       if (expectSslErrors == -1) // && expectSslCertificate == certificate?
         expects[TEST_SSL_CERTIFICATE_ERROR] = false;
+
+      // return false so that we won't block the thread
+      return false;
     }
 
     /**
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
index de39800..71d9758 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
@@ -1,5 +1,7 @@
 package com.android.dumprendertree;
 
+import android.app.Activity;
+import android.content.Intent;
 import android.os.Handler;
 import android.os.Message;
 import android.test.ActivityInstrumentationTestCase2;
@@ -33,7 +35,7 @@
     }
 
     public void runReliabilityTest() throws Throwable {
-        ReliabilityTestActivity activity = getActivity();
+//        ReliabilityTestActivity activity = getActivity();
         LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner)getInstrumentation();
 
         File testListFile = new File(TEST_LIST_FILE);
@@ -54,6 +56,8 @@
         boolean timeoutFlag = false;
         long start, elapsed;
 
+        Intent intent = new Intent(runner.getContext(), ReliabilityTestActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         //read from BufferedReader instead of populating a list in advance,
         //this will avoid excessive memory usage in case of a large list
         while((url = listReader.readLine()) != null) {
@@ -63,6 +67,8 @@
             start = System.currentTimeMillis();
             Log.v(LOGTAG, "Testing URL: " + url);
             FsUtils.updateTestStatus(TEST_STATUS_FILE, url);
+            ReliabilityTestActivity activity = (ReliabilityTestActivity)runner.startActivitySync(
+                    intent);
             activity.reset();
             //use message to send new URL to avoid interacting with
             //WebView in non-UI thread
@@ -88,12 +94,13 @@
             if(runner.mLogtime) {
                 writeLoadTime(url, activity.getPageLoadTime());
             }
+            activity.finish();
             System.runFinalization();
             System.gc();
             System.gc();
         }
         FsUtils.updateTestStatus(TEST_STATUS_FILE, TEST_DONE);
-        activity.finish();
+//        activity.finish();
         listReader.close();
     }
 
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
index 5ddd0b3..995c129 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
@@ -122,8 +122,10 @@
 
     @Override
     protected void onDestroy() {
-        Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
         super.onDestroy();
+        Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
+        webView.clearCache(true);
+        webView.destroy();
     }
 
     private boolean isPageDone() {
@@ -270,8 +272,7 @@
         }
 
         public void run() {
-            if (initialStartCount == pageStartCount) {
-                //perform cleanup
+            if (initialStartCount == pageStartCount && !isPageDone()) {
                 handler.removeMessages(MSG_TIMEOUT);
                 webView.stopLoading();
                 handler.postDelayed(pageDoneRunner, manualDelay);
diff --git a/tests/backup/test_backup.sh b/tests/backup/test_backup.sh
index dbf9ed2..dd3907c 100755
--- a/tests/backup/test_backup.sh
+++ b/tests/backup/test_backup.sh
@@ -1,27 +1,54 @@
 #!/bin/bash
 
+# 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.
+
+
+ADB_OPTS="$@"
+
+#FIXME: what was this for?
 #adb kill-server
 
+# run adb as root so we can poke at com.android.backuptest's data
+root_status=$(adb $ADB_OPTS root)
+if [ "x$root_status" != "xadbd is already running as root" ]; then
+    sleep 2
+    adb $ADB_OPTS 'wait-for-device'
+fi
+
+# show commands as we go
+set -x
+
 # set the transport
-adb shell bmgr transport 1
+adb $ADB_OPTS shell bmgr transport com.google.android.backup/.BackupTransportService
 
 # load up the three files
-adb shell "rm /data/data/com.android.backuptest/files/* ; \
-           mkdir /data/data/com.android.backuptest ; \
-           mkdir /data/data/com.android.backuptest/files ; \
-           mkdir /data/data/com.android.backuptest/shared_prefs ; \
-           echo -n \"<map><int name=\\\"pref\\\" value=\\\"1\\\" /></map>\" > /data/data/com.android.backuptest/shared_prefs/raw.xml ; \
-           echo -n first file > /data/data/com.android.backuptest/files/file.txt ; \
-           echo -n asdf > /data/data/com.android.backuptest/files/another_file.txt ; \
-           echo -n 3 > /data/data/com.android.backuptest/files/3.txt ; \
-           echo -n "" > /data/data/com.android.backuptest/files/empty.txt ; \
+adb $ADB_OPTS shell \
+   "rm /data/data/com.android.backuptest/files/* ; \
+    mkdir /data/data/com.android.backuptest ; \
+    mkdir /data/data/com.android.backuptest/files ; \
+    mkdir /data/data/com.android.backuptest/shared_prefs ; \
+    echo -n \"<map><int name=\\\"pref\\\" value=\\\"1\\\" /></map>\" > /data/data com.android.backuptest/shared_prefs/raw.xml ; \
+    echo -n first file > /data/data/com.android.backuptest/files/file.txt ; \
+    echo -n asdf > /data/data/com.android.backuptest/files/another_file.txt ; \
+    echo -n 3 > /data/data/com.android.backuptest/files/3.txt ; \
+    echo -n "" > /data/data/com.android.backuptest/files/empty.txt ; \
 "
 
 # say that the data has changed
-adb shell bmgr backup com.android.backuptest
+adb $ADB_OPTS shell bmgr backup com.android.backuptest
 
 # run the backup
-adb shell bmgr run
-
-
+adb $ADB_OPTS shell bmgr run
 
diff --git a/tests/backup/test_restore.sh b/tests/backup/test_restore.sh
index ccf29cf..8de70cb 100755
--- a/tests/backup/test_restore.sh
+++ b/tests/backup/test_restore.sh
@@ -1,8 +1,25 @@
 #!/bin/bash
 
+# 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.
+
+
+ADB_OPTS="$@"
+
 function check_file
 {
-    data=$(adb shell cat /data/data/com.android.backuptest/$1)
+    data=$(adb $ADB_OPTS shell cat /data/data/com.android.backuptest/$1)
     if [ "$data" = "$2" ] ; then
         echo "$1 has correct value [$2]"
     else
@@ -12,24 +29,39 @@
     fi
 }
 
+# run adb as root so we can poke at com.android.backuptest's data
+root_status=$(adb $ADB_OPTS root)
+if [ "x$root_status" != "xadbd is already running as root" ]; then
+    echo -n "Restarting adb as root..."
+    sleep 2
+    adb $ADB_OPTS 'wait-for-device'
+    echo done.
+fi
+
 # delete the old data
 echo --- Previous files
-adb shell "ls -l /data/data/com.android.backuptest/files"
-adb shell "rm /data/data/com.android.backuptest/files/*"
+adb $ADB_OPTS shell "ls -l /data/data/com.android.backuptest/files"
+adb $ADB_OPTS shell "rm /data/data/com.android.backuptest/files/*"
 echo --- Previous shared_prefs
-adb shell "ls -l /data/data/com.android.backuptest/shared_prefs"
-adb shell "rm /data/data/com.android.backuptest/shared_prefs/*"
+adb $ADB_OPTS shell "ls -l /data/data/com.android.backuptest/shared_prefs"
+adb $ADB_OPTS shell "rm /data/data/com.android.backuptest/shared_prefs/*"
 echo --- Erased files and shared_prefs
-adb shell "ls -l /data/data/com.android.backuptest/files"
-adb shell "ls -l /data/data/com.android.backuptest/shared_prefs"
+adb $ADB_OPTS shell "ls -l /data/data/com.android.backuptest/files"
+adb $ADB_OPTS shell "ls -l /data/data/com.android.backuptest/shared_prefs"
 echo ---
 
 echo
 echo
 echo
 
+# FIXME: there's probably a smarter way to do this
+# FIXME: if we can get the android ID, that's probably the safest thing to do
+# pick the most recent set and restore from it
+restore_set=$(adb $ADB_OPTS shell bmgr list sets | head -n1 | awk '{print $1}')
+
 # run the restore
-adb shell bmgr restore 0
+printf "Restoring from set %d (hex: 0x%x)\n" $restore_set $restore_set
+adb $ADB_OPTS shell bmgr restore $restore_set
 
 echo
 echo
@@ -46,8 +78,9 @@
 echo
 echo
 echo --- Restored files
-adb shell "ls -l /data/data/com.android.backuptest/files"
+adb $ADB_OPTS shell "ls -l /data/data/com.android.backuptest/files"
 echo --- Restored shared_prefs
-adb shell "ls -l /data/data/com.android.backuptest/shared_prefs"
+adb $ADB_OPTS shell "ls -l /data/data/com.android.backuptest/shared_prefs"
 echo ---
 echo
+
diff --git a/tools/aidl/AST.cpp b/tools/aidl/AST.cpp
index 1856cb9..752ef7c 100755
--- a/tools/aidl/AST.cpp
+++ b/tools/aidl/AST.cpp
@@ -6,6 +6,10 @@
 {
     int m = mod & mask;
 
+    if (m & OVERRIDE) {
+        fprintf(to, "@Override ");
+    }
+
     if ((m & SCOPE_MASK) == PUBLIC) {
         fprintf(to, "public ");
     }
@@ -79,7 +83,7 @@
     if (this->comment.length() != 0) {
         fprintf(to, "%s\n", this->comment.c_str());
     }
-    WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL);
+    WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL | OVERRIDE);
     fprintf(to, "%s %s", this->variable->type->QualifiedName().c_str(),
             this->variable->name.c_str());
     if (this->value.length() != 0) {
@@ -674,7 +678,7 @@
         fprintf(to, "%s\n", this->comment.c_str());
     }
 
-    WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL);
+    WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL | OVERRIDE);
 
     if (this->returnType != NULL) {
         string dim;
diff --git a/tools/aidl/AST.h b/tools/aidl/AST.h
index aec2164..3156356 100755
--- a/tools/aidl/AST.h
+++ b/tools/aidl/AST.h
@@ -22,6 +22,8 @@
     FINAL           = 0x00000020,
     ABSTRACT        = 0x00000040,
 
+    OVERRIDE        = 0x00000100,
+
     ALL_MODIFIERS   = 0xffffffff
 };
 
diff --git a/tools/aidl/generate_java.cpp b/tools/aidl/generate_java.cpp
index da20d1f..0f18132 100644
--- a/tools/aidl/generate_java.cpp
+++ b/tools/aidl/generate_java.cpp
@@ -104,7 +104,7 @@
     this->transact_reply = new Variable(PARCEL_TYPE, "reply");
     this->transact_flags = new Variable(INT_TYPE, "flags");
     Method* onTransact = new Method;
-        onTransact->modifiers = PUBLIC;
+        onTransact->modifiers = PUBLIC | OVERRIDE;
         onTransact->returnType = BOOLEAN_TYPE;
         onTransact->name = "onTransact";
         onTransact->parameters.push_back(this->transact_code);