Merge "Add EXTRA_PARTIAL_RESULTS so that clients can enable receiving results via onPartialResults()"
diff --git a/Android.mk b/Android.mk
index ec6f96b..7bb5b5f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -33,6 +33,9 @@
 # FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
 LOCAL_SRC_FILES := $(call find-other-java-files,$(FRAMEWORKS_BASE_SUBDIRS))
 
+# EventLogTags files.
+LOCAL_SRC_FILES += core/java/android/content/EventLogTags.logtags
+
 # The following filters out code we are temporarily not including at all.
 # TODO: Move AWT and beans (and associated harmony code) back into libcore.
 # TODO: Maybe remove javax.microedition entirely?
@@ -367,6 +370,8 @@
 
 sample_dir := development/samples
 
+# the list here should match the list of samples included in the sdk samples package
+# (see development/build/sdk.atree)
 web_docs_sample_code_flags := \
 		-hdf android.hasSamples 1 \
 		-samplecode $(sample_dir)/ApiDemos \
@@ -377,6 +382,8 @@
 		            resources/samples/BusinessCard "Business Card" \
 		-samplecode $(sample_dir)/ContactManager \
 		            resources/samples/ContactManager "Contact Manager" \
+                -samplecode $(sample_dir)/CubeLiveWallpaper \
+                            resources/samples/CubeLiveWallpaper "Live Wallpaper" \
 		-samplecode $(sample_dir)/Home \
 		            resources/samples/Home "Home" \
 		-samplecode $(sample_dir)/JetBoy \
@@ -387,6 +394,8 @@
 		            resources/samples/MultiResolution "Multiple Resolutions" \
 		-samplecode $(sample_dir)/NotePad \
 		            resources/samples/NotePad "Note Pad" \
+                -samplecode $(sample_dir)/SampleSyncAdapter \
+                            resources/samples/SampleSyncAdapter "Sample Sync Adapter" \
 		-samplecode $(sample_dir)/SearchableDictionary \
 		            resources/samples/SearchableDictionary "Searchable Dictionary" \
 		-samplecode $(sample_dir)/Snake \
diff --git a/common/java/com/android/common/Patterns.java b/common/java/com/android/common/Patterns.java
index 24a18c0..71c3a5e 100644
--- a/common/java/com/android/common/Patterns.java
+++ b/common/java/com/android/common/Patterns.java
@@ -25,87 +25,87 @@
 public class Patterns {
     /**
      *  Regular expression pattern to match all IANA top-level domains.
-     *  List accurate as of 2007/06/15.  List taken from:
+     *  List accurate as of 2010/02/05.  List taken from:
      *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
-     *  This pattern is auto-generated by //device/tools/make-iana-tld-pattern.py
+     *  This pattern is auto-generated by development/tools/make-iana-tld-pattern.py
      */
-    public static final Pattern TOP_LEVEL_DOMAIN
-        = Pattern.compile(
-                "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
-                + "|(biz|b[abdefghijmnorstvwyz])"
-                + "|(cat|com|coop|c[acdfghiklmnoruvxyz])"
-                + "|d[ejkmoz]"
-                + "|(edu|e[cegrstu])"
-                + "|f[ijkmor]"
-                + "|(gov|g[abdefghilmnpqrstuwy])"
-                + "|h[kmnrtu]"
-                + "|(info|int|i[delmnoqrst])"
-                + "|(jobs|j[emop])"
-                + "|k[eghimnrwyz]"
-                + "|l[abcikrstuvy]"
-                + "|(mil|mobi|museum|m[acdghklmnopqrstuvwxyz])"
-                + "|(name|net|n[acefgilopruz])"
-                + "|(org|om)"
-                + "|(pro|p[aefghklmnrstwy])"
-                + "|qa"
-                + "|r[eouw]"
-                + "|s[abcdeghijklmnortuvyz]"
-                + "|(tel|travel|t[cdfghjklmnoprtvwz])"
-                + "|u[agkmsyz]"
-                + "|v[aceginu]"
-                + "|w[fs]"
-                + "|y[etu]"
-                + "|z[amw])");
+    public static final Pattern TOP_LEVEL_DOMAIN = Pattern.compile(
+        "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
+        + "|(biz|b[abdefghijmnorstvwyz])"
+        + "|(cat|com|coop|c[acdfghiklmnoruvxyz])"
+        + "|d[ejkmoz]"
+        + "|(edu|e[cegrstu])"
+        + "|f[ijkmor]"
+        + "|(gov|g[abdefghilmnpqrstuwy])"
+        + "|h[kmnrtu]"
+        + "|(info|int|i[delmnoqrst])"
+        + "|(jobs|j[emop])"
+        + "|k[eghimnprwyz]"
+        + "|l[abcikrstuvy]"
+        + "|(mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])"
+        + "|(name|net|n[acefgilopruz])"
+        + "|(org|om)"
+        + "|(pro|p[aefghklmnrstwy])"
+        + "|qa"
+        + "|r[eosuw]"
+        + "|s[abcdeghijklmnortuvyz]"
+        + "|(tel|travel|t[cdfghjklmnoprtvwz])"
+        + "|u[agksyz]"
+        + "|v[aceginu]"
+        + "|w[fs]"
+        + "|(xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)"
+        + "|y[etu]"
+        + "|z[amw])");
 
     /**
      *  Regular expression pattern to match RFC 1738 URLs
-     *  List accurate as of 2007/06/15.  List taken from:
+     *  List accurate as of 2010/02/05.  List taken from:
      *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
-     *  This pattern is auto-generated by //device/tools/make-iana-tld-pattern.py
+     *  This pattern is auto-generated by development/tools/make-iana-tld-pattern.py
      */
-    public static final Pattern WEB_URL
-        = Pattern.compile(
-            "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
-            + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
-            + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
-            + "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+"   // named host
-            + "(?:"   // plus top level domain
-            + "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
-            + "|(?:biz|b[abdefghijmnorstvwyz])"
-            + "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
-            + "|d[ejkmoz]"
-            + "|(?:edu|e[cegrstu])"
-            + "|f[ijkmor]"
-            + "|(?:gov|g[abdefghilmnpqrstuwy])"
-            + "|h[kmnrtu]"
-            + "|(?:info|int|i[delmnoqrst])"
-            + "|(?:jobs|j[emop])"
-            + "|k[eghimnrwyz]"
-            + "|l[abcikrstuvy]"
-            + "|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])"
-            + "|(?:name|net|n[acefgilopruz])"
-            + "|(?:org|om)"
-            + "|(?:pro|p[aefghklmnrstwy])"
-            + "|qa"
-            + "|r[eouw]"
-            + "|s[abcdeghijklmnortuvyz]"
-            + "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
-            + "|u[agkmsyz]"
-            + "|v[aceginu]"
-            + "|w[fs]"
-            + "|y[etu]"
-            + "|z[amw]))"
-            + "|(?:(?:25[0-5]|2[0-4]" // or ip address
-            + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
-            + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
-            + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
-            + "|[1-9][0-9]|[0-9])))"
-            + "(?:\\:\\d{1,5})?)" // plus option port number
-            + "(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~"  // plus option query params
-            + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
-            + "(?:\\b|$)"); // and finally, a word boundary or end of
-                            // input.  This is to stop foo.sure from
-                            // matching as foo.su
+    public static final Pattern WEB_URL = Pattern.compile(
+        "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+        + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+        + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+        + "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+"   // named host
+        + "(?:"   // plus top level domain
+        + "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
+        + "|(?:biz|b[abdefghijmnorstvwyz])"
+        + "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
+        + "|d[ejkmoz]"
+        + "|(?:edu|e[cegrstu])"
+        + "|f[ijkmor]"
+        + "|(?:gov|g[abdefghilmnpqrstuwy])"
+        + "|h[kmnrtu]"
+        + "|(?:info|int|i[delmnoqrst])"
+        + "|(?:jobs|j[emop])"
+        + "|k[eghimnprwyz]"
+        + "|l[abcikrstuvy]"
+        + "|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])"
+        + "|(?:name|net|n[acefgilopruz])"
+        + "|(?:org|om)"
+        + "|(?:pro|p[aefghklmnrstwy])"
+        + "|qa"
+        + "|r[eosuw]"
+        + "|s[abcdeghijklmnortuvyz]"
+        + "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
+        + "|u[agksyz]"
+        + "|v[aceginu]"
+        + "|w[fs]"
+        + "|(?:xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-80akhbyknj4f|xn\\-\\-9t4b11yi5a|xn\\-\\-deba0ad|xn\\-\\-g6w251d|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-zckzah)"
+        + "|y[etu]"
+        + "|z[amw]))"
+        + "|(?:(?:25[0-5]|2[0-4]" // or ip address
+        + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]"
+        + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
+        + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+        + "|[1-9][0-9]|[0-9])))"
+        + "(?:\\:\\d{1,5})?)" // plus option port number
+        + "(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~"  // plus option query params
+        + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
+        + "(?:\\b|$)"); // and finally, a word boundary or end of
+                        // input.  This is to stop foo.sure from
+                        // matching as foo.su
 
     public static final Pattern IP_ADDRESS
         = Pattern.compile(
diff --git a/common/tests/src/com/android/common/PatternsTest.java b/common/tests/src/com/android/common/PatternsTest.java
index 7fabe5e..635601e 100644
--- a/common/tests/src/com/android/common/PatternsTest.java
+++ b/common/tests/src/com/android/common/PatternsTest.java
@@ -31,6 +31,20 @@
         t = Patterns.TOP_LEVEL_DOMAIN.matcher("com").matches();
         assertTrue("Missed valid TLD", t);
 
+        // One of the new top level domain.
+        t = Patterns.TOP_LEVEL_DOMAIN.matcher("me").matches();
+        assertTrue("Missed valid TLD", t);
+
+        // One of the new top level test domain.
+        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn--0zwm56d").matches();
+        assertTrue("Missed valid TLD", t);
+
+        t = Patterns.TOP_LEVEL_DOMAIN.matcher("mem").matches();
+        assertFalse("Matched invalid TLD!", t);
+
+        t = Patterns.TOP_LEVEL_DOMAIN.matcher("xn").matches();
+        assertFalse("Matched invalid TLD!", t);
+
         t = Patterns.TOP_LEVEL_DOMAIN.matcher("xer").matches();
         assertFalse("Matched invalid TLD!", t);
     }
@@ -42,6 +56,18 @@
         t = Patterns.WEB_URL.matcher("http://www.google.com").matches();
         assertTrue("Valid URL", t);
 
+        // Google in one of the new top level domain.
+        t = Patterns.WEB_URL.matcher("http://www.google.me").matches();
+        assertTrue("Valid URL", t);
+        t = Patterns.WEB_URL.matcher("google.me").matches();
+        assertTrue("Valid URL", t);
+
+        // Test url in Chinese: http://xn--fsqu00a.xn--0zwm56d
+        t = Patterns.WEB_URL.matcher("http://xn--fsqu00a.xn--0zwm56d").matches();
+        assertTrue("Valid URL", t);
+        t = Patterns.WEB_URL.matcher("xn--fsqu00a.xn--0zwm56d").matches();
+        assertTrue("Valid URL", t);
+
         t = Patterns.WEB_URL.matcher("ftp://www.example.com").matches();
         assertFalse("Matched invalid protocol", t);
 
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 652f405..be15ac9 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -27,6 +27,7 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.Parcelable;
+import android.os.Build;
 import android.util.Log;
 
 import java.io.IOException;
@@ -841,7 +842,9 @@
                     "calling this from your main thread can lead to deadlock");
             Log.e(TAG, "calling this from your main thread can lead to deadlock and/or ANRs",
                     exception);
-            throw exception;
+            if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.FROYO) {
+                throw exception;
+            }
         }
     }
 
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index e3ccd00..7850124 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1788,7 +1788,7 @@
         if (!permissionGranted && isDebuggableMonkeyBuild) {
             // TODO: Skip this check when running automated tests. Replace this
             // with a more general solution.
-            Log.w(TAG, "no credentials permission for usage of " + account + ", "
+            Log.d(TAG, "no credentials permission for usage of " + account + ", "
                     + authTokenType + " by uid " + Binder.getCallingUid()
                     + " but ignoring since this is a monkey build");
             return true;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index b33be23..bdbe341 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -16,6 +16,8 @@
 
 package android.content;
 
+import android.accounts.Account;
+import android.app.ActivityThread;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
@@ -30,8 +32,8 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.text.TextUtils;
-import android.accounts.Account;
 import android.util.Config;
+import android.util.EventLog;
 import android.util.Log;
 
 import java.io.File;
@@ -41,6 +43,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.List;
+import java.util.Random;
 import java.util.ArrayList;
 
 
@@ -163,6 +166,11 @@
     /** @hide */
     public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff;
 
+    // Always log queries which take 100ms+; shorter queries are
+    // sampled accordingly.
+    private static final int SLOW_THRESHOLD_MILLIS = 100;
+    private final Random mRandom = new Random();  // guarded by itself
+
     public ContentResolver(Context context) {
         mContext = context;
     }
@@ -235,12 +243,15 @@
             return null;
         }
         try {
+            long startTime = System.currentTimeMillis();
             Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
-            if(qCursor == null) {
+            if (qCursor == null) {
                 releaseProvider(provider);
                 return null;
             }
-            //Wrap the cursor object into CursorWrapperInner object
+            long durationMillis = System.currentTimeMillis() - startTime;
+            maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder);
+            // Wrap the cursor object into CursorWrapperInner object
             return new CursorWrapperInner(qCursor, provider);
         } catch (RemoteException e) {
             releaseProvider(provider);
@@ -572,7 +583,11 @@
             throw new IllegalArgumentException("Unknown URL " + url);
         }
         try {
-            return provider.insert(url, values);
+            long startTime = System.currentTimeMillis();
+            Uri createdRow = provider.insert(url, values);
+            long durationMillis = System.currentTimeMillis() - startTime;
+            maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */);
+            return createdRow;
         } catch (RemoteException e) {
             return null;
         } finally {
@@ -627,7 +642,11 @@
             throw new IllegalArgumentException("Unknown URL " + url);
         }
         try {
-            return provider.bulkInsert(url, values);
+            long startTime = System.currentTimeMillis();
+            int rowsCreated = provider.bulkInsert(url, values);
+            long durationMillis = System.currentTimeMillis() - startTime;
+            maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */);
+            return rowsCreated;
         } catch (RemoteException e) {
             return 0;
         } finally {
@@ -652,7 +671,11 @@
             throw new IllegalArgumentException("Unknown URL " + url);
         }
         try {
-            return provider.delete(url, where, selectionArgs);
+            long startTime = System.currentTimeMillis();
+            int rowsDeleted = provider.delete(url, where, selectionArgs);
+            long durationMillis = System.currentTimeMillis() - startTime;
+            maybeLogUpdateToEventLog(durationMillis, url, "delete", where);
+            return rowsDeleted;
         } catch (RemoteException e) {
             return -1;
         } finally {
@@ -680,7 +703,11 @@
             throw new IllegalArgumentException("Unknown URI " + uri);
         }
         try {
-            return provider.update(uri, values, where, selectionArgs);
+            long startTime = System.currentTimeMillis();
+            int rowsUpdated = provider.update(uri, values, where, selectionArgs);
+            long durationMillis = System.currentTimeMillis() - startTime;
+            maybeLogUpdateToEventLog(durationMillis, uri, "update", where);
+            return rowsUpdated;
         } catch (RemoteException e) {
             return -1;
         } finally {
@@ -1217,6 +1244,78 @@
         }
     }
 
+    /**
+     * Returns sampling percentage for a given duration.
+     *
+     * Always returns at least 1%.
+     */
+    private int samplePercentForDuration(long durationMillis) {
+        if (durationMillis >= SLOW_THRESHOLD_MILLIS) {
+            return 100;
+        }
+        return (int) (100 * durationMillis / SLOW_THRESHOLD_MILLIS) + 1;
+    }
+
+    private void maybeLogQueryToEventLog(long durationMillis,
+                                         Uri uri, String[] projection,
+                                         String selection, String sortOrder) {
+        int samplePercent = samplePercentForDuration(durationMillis);
+        if (samplePercent < 100) {
+            synchronized (mRandom) {
+                if (mRandom.nextInt(100) >= samplePercent) {
+                    return;
+                }
+            }
+        }
+
+        StringBuilder projectionBuffer = new StringBuilder(100);
+        if (projection != null) {
+            for (int i = 0; i < projection.length; ++i) {
+                // Note: not using a comma delimiter here, as the
+                // multiple arguments to EventLog.writeEvent later
+                // stringify with a comma delimiter, which would make
+                // parsing uglier later.
+                if (i != 0) projectionBuffer.append('/');
+                projectionBuffer.append(projection[i]);
+            }
+        }
+
+        // ActivityThread.currentPackageName() only returns non-null if the
+        // current thread is an application main thread.  This parameter tells
+        // us whether an event loop is blocked, and if so, which app it is.
+        String blockingPackage = ActivityThread.currentPackageName();
+
+        EventLog.writeEvent(
+            EventLogTags.CONTENT_QUERY_OPERATION,
+            uri.toString(),
+            projectionBuffer.toString(),
+            selection != null ? selection : "",
+            sortOrder != null ? sortOrder : "",
+            durationMillis,
+            blockingPackage != null ? blockingPackage : "",
+            samplePercent);
+    }
+
+    private void maybeLogUpdateToEventLog(
+        long durationMillis, Uri uri, String operation, String selection) {
+        int samplePercent = samplePercentForDuration(durationMillis);
+        if (samplePercent < 100) {
+            synchronized (mRandom) {
+                if (mRandom.nextInt(100) >= samplePercent) {
+                    return;
+                }
+            }
+        }
+        String blockingPackage = ActivityThread.currentPackageName();
+        EventLog.writeEvent(
+            EventLogTags.CONTENT_UPDATE_OPERATION,
+            uri.toString(),
+            operation,
+            selection != null ? selection : "",
+            durationMillis,
+            blockingPackage != null ? blockingPackage : "",
+            samplePercent);
+    }
 
     private final class CursorWrapperInner extends CursorWrapper {
         private IContentProvider mContentProvider;
diff --git a/core/java/android/content/EventLogTags.logtags b/core/java/android/content/EventLogTags.logtags
new file mode 100644
index 0000000..a815b95
--- /dev/null
+++ b/core/java/android/content/EventLogTags.logtags
@@ -0,0 +1,6 @@
+# See system/core/logcat/event.logtags for a description of the format of this file.
+
+option java_package android.content;
+
+52002 content_query_operation (uri|3),(projection|3),(selection|3),(sortorder|3),(time|1|3),(blocking_package|3),(sample_percent|1|6)
+52003 content_update_operation (uri|3),(operation|3),(selection|3),(time|1|3),(blocking_package|3),(sample_percent|1|6)
diff --git a/core/java/android/view/VelocityTracker.java b/core/java/android/view/VelocityTracker.java
index 9581080..9a8ee02 100644
--- a/core/java/android/view/VelocityTracker.java
+++ b/core/java/android/view/VelocityTracker.java
@@ -61,6 +61,7 @@
 
     float mYVelocity[] = new float[MotionEvent.BASE_AVAIL_POINTERS];
     float mXVelocity[] = new float[MotionEvent.BASE_AVAIL_POINTERS];
+    int mLastTouch;
 
     private VelocityTracker mNext;
 
@@ -105,8 +106,11 @@
      * Reset the velocity tracker back to its initial state.
      */
     public void clear() {
-        for (int i = 0; i < MotionEvent.BASE_AVAIL_POINTERS; i++) {
-            mPastTime[i][0] = 0;
+        final long[][] pastTime = mPastTime;
+        for (int p = 0; p < MotionEvent.BASE_AVAIL_POINTERS; p++) {
+            for (int i = 0; i < NUM_PAST; i++) {
+                pastTime[p][i] = 0;
+            }
         }
     }
     
@@ -133,42 +137,11 @@
     }
 
     private void addPoint(int pos, float x, float y, long time) {
-        int drop = -1;
-        int i;
-        if (localLOGV) Log.v(TAG, "Adding past y=" + y + " time=" + time);
-        final long[] pastTime = mPastTime[pos];
-        for (i=0; i<NUM_PAST; i++) {
-            if (pastTime[i] == 0) {
-                break;
-            } else if (pastTime[i] < time-LONGEST_PAST_TIME) {
-                if (localLOGV) Log.v(TAG, "Dropping past too old at "
-                        + i + " time=" + pastTime[i]);
-                drop = i;
-            }
-        }
-        if (localLOGV) Log.v(TAG, "Add index: " + i);
-        if (i == NUM_PAST && drop < 0) {
-            drop = 0;
-        }
-        if (drop == i) drop--;
-        final float[] pastX = mPastX[pos];
-        final float[] pastY = mPastY[pos];
-        if (drop >= 0) {
-            if (localLOGV) Log.v(TAG, "Dropping up to #" + drop);
-            final int start = drop+1;
-            final int count = NUM_PAST-drop-1;
-            System.arraycopy(pastX, start, pastX, 0, count);
-            System.arraycopy(pastY, start, pastY, 0, count);
-            System.arraycopy(pastTime, start, pastTime, 0, count);
-            i -= (drop+1);
-        }
-        pastX[i] = x;
-        pastY[i] = y;
-        pastTime[i] = time;
-        i++;
-        if (i < NUM_PAST) {
-            pastTime[i] = 0;
-        }
+        final int lastTouch = (mLastTouch + 1) % NUM_PAST;
+        mPastX[pos][lastTouch] = x;
+        mPastY[pos][lastTouch] = y;
+        mPastTime[pos][lastTouch] = time;
+        mLastTouch = lastTouch;
     }
 
     /**
@@ -199,36 +172,41 @@
             final float[] pastX = mPastX[pos];
             final float[] pastY = mPastY[pos];
             final long[] pastTime = mPastTime[pos];
-
+            final int lastTouch = mLastTouch;
+        
+            // find oldest acceptable time
+            int oldestTouch = lastTouch;
+            if (pastTime[lastTouch] > 0) { // cleared ?
+                oldestTouch = (lastTouch + 1) % NUM_PAST;
+                final float acceptableTime = pastTime[lastTouch] - LONGEST_PAST_TIME;
+                while (pastTime[oldestTouch] < acceptableTime) {
+                    oldestTouch = (oldestTouch + 1) % NUM_PAST;
+                }
+            }
+        
             // Kind-of stupid.
-            final float oldestX = pastX[0];
-            final float oldestY = pastY[0];
-            final long oldestTime = pastTime[0];
+            final float oldestX = pastX[oldestTouch];
+            final float oldestY = pastY[oldestTouch];
+            final long oldestTime = pastTime[oldestTouch];
             float accumX = 0;
             float accumY = 0;
-            int N=0;
-            while (N < NUM_PAST) {
-                if (pastTime[N] == 0) {
-                    break;
-                }
-                N++;
-            }
+            float N = (lastTouch - oldestTouch + NUM_PAST) % NUM_PAST + 1;
             // Skip the last received event, since it is probably pretty noisy.
             if (N > 3) N--;
 
             for (int i=1; i < N; i++) {
-                final int dur = (int)(pastTime[i] - oldestTime);
+                final int j = (oldestTouch + i) % NUM_PAST;
+                final int dur = (int)(pastTime[j] - oldestTime);
                 if (dur == 0) continue;
-                float dist = pastX[i] - oldestX;
+                float dist = pastX[j] - oldestX;
                 float vel = (dist/dur) * units;   // pixels/frame.
-                if (accumX == 0) accumX = vel;
-                else accumX = (accumX + vel) * .5f;
-
-                dist = pastY[i] - oldestY;
+                accumX = (accumX == 0) ? vel : (accumX + vel) * .5f;
+            
+                dist = pastY[j] - oldestY;
                 vel = (dist/dur) * units;   // pixels/frame.
-                if (accumY == 0) accumY = vel;
-                else accumY = (accumY + vel) * .5f;
+                accumY = (accumY == 0) ? vel : (accumY + vel) * .5f;
             }
+            
             mXVelocity[pos] = accumX < 0.0f ? Math.max(accumX, -maxVelocity)
                     : Math.min(accumX, maxVelocity);
             mYVelocity[pos] = accumY < 0.0f ? Math.max(accumY, -maxVelocity)
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 889985a..fb19dcf 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8282,7 +8282,7 @@
      */
     public void clearAnimation() {
         if (mCurrentAnimation != null) {
-            mCurrentAnimation.cancel();
+            mCurrentAnimation.detach();
         }
         mCurrentAnimation = null;
     }
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index ad98259..337fe58 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -277,6 +277,16 @@
     }
 
     /**
+     * @hide
+     */
+    public void detach() {
+        if (mStarted && !mEnded) {
+            if (mListener != null) mListener.onAnimationEnd(this);
+            mEnded = true;
+        }
+    }
+
+    /**
      * Whether or not the animation has been initialized.
      *
      * @return Has this animation been initialized.
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 299ed8a..9ef5e0b 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -103,6 +103,18 @@
         mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
         DateFormatSymbols dfs = new DateFormatSymbols();
         String[] months = dfs.getShortMonths();
+
+        /*
+         * If the user is in a locale where the month names are numeric,
+         * use just the number instead of the "month" character for
+         * consistency with the other fields.
+         */
+        if (months[0].startsWith("1")) {
+            for (int i = 0; i < months.length; i++) {
+                months[i] = String.valueOf(i + 1);
+            }
+        }
+
         mMonthPicker.setRange(1, 12, months);
         mMonthPicker.setSpeed(200);
         mMonthPicker.setOnChangeListener(new OnChangedListener() {
diff --git a/docs/html/resources/articles/images/live_wallpapers_small.png b/docs/html/resources/articles/images/live_wallpapers_small.png
new file mode 100644
index 0000000..3b49b24
--- /dev/null
+++ b/docs/html/resources/articles/images/live_wallpapers_small.png
Binary files differ
diff --git a/docs/html/resources/articles/index.jd b/docs/html/resources/articles/index.jd
index 4fda6d7..d2f0996 100644
--- a/docs/html/resources/articles/index.jd
+++ b/docs/html/resources/articles/index.jd
@@ -77,6 +77,11 @@
 </dl>
 
 <dl>
+  <dt><a href="{@docRoot}resources/articles/live-wallpapers.html">Live Wallpapers</a></dt>
+  <dd>Live wallpapers are richer, animated, interactive backgrounds that users can display in their home screens. Learn how to create a live wallpaper and bundle it in an application that users can install on their devices.</dd>
+</dl>
+
+<dl>
   <dt><a href="{@docRoot}resources/articles/on-screen-inputs.html">Onscreen Input Methods</a></dt>
   <dd>The Input Method Framework (IMF) allows users to take advantage of on-screen input methods, such as software keyboards. This article provides an overview of Input Method Editors (IMEs) and how applications interact with them.</dd>
 </dl>
diff --git a/docs/html/resources/articles/live-wallpapers.jd b/docs/html/resources/articles/live-wallpapers.jd
new file mode 100644
index 0000000..8dda879
--- /dev/null
+++ b/docs/html/resources/articles/live-wallpapers.jd
@@ -0,0 +1,84 @@
+page.title=Live Wallpapers
+@jd:body
+
+<p>Starting with Android 2.1 (API Level 7), users can now enjoy <em>live
+wallpapers</em> &mdash; richer, animated, interactive backgrounds &mdash; on
+their home screens. A live wallpaper is very similar to a normal Android
+application and has access to all the facilities of the platform: SGL (2D
+drawing), OpenGL (3D drawing), GPS, accelerometers, network access, etc. The
+live wallpapers included on Nexus One demonstrate the use of some of these APIs
+to create fun and interesting user experiences. For instance, the Grass
+wallpaper uses the phone's location to compute sunrise and sunset times in order
+to display the appropriate sky.</p>
+
+<img src="images/live_wallpapers_small.png" style="align:center" />
+
+<p>Creating your own live wallpaper is easy, especially if you have had
+previous experience with <a
+href="../../../reference/android/view/SurfaceView.html"><code>SurfaceView</code></a> or <a
+href="../../../reference/android/graphics/Canvas.html"><code>Canvas</code></a>. 
+To learn how to create a live wallpaper, you should check out the <a 
+href="../samples/CubeLiveWallpaper/index.html">CubeLiveWallpaper sample code</a>.</p>
+
+<p>In terms of implementation, a live wallpaper is very similar to a regular
+Android <a href="../../../reference/android/app/Service.html">service</a>. The
+only difference is the addition of a new method, <a
+href="../../../reference/android/service/wallpaper/WallpaperService.
+html#onCreateEngine()"><code>onCreateEngine()</code></a>, whose goal is to create a <a
+href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html">
+<code>WallpaperService.Engine</code></a>. The engine is responsible for
+handling the lifecycle and drawing of a wallpaper. The system provides a surface
+on which you can draw, just like you would with a <code>SurfaceView</code></a>.
+Drawing a wallpaper can be very expensive so you should optimize your code
+as much as possible to avoid using too much CPU, not only for battery life
+but also to avoid slowing down the rest of the system. That is also why the
+most important part of the lifecycle of a wallpaper is <a href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onVisibilityChanged%28boolean%29">when it becomes invisible</a>. 
+When invisible, such as when the user launches an application that covers
+the home screen, a wallpaper must stop all activity.</p>
+
+<p>The engine can also implement several methods to interact with the user
+or the home application. For instance, if you want your wallpaper to scroll
+along when the user swipes from one home screen to another, you can use <a href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onOffsetsChanged%28float,%20float,%20float,%20float,%20int,%20int%29"><code>onOffsetsChanged()</code></a>.
+To react to touch events, simply implement <a href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onTouchEvent%28android.view.MotionEvent%29"><code>onTouchEvent(MotionEvent)</code></a>.
+Finally, applications can send arbitrary commands to the live wallpaper.
+Currently, only the standard home application sends commands to the <a
+href="../../../reference/android/service/wallpaper/WallpaperService.Engine.html#onCommand%28java.lang.String,%20int,%20int,%20int,%20android.os.Bundle,%20boolean%29"><code>onCommand()</code></a>
+method of the live wallpaper:</p>
+
+<ul>
+<li><code>android.wallpaper.tap</code>: When the user taps an empty space
+on the workspace. This command is interpreted by the Nexus and Water live
+wallpapers to make the wallpaper react to user interaction. For instance,
+if you tap an empty space on the Water live wallpaper, new ripples appear
+under your finger.</li>
+<li><code>android.home.drop</code>: When the user drops an icon or a widget
+on the workspace. This command is also interpreted by the Nexus and Water
+live wallpapers.</li>
+</ul>
+
+<p>If you are developing a live wallpaper, remember that the feature is
+supported only on Android 2.1 (API level 7) and higher versions of the platform.
+To ensure that your application can only be installed on devices that support
+live wallpapers, remember to add the following to the application's manifest
+before publishing to Android Market:</p>
+
+<ul>
+<li><code>&lt;uses-sdk android:minSdkVersion="7" /&gt;</code>, which indicates
+to Android Market and the platform that your application requires Android 2.1 or
+higher. For more information, see the <a href="../../../guide/appendix/api-levels.html">API
+Levels</a> and the documentation for the
+<a href="../../../guide/topics/manifest/uses-sdk-element.html"><code>&lt;uses-sdk&gt;</code></a>
+element.</li>
+<li><code>&lt;uses-feature android:name="android.software.live_wallpaper" /&gt;</code>,
+which tells Android Market that your application includes a live wallpaper
+Android Market uses this feature as a filter, when presenting users lists of
+available applications. When you declaring this feature, Android Market
+displays your application only to users whose devices support live wallpapers,
+while hiding it from other devices on which it would not be able to run. For
+more information, see the documentation for the
+<a href="../../../guide/topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;</code></a>
+element.</li>
+</ul>
+
+<p>Many great live wallpapers are already available on Android Market and
+we can't wait to see more!</p>
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index e337e38..0972029 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -83,6 +83,9 @@
         <li><a href="<?cs var:toroot ?>resources/articles/live-folders.html">
                 <span class="en">Live Folders</span>
                 </a></li>
+        <li><a href="<?cs var:toroot ?>resources/articles/live-wallpapers.html">
+                <span class="en">Live Wallpapers</span>
+                </a> <span class="new">new!</span></li>
         <li><a href="<?cs var:toroot ?>resources/articles/on-screen-inputs.html">
                 <span class="en">Onscreen Input Methods</span>
                 </a></li>
@@ -178,28 +181,34 @@
               </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/BluetoothChat/index.html">
                 <span class="en">Bluetooth Chat</span>
-              </a> <span class="new">new!</span></li>
+              </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/BusinessCard/index.html">
                 <span class="en">Business Card</span>
-              </a> <span class="new">new!</span></li>
+              </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/ContactManager/index.html">
                 <span class="en">Contact Manager</span>
-              </a> <span class="new">new!</span></li>
+              </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/Home/index.html">
                 <span class="en">Home</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/JetBoy/index.html">
                 <span class="en">JetBoy</span>
               </a></li>
+          <li><a href="<?cs var:toroot ?>resources/samples/CubeLiveWallpaper/index.html">
+                <span class="en">Live Wallpaper</span>
+                </a> <span class="new">new!</span></li>
           <li><a href="<?cs var:toroot ?>resources/samples/LunarLander/index.html">
                 <span class="en">Lunar Lander</span>
               </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/MultiResolution/index.html">
                 <span class="en">Multiple Resolutions</span>
-              </a> <span class="new">new!</span></li>
+              </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/NotePad/index.html">
                 <span class="en">Note Pad</span>
               </a></li>
+          <li><a href="<?cs var:toroot ?>resources/samples/SampleSyncAdapter/index.html">
+                <span class="en">Sample Sync Adapter</span>
+              </a> <span class="new">new!</span></li>
           <li><a href="<?cs var:toroot ?>resources/samples/SearchableDictionary/index.html">
                 <span class="en">Searchable Dictionary</span>
               </a></li>
@@ -211,10 +220,10 @@
               </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/Wiktionary/index.html">
                 <span class="en">Wiktionary</span>
-              </a> <span class="new">new!</span></li>
+              </a></li>
           <li><a href="<?cs var:toroot ?>resources/samples/WiktionarySimple/index.html">
                 <span class="en">Wiktionary (Simplified)</span>
-              </a> <span class="new">new!</span></li>
+              </a></li>
         </ul>
       </li>
     </ul>
diff --git a/docs/html/resources/samples/images/CubeLiveWallpaper1.png b/docs/html/resources/samples/images/CubeLiveWallpaper1.png
new file mode 100644
index 0000000..55bc1e9
--- /dev/null
+++ b/docs/html/resources/samples/images/CubeLiveWallpaper1.png
Binary files differ
diff --git a/docs/html/resources/samples/images/CubeLiveWallpaper3.png b/docs/html/resources/samples/images/CubeLiveWallpaper3.png
new file mode 100644
index 0000000..2747a88
--- /dev/null
+++ b/docs/html/resources/samples/images/CubeLiveWallpaper3.png
Binary files differ
diff --git a/docs/html/resources/samples/index.jd b/docs/html/resources/samples/index.jd
index 0beb781..5ebf41c 100644
--- a/docs/html/resources/samples/index.jd
+++ b/docs/html/resources/samples/index.jd
@@ -27,10 +27,10 @@
 platforms) and allow you to view the source files in your browser. </p>
 
 <div class="special">
-  <p>Some of the samples in this listing are not yet available in the
-  SDK. While we work to update the SDK, you can
-  <a href="{@docRoot}shareables/latest_samples.zip">download the latest samples</a> as a ZIP
-  archive.</p>
+  <p>Some of the samples in this listing may not yet be available in the
+  SDK. To ensure that you have the latest versions of the samples, you can
+  <a href="{@docRoot}shareables/latest_samples.zip">download the samples pack</a>
+  as a .zip archive.</p>
 </div>
 
 <dl>
@@ -55,11 +55,15 @@
 
  <dt><a href="Home/index.html">Home</a></dt>
   <dd>A home screen replacement application.</dd>
-  
+
  <dt><a href="JetBoy/index.html">JetBoy</a></dt>
   <dd>A game that demonstrates the SONiVOX JET interactive music technology,
   with {@link android.media.JetPlayer}.</dd>
-    
+
+ <dt><a href="CubeLiveWallpaper/index.html">Live Wallpaper</a></dt>
+  <dd>An application that demonstrates how to create a live wallpaper and 
+  bundle it in an application that users can install on their devices.</dd>
+
  <dt><a href="LunarLander/index.html">Lunar Lander</a></dt>
   <dd>A classic Lunar Lander game.</dd>
 
@@ -70,14 +74,21 @@
  <dt><a href="NotePad/index.html">Note Pad</a></dt>
   <dd>An application for saving notes. Similar (but not identical) to the 
     <a href="{@docRoot}resources/tutorials/notepad/index.html">Notepad tutorial</a>.</dd>
-  
+
+ <dt><a href="SampleSyncAdapter/index.html">SampleSyncAdapter</a></dt>
+  <dd>Demonstrates how an application can communicate with a
+cloud-based service and synchronize its data with data stored locally in a
+content provider. The sample uses two related parts of the Android framework
+&mdash; the account manager and the synchronization manager (through a sync
+adapter).</dd>
+
  <dt><a href="SearchableDictionary/index.html">Searchable Dictionary</a></dt>
   <dd>A sample application that demonstrates Android's search framework, 
   including how to provide search suggestions for Quick Search Box.</dd>
-  
+
  <dt><a href="Snake/index.html">Snake</a></dt>
   <dd>An implementation of the classic game "Snake."</dd>
-  
+
  <dt><a href="SoftKeyboard/index.html">Soft Keyboard</a></dt>
   <dd>An example of writing an input method for a software keyboard.</dd>
 
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index ad1bb54..1d3f82d 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -36,7 +36,7 @@
  **/
 public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
     private SurfaceHolder mSurfaceHolder;
-    private RenderScript mRS;
+    private RenderScriptGL mRS;
 
     /**
      * Standard View constructor. In order to render something, you
@@ -146,13 +146,13 @@
 
     // ----------------------------------------------------------------------
 
-    public RenderScript createRenderScript(boolean useDepth, boolean forceSW) {
+    public RenderScriptGL createRenderScript(boolean useDepth, boolean forceSW) {
         Log.v(RenderScript.LOG_TAG, "createRenderScript");
-        mRS = new RenderScript(useDepth, forceSW);
+        mRS = new RenderScriptGL(useDepth, forceSW);
         return mRS;
     }
 
-    public RenderScript createRenderScript(boolean useDepth) {
+    public RenderScriptGL createRenderScript(boolean useDepth) {
         return createRenderScript(useDepth, false);
     }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 29361af..84b1a70 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -31,11 +31,9 @@
  **/
 public class RenderScript {
     static final String LOG_TAG = "RenderScript_jni";
-    private static final boolean DEBUG  = false;
+    protected static final boolean DEBUG  = false;
     @SuppressWarnings({"UnusedDeclaration", "deprecation"})
-    private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
-    int mWidth;
-    int mHeight;
+    protected static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
 
 
 
@@ -44,8 +42,8 @@
      * field offsets.
      */
     @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
-    private static boolean sInitialized;
-    native private static void _nInit();
+    protected static boolean sInitialized;
+    native protected static void _nInit();
 
 
     static {
@@ -64,7 +62,8 @@
     native int  nDeviceCreate();
     native void nDeviceDestroy(int dev);
     native void nDeviceSetConfig(int dev, int param, int value);
-    native int  nContextCreate(int dev, int ver, boolean useDepth);
+    native int  nContextCreateGL(int dev, int ver, boolean useDepth);
+    native int  nContextCreate(int dev, int ver);
     native void nContextDestroy(int con);
     native void nContextSetSurface(int w, int h, Surface sur);
     native void nContextSetPriority(int p);
@@ -190,11 +189,10 @@
     native void nAnimationAdd(float time, float[] attribs);
     native int  nAnimationCreate();
 
-    private int     mDev;
-    private int     mContext;
+    protected int     mDev;
+    protected int     mContext;
     @SuppressWarnings({"FieldCanBeLocal"})
-    private Surface mSurface;
-    private MessageThread mMessageThread;
+    protected MessageThread mMessageThread;
 
     Element mElement_USER_U8;
     Element mElement_USER_I8;
@@ -251,7 +249,7 @@
         nContextSetPriority(p.mID);
     }
 
-    private static class MessageThread extends Thread {
+    protected static class MessageThread extends Thread {
         RenderScript mRS;
         boolean mRun = true;
 
@@ -289,26 +287,18 @@
         }
     }
 
-    public RenderScript(boolean useDepth, boolean forceSW) {
-        mSurface = null;
-        mWidth = 0;
-        mHeight = 0;
-        mDev = nDeviceCreate();
-        if(forceSW) {
-            nDeviceSetConfig(mDev, 0, 1);
-        }
-        mContext = nContextCreate(mDev, 0, useDepth);
-        mMessageThread = new MessageThread(this);
-        mMessageThread.start();
-        Element.initPredefined(this);
+    protected RenderScript() {
     }
 
-    public void contextSetSurface(int w, int h, Surface sur) {
-        mSurface = sur;
-        mWidth = w;
-        mHeight = h;
-        validate();
-        nContextSetSurface(w, h, mSurface);
+    public static RenderScript create() {
+        RenderScript rs = new RenderScript();
+
+        rs.mDev = rs.nDeviceCreate();
+        rs.mContext = rs.nContextCreate(rs.mDev, 0);
+        rs.mMessageThread = new MessageThread(rs);
+        rs.mMessageThread.start();
+        Element.initPredefined(rs);
+        return rs;
     }
 
     public void contextDump(int bits) {
@@ -332,77 +322,15 @@
         return mContext != 0;
     }
 
-    void pause() {
-        validate();
-        nContextPause();
-    }
-
-    void resume() {
-        validate();
-        nContextResume();
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    // File
-
-    public class File extends BaseObj {
-        File(int id) {
-            super(RenderScript.this);
-            mID = id;
-        }
-    }
-
-    public File fileOpen(String s) throws IllegalStateException, IllegalArgumentException
-    {
-        if(s.length() < 1) {
-            throw new IllegalArgumentException("fileOpen does not accept a zero length string.");
-        }
-
-        try {
-            byte[] bytes = s.getBytes("UTF-8");
-            int id = nFileOpen(bytes);
-            return new File(id);
-        } catch (java.io.UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-
     ///////////////////////////////////////////////////////////////////////////////////
     // Root state
 
-    private int safeID(BaseObj o) {
+    protected int safeID(BaseObj o) {
         if(o != null) {
             return o.mID;
         }
         return 0;
     }
-
-    public void contextBindRootScript(Script s) {
-        validate();
-        nContextBindRootScript(safeID(s));
-    }
-
-    public void contextBindProgramFragmentStore(ProgramStore p) {
-        validate();
-        nContextBindProgramFragmentStore(safeID(p));
-    }
-
-    public void contextBindProgramFragment(ProgramFragment p) {
-        validate();
-        nContextBindProgramFragment(safeID(p));
-    }
-
-    public void contextBindProgramRaster(ProgramRaster p) {
-        validate();
-        nContextBindProgramRaster(safeID(p));
-    }
-
-    public void contextBindProgramVertex(ProgramVertex p) {
-        validate();
-        nContextBindProgramVertex(safeID(p));
-    }
-
 }
 
 
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
new file mode 100644
index 0000000..d1df23d
--- /dev/null
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -0,0 +1,127 @@
+/*
+ * 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.lang.reflect.Field;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.Config;
+import android.util.Log;
+import android.view.Surface;
+
+
+/**
+ * @hide
+ *
+ **/
+public class RenderScriptGL extends RenderScript {
+    private Surface mSurface;
+    int mWidth;
+    int mHeight;
+
+
+    public RenderScriptGL(boolean useDepth, boolean forceSW) {
+        mSurface = null;
+        mWidth = 0;
+        mHeight = 0;
+        mDev = nDeviceCreate();
+        if(forceSW) {
+            nDeviceSetConfig(mDev, 0, 1);
+        }
+        mContext = nContextCreateGL(mDev, 0, useDepth);
+        mMessageThread = new MessageThread(this);
+        mMessageThread.start();
+        Element.initPredefined(this);
+    }
+
+    public void contextSetSurface(int w, int h, Surface sur) {
+        mSurface = sur;
+        mWidth = w;
+        mHeight = h;
+        validate();
+        nContextSetSurface(w, h, mSurface);
+    }
+
+
+    void pause() {
+        validate();
+        nContextPause();
+    }
+
+    void resume() {
+        validate();
+        nContextResume();
+    }
+
+
+    public void contextBindRootScript(Script s) {
+        validate();
+        nContextBindRootScript(safeID(s));
+    }
+
+    public void contextBindProgramFragmentStore(ProgramStore p) {
+        validate();
+        nContextBindProgramFragmentStore(safeID(p));
+    }
+
+    public void contextBindProgramFragment(ProgramFragment p) {
+        validate();
+        nContextBindProgramFragment(safeID(p));
+    }
+
+    public void contextBindProgramRaster(ProgramRaster p) {
+        validate();
+        nContextBindProgramRaster(safeID(p));
+    }
+
+    public void contextBindProgramVertex(ProgramVertex p) {
+        validate();
+        nContextBindProgramVertex(safeID(p));
+    }
+
+
+
+
+    //////////////////////////////////////////////////////////////////////////////////
+    // File
+
+    public class File extends BaseObj {
+        File(int id) {
+            super(RenderScriptGL.this);
+            mID = id;
+        }
+    }
+
+    public File fileOpen(String s) throws IllegalStateException, IllegalArgumentException
+    {
+        if(s.length() < 1) {
+            throw new IllegalArgumentException("fileOpen does not accept a zero length string.");
+        }
+
+        try {
+            byte[] bytes = s.getBytes("UTF-8");
+            int id = nFileOpen(bytes);
+            return new File(id);
+        } catch (java.io.UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}
+
+
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 7ded133..4d35c37 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -151,10 +151,17 @@
 }
 
 static jint
-nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver, jboolean useDepth)
+nContextCreate(JNIEnv *_env, jobject _this, jint dev, jint ver)
 {
     LOG_API("nContextCreate");
-    return (jint)rsContextCreate((RsDevice)dev, ver, useDepth);
+    return (jint)rsContextCreate((RsDevice)dev, ver);
+}
+
+static jint
+nContextCreateGL(JNIEnv *_env, jobject _this, jint dev, jint ver, jboolean useDepth)
+{
+    LOG_API("nContextCreateGL");
+    return (jint)rsContextCreateGL((RsDevice)dev, ver, useDepth);
 }
 
 static void
@@ -260,7 +267,7 @@
 {
     int fieldCount = _env->GetArrayLength(_ids);
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
-    LOG_API("nElementCreate, con(%p), type(%i), kind(%i), norm(%i), size(%i)", con, type, kind, norm, size);
+    LOG_API("nElementCreate2, con(%p)", con);
 
     jint *ids = _env->GetIntArrayElements(_ids, NULL);
     const char ** nameArray = (const char **)calloc(fieldCount, sizeof(char *));
@@ -1089,7 +1096,7 @@
     jint *paramPtr = _env->GetIntArrayElements(params, NULL);
     jint paramLen = _env->GetArrayLength(params);
 
-    LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", con, shaderLen, paramLen);
+    LOG_API("nProgramFragmentCreate, con(%p), paramLen(%i)", con, paramLen);
 
     jint ret = (jint)rsProgramFragmentCreate(con, (uint32_t *)paramPtr, paramLen);
     _env->ReleaseIntArrayElements(params, paramPtr, JNI_ABORT);
@@ -1332,7 +1339,8 @@
 {"nDeviceCreate",                  "()I",                                  (void*)nDeviceCreate },
 {"nDeviceDestroy",                 "(I)V",                                 (void*)nDeviceDestroy },
 {"nDeviceSetConfig",               "(III)V",                               (void*)nDeviceSetConfig },
-{"nContextCreate",                 "(IIZ)I",                               (void*)nContextCreate },
+{"nContextCreate",                 "(II)I",                                (void*)nContextCreate },
+{"nContextCreateGL",               "(IIZ)I",                               (void*)nContextCreateGL },
 {"nContextSetPriority",            "(I)V",                                 (void*)nContextSetPriority },
 {"nContextSetSurface",             "(IILandroid/view/Surface;)V",          (void*)nContextSetSurface },
 {"nContextDestroy",                "(I)V",                                 (void*)nContextDestroy },
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 6662333..02667d8 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -55,7 +55,8 @@
 void rsDeviceDestroy(RsDevice);
 void rsDeviceSetConfig(RsDevice, RsDeviceParam, int32_t value);
 
-RsContext rsContextCreate(RsDevice, uint32_t version, bool useDepth);
+RsContext rsContextCreate(RsDevice, uint32_t version);
+RsContext rsContextCreateGL(RsDevice, uint32_t version, bool useDepth);
 void rsContextDestroy(RsContext);
 void rsObjDestroyOOB(RsContext, void *);
 
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 b80e619..7d04502 100644
--- a/libs/rs/java/Film/src/com/android/film/FilmRS.java
+++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java
@@ -40,7 +40,7 @@
     public FilmRS() {
     }
 
-    public void init(RenderScript rs, Resources res, int width, int height) {
+    public void init(RenderScriptGL rs, Resources res, int width, int height) {
         mRS = rs;
         mRes = res;
         initRS();
@@ -65,7 +65,7 @@
 
 
     private Resources mRes;
-    private RenderScript mRS;
+    private RenderScriptGL mRS;
     private Script mScriptStrip;
     private Script mScriptImage;
     private Sampler mSampler;
diff --git a/libs/rs/java/Film/src/com/android/film/FilmView.java b/libs/rs/java/Film/src/com/android/film/FilmView.java
index 4a201fd..5bc2811 100644
--- a/libs/rs/java/Film/src/com/android/film/FilmView.java
+++ b/libs/rs/java/Film/src/com/android/film/FilmView.java
@@ -22,6 +22,7 @@
 
 import android.renderscript.RSSurfaceView;
 import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -45,7 +46,7 @@
         //setFocusable(true);
     }
 
-    private RenderScript mRS;
+    private RenderScriptGL mRS;
     private FilmRS mRender;
 
 
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 71f95a7..9356579 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -37,7 +37,7 @@
     public FountainRS() {
     }
 
-    public void init(RenderScript rs, Resources res, int width, int height) {
+    public void init(RenderScriptGL rs, Resources res, int width, int height) {
         mRS = rs;
         mRes = res;
         initRS();
@@ -65,7 +65,7 @@
 
     private Resources mRes;
 
-    private RenderScript mRS;
+    private RenderScriptGL mRS;
     private Allocation mIntAlloc;
     private SimpleMesh mSM;
     private SomeData mSD;
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
index fcb93f4..dfd6a49 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
@@ -22,6 +22,7 @@
 
 import android.renderscript.RSSurfaceView;
 import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
 
 import android.content.Context;
 import android.content.res.Resources;
@@ -45,7 +46,7 @@
         //setFocusable(true);
     }
 
-    private RenderScript mRS;
+    private RenderScriptGL mRS;
     private FountainRS mRender;
 
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 0ca00b3..568d3ab 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -126,14 +126,13 @@
     }
 
     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-        mRS.contextSetSurface(width, height, holder.getSurface());
     }
 
     public void surfaceDestroyed(SurfaceHolder holder) {
     }
 
     private Script.Invokable createScript() {
-        mRS = new RenderScript(false, false);
+        mRS = RenderScript.create();
         mRS.mMessageCallback = new FilterCallback();
 
         mParamsType = Type.createFromClass(mRS, Params.class, 1, "Parameters");
@@ -164,7 +163,7 @@
         sb.setType(true, 2);
         Script.Invokable invokable = sb.addInvokable("main");
         sb.setScript(getResources(), R.raw.threshold);
-        sb.setRoot(true);
+        //sb.setRoot(true);
 
         ScriptC script = sb.create();
         script.bindAllocation(mParamsAllocation, 0);
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 261b827..2e47ea3 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -289,15 +289,17 @@
          LOGE("pthread_setspecific %i", status);
      }
 
-     rsc->mStateRaster.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
-     rsc->setRaster(NULL);
-     rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
-     rsc->setVertex(NULL);
-     rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
-     rsc->setFragment(NULL);
-     rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
-     rsc->setFragmentStore(NULL);
-     rsc->mStateVertexArray.init(rsc);
+     if (rsc->mIsGraphicsContext) {
+         rsc->mStateRaster.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+         rsc->setRaster(NULL);
+         rsc->mStateVertex.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+         rsc->setVertex(NULL);
+         rsc->mStateFragment.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+         rsc->setFragment(NULL);
+         rsc->mStateFragmentStore.init(rsc, rsc->mEGL.mWidth, rsc->mEGL.mHeight);
+         rsc->setFragmentStore(NULL);
+         rsc->mStateVertexArray.init(rsc);
+     }
 
      rsc->mRunning = true;
      bool mDraw = true;
@@ -307,7 +309,7 @@
          mDraw &= (rsc->mWndSurface != NULL);
 
          uint32_t targetTime = 0;
-         if (mDraw) {
+         if (mDraw && rsc->mIsGraphicsContext) {
              targetTime = rsc->runRootScript();
              mDraw = targetTime && !rsc->mPaused;
              rsc->timerSet(RS_TIMER_CLEAR_SWAP);
@@ -329,23 +331,27 @@
      }
 
      LOGV("RS Thread exiting");
-     rsc->mRaster.clear();
-     rsc->mFragment.clear();
-     rsc->mVertex.clear();
-     rsc->mFragmentStore.clear();
-     rsc->mRootScript.clear();
-     rsc->mStateRaster.deinit(rsc);
-     rsc->mStateVertex.deinit(rsc);
-     rsc->mStateFragment.deinit(rsc);
-     rsc->mStateFragmentStore.deinit(rsc);
+     if (rsc->mIsGraphicsContext) {
+         rsc->mRaster.clear();
+         rsc->mFragment.clear();
+         rsc->mVertex.clear();
+         rsc->mFragmentStore.clear();
+         rsc->mRootScript.clear();
+         rsc->mStateRaster.deinit(rsc);
+         rsc->mStateVertex.deinit(rsc);
+         rsc->mStateFragment.deinit(rsc);
+         rsc->mStateFragmentStore.deinit(rsc);
+     }
      ObjectBase::zeroAllUserRef(rsc);
 
      rsc->mObjDestroy.mNeedToEmpty = true;
      rsc->objDestroyOOBRun();
 
-     pthread_mutex_lock(&gInitMutex);
-     rsc->deinitEGL();
-     pthread_mutex_unlock(&gInitMutex);
+     if (rsc->mIsGraphicsContext) {
+         pthread_mutex_lock(&gInitMutex);
+         rsc->deinitEGL();
+         pthread_mutex_unlock(&gInitMutex);
+     }
 
      LOGV("RS Thread exited");
      return NULL;
@@ -371,7 +377,7 @@
 #endif
 }
 
-Context::Context(Device *dev, bool useDepth)
+Context::Context(Device *dev, bool isGraphics, bool useDepth)
 {
     pthread_mutex_lock(&gInitMutex);
 
@@ -383,6 +389,8 @@
     mPaused = false;
     mObjHead = NULL;
     memset(&mEGL, 0, sizeof(mEGL));
+    memset(&mGL, 0, sizeof(mGL));
+    mIsGraphicsContext = isGraphics;
 
     int status;
     pthread_attr_t threadAttr;
@@ -454,7 +462,7 @@
 
 void Context::setSurface(uint32_t w, uint32_t h, Surface *sur)
 {
-    LOGV("setSurface %i %i %p", w, h, sur);
+    rsAssert(mIsGraphicsContext);
 
     EGLBoolean ret;
     if (mEGL.mSurface != NULL) {
@@ -544,21 +552,25 @@
 
 void Context::pause()
 {
+    rsAssert(mIsGraphicsContext);
     mPaused = true;
 }
 
 void Context::resume()
 {
+    rsAssert(mIsGraphicsContext);
     mPaused = false;
 }
 
 void Context::setRootScript(Script *s)
 {
+    rsAssert(mIsGraphicsContext);
     mRootScript.set(s);
 }
 
 void Context::setFragmentStore(ProgramFragmentStore *pfs)
 {
+    rsAssert(mIsGraphicsContext);
     if (pfs == NULL) {
         mFragmentStore.set(mStateFragmentStore.mDefault);
     } else {
@@ -568,6 +580,7 @@
 
 void Context::setFragment(ProgramFragment *pf)
 {
+    rsAssert(mIsGraphicsContext);
     if (pf == NULL) {
         mFragment.set(mStateFragment.mDefault);
     } else {
@@ -577,6 +590,7 @@
 
 void Context::setRaster(ProgramRaster *pr)
 {
+    rsAssert(mIsGraphicsContext);
     if (pr == NULL) {
         mRaster.set(mStateRaster.mDefault);
     } else {
@@ -586,6 +600,7 @@
 
 void Context::setVertex(ProgramVertex *pv)
 {
+    rsAssert(mIsGraphicsContext);
     if (pv == NULL) {
         mVertex.set(mStateVertex.mDefault);
     } else {
@@ -860,10 +875,19 @@
 }
 
 
-RsContext rsContextCreate(RsDevice vdev, uint32_t version, bool useDepth)
+RsContext rsContextCreate(RsDevice vdev, uint32_t version)
 {
+    LOGV("rsContextCreate %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
-    Context *rsc = new Context(dev, useDepth);
+    Context *rsc = new Context(dev, false, false);
+    return rsc;
+}
+
+RsContext rsContextCreateGL(RsDevice vdev, uint32_t version, bool useDepth)
+{
+    LOGV("rsContextCreateGL %p, %i", vdev, useDepth);
+    Device * dev = static_cast<Device *>(vdev);
+    Context *rsc = new Context(dev, true, useDepth);
     return rsc;
 }
 
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 2edd16d..31d8cc8 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -51,7 +51,7 @@
 class Context
 {
 public:
-    Context(Device *, bool useDepth);
+    Context(Device *, bool isGraphics, bool useDepth);
     ~Context();
 
     static pthread_key_t gThreadTLSKey;
@@ -201,6 +201,7 @@
     uint32_t mWidth;
     uint32_t mHeight;
     int32_t mThreadPriority;
+    bool mIsGraphicsContext;
 
     bool mRunning;
     bool mExit;
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 965b7dd..2d6152e 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -39,7 +39,6 @@
 
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/PixelFormat.h>
-#include <ui/DisplayInfo.h>
 
 #include <pixelflinger/pixelflinger.h>
 #include <GLES/gl.h>
@@ -350,8 +349,8 @@
     mServerCblk->connected |= 1<<dpy;
     display_cblk_t* dcblk = mServerCblk->displays + dpy;
     memset(dcblk, 0, sizeof(display_cblk_t));
-    dcblk->w            = w;
-    dcblk->h            = h;
+    dcblk->w            = plane.getWidth();
+    dcblk->h            = plane.getHeight();
     dcblk->format       = f;
     dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
     dcblk->xdpi         = hw.getDpiX();
@@ -621,14 +620,8 @@
             const DisplayHardware& hw(plane.displayHardware());
             volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
             dcblk->orientation = orientation;
-            if (orientation & eOrientationSwapMask) {
-                // 90 or 270 degrees orientation
-                dcblk->w = hw.getHeight();
-                dcblk->h = hw.getWidth();
-            } else {
-                dcblk->w = hw.getWidth();
-                dcblk->h = hw.getHeight();
-            }
+            dcblk->w = plane.getWidth();
+            dcblk->h = plane.getHeight();
 
             mVisibleRegionsDirty = true;
             mDirtyRegion.set(hw.bounds());
@@ -1795,13 +1788,47 @@
     return mHw ? true : false;
 }
 
-void GraphicPlane::setDisplayHardware(DisplayHardware *hw) {
-    mHw = hw;
+int GraphicPlane::getWidth() const {
+    return mWidth;
 }
 
-void GraphicPlane::setTransform(const Transform& tr) {
-    mTransform = tr;
-    mGlobalTransform = mOrientationTransform * mTransform;
+int GraphicPlane::getHeight() const {
+    return mHeight;
+}
+
+void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
+{
+    mHw = hw;
+
+    // initialize the display orientation transform.
+    // it's a constant that should come from the display driver.
+    int displayOrientation = ISurfaceComposer::eOrientationDefault;
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
+        //displayOrientation
+        switch (atoi(property)) {
+        case 90:
+            displayOrientation = ISurfaceComposer::eOrientation90;
+            break;
+        case 270:
+            displayOrientation = ISurfaceComposer::eOrientation270;
+            break;
+        }
+    }
+
+    const float w = hw->getWidth();
+    const float h = hw->getHeight();
+    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
+            &mDisplayTransform);
+    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
+        mDisplayWidth = h;
+        mDisplayHeight = w;
+    } else {
+        mDisplayWidth = w;
+        mDisplayHeight = h;
+    }
+
+    setOrientation(ISurfaceComposer::eOrientationDefault);
 }
 
 status_t GraphicPlane::orientationToTransfrom(
@@ -1810,8 +1837,9 @@
     float a, b, c, d, x, y;
     switch (orientation) {
     case ISurfaceComposer::eOrientationDefault:
-        a=1; b=0; c=0; d=1; x=0; y=0;
-        break;
+        // make sure the default orientation is optimal
+        tr->reset();
+        return NO_ERROR;
     case ISurfaceComposer::eOrientation90:
         a=0; b=-1; c=1; d=0; x=w; y=0;
         break;
@@ -1831,20 +1859,16 @@
 
 status_t GraphicPlane::setOrientation(int orientation)
 {
-    const DisplayHardware& hw(displayHardware());
-    const float w = hw.getWidth();
-    const float h = hw.getHeight();
-
-    if (orientation == ISurfaceComposer::eOrientationDefault) {
-        // make sure the default orientation is optimal
-        mOrientationTransform.reset();
-        mOrientation = orientation;
-        mGlobalTransform = mTransform;
-        return NO_ERROR;
-    }
-
     // If the rotation can be handled in hardware, this is where
     // the magic should happen.
+
+    const DisplayHardware& hw(displayHardware());
+    const float w = mDisplayWidth;
+    const float h = mDisplayHeight;
+    mWidth = int(w);
+    mHeight = int(h);
+
+    Transform orientationTransform;
     if (UNLIKELY(orientation == 42)) {
         float a, b, c, d, x, y;
         const float r = (3.14159265f / 180.0f) * 42.0f;
@@ -1853,14 +1877,18 @@
         a=co; b=-si; c=si; d=co;
         x = si*(h*0.5f) + (1-co)*(w*0.5f);
         y =-si*(w*0.5f) + (1-co)*(h*0.5f);
-        mOrientationTransform.set(a, b, c, d);
-        mOrientationTransform.set(x, y);
+        orientationTransform.set(a, b, c, d);
+        orientationTransform.set(x, y);
     } else {
         GraphicPlane::orientationToTransfrom(orientation, w, h,
-                &mOrientationTransform);
+                &orientationTransform);
+        if (orientation & ISurfaceComposer::eOrientationSwapMask) {
+            mWidth = int(h);
+            mHeight = int(w);
+        }
     }
     mOrientation = orientation;
-    mGlobalTransform = mOrientationTransform * mTransform;
+    mGlobalTransform = mDisplayTransform * orientationTransform;
     return NO_ERROR;
 }
 
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index c0ab73d..2b7820c 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -116,9 +116,10 @@
         bool                    initialized() const;
 
         void                    setDisplayHardware(DisplayHardware *);
-        void                    setTransform(const Transform& tr);
         status_t                setOrientation(int orientation);
         int                     getOrientation() const { return mOrientation; }
+        int                     getWidth() const;
+        int                     getHeight() const;
 
         const DisplayHardware&  displayHardware() const;
         const Transform&        transform() const;
@@ -129,10 +130,13 @@
         GraphicPlane            operator = (const GraphicPlane&);
 
         DisplayHardware*        mHw;
-        Transform               mTransform;
-        Transform               mOrientationTransform;
         Transform               mGlobalTransform;
+        Transform               mDisplayTransform;
         int                     mOrientation;
+        float                   mDisplayWidth;
+        float                   mDisplayHeight;
+        int                     mWidth;
+        int                     mHeight;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index b1e5d32..10bf851 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -20,6 +20,7 @@
 import com.android.internal.app.ResolverActivity;
 import com.android.common.FastXmlSerializer;
 import com.android.common.XmlUtils;
+import com.android.server.JournaledFile;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -6826,6 +6827,7 @@
     private static final class Settings {
         private final File mSettingsFilename;
         private final File mBackupSettingsFilename;
+        private final File mPackageListFilename;
         private final HashMap<String, PackageSetting> mPackages =
                 new HashMap<String, PackageSetting>();
         // List of replaced system applications
@@ -6907,6 +6909,7 @@
                     -1, -1);
             mSettingsFilename = new File(systemDir, "packages.xml");
             mBackupSettingsFilename = new File(systemDir, "packages-backup.xml");
+            mPackageListFilename = new File(systemDir, "packages.list");
         }
 
         PackageSetting getPackageLP(PackageParser.Package pkg, PackageSetting origPackage,
@@ -7446,7 +7449,7 @@
                         serializer.endTag(null, "cleaning-package");
                     }
                 }
-                
+
                 serializer.endTag(null, "packages");
 
                 serializer.endDocument();
@@ -7462,6 +7465,61 @@
                         |FileUtils.S_IRGRP|FileUtils.S_IWGRP
                         |FileUtils.S_IROTH,
                         -1, -1);
+
+                // Write package list file now, use a JournaledFile.
+                //
+                File tempFile = new File(mPackageListFilename.toString() + ".tmp");
+                JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
+
+                str = new FileOutputStream(journal.chooseForWrite());
+                try {
+                    StringBuilder sb = new StringBuilder();
+                    for (PackageSetting pkg : mPackages.values()) {
+                        ApplicationInfo ai = pkg.pkg.applicationInfo;
+                        String  dataPath = ai.dataDir;
+                        boolean isDebug  = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+
+                        // Avoid any application that has a space in its path
+                        // or that is handled by the system.
+                        if (dataPath.indexOf(" ") >= 0 || ai.uid <= Process.FIRST_APPLICATION_UID)
+                            continue;
+
+                        // we store on each line the following information for now:
+                        //
+                        // pkgName    - package name
+                        // userId     - application-specific user id
+                        // debugFlag  - 0 or 1 if the package is debuggable.
+                        // dataPath   - path to package's data path
+                        //
+                        // NOTE: We prefer not to expose all ApplicationInfo flags for now.
+                        //
+                        // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
+                        // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
+                        //   system/core/run-as/run-as.c
+                        //
+                        sb.setLength(0);
+                        sb.append(ai.packageName);
+                        sb.append(" ");
+                        sb.append((int)ai.uid);
+                        sb.append(isDebug ? " 1 " : " 0 ");
+                        sb.append(dataPath);
+                        sb.append("\n");
+                        str.write(sb.toString().getBytes());
+                    }
+                    str.flush();
+                    str.close();
+                    journal.commit();
+                }
+                catch (Exception  e) {
+                    journal.rollback();
+                }
+
+                FileUtils.setPermissions(mPackageListFilename.toString(),
+                        FileUtils.S_IRUSR|FileUtils.S_IWUSR
+                        |FileUtils.S_IRGRP|FileUtils.S_IWGRP
+                        |FileUtils.S_IROTH,
+                        -1, -1);
+
                 return;
 
             } catch(XmlPullParserException e) {
@@ -7469,7 +7527,7 @@
             } catch(java.io.IOException e) {
                 Log.w(TAG, "Unable to write package manager settings, current changes will be lost at reboot", e);
             }
-            // Clean up partially written file
+            // Clean up partially written files
             if (mSettingsFilename.exists()) {
                 if (!mSettingsFilename.delete()) {
                     Log.i(TAG, "Failed to clean up mangled file: " + mSettingsFilename);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 263e6db..b57e543 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -5477,7 +5477,7 @@
                         + " fin=" + finished + " gfw=" + gotFirstWindow
                         + " ed=" + eventDispatching + " tts=" + timeToSwitch
                         + " wf=" + wasFrozen + " fp=" + focusPaused
-                        + " mcf=" + mCurrentFocus + "}}";
+                        + " mcf=" + curFocus + "}}";
             }
         };
         private DispatchState mDispatchState = null;