Merge change 26752 into eclair

* changes:
  Fix 2105956: The nine patch markers for one of the zoom buttons were reversed
diff --git a/api/current.xml b/api/current.xml
index 2672d53..c47fd5a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2825,6 +2825,17 @@
  visibility="public"
 >
 </field>
+<field name="detachWallpaper"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843430"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="detailColumn"
  type="int"
  transient="false"
@@ -162482,6 +162493,17 @@
  visibility="protected"
 >
 </method>
+<method name="getDetachWallpaper"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getDuration"
  return="long"
  abstract="false"
@@ -162728,6 +162750,19 @@
 <parameter name="listener" type="android.view.animation.Animation.AnimationListener">
 </parameter>
 </method>
+<method name="setDetachWallpaper"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="detachWallpaper" type="boolean">
+</parameter>
+</method>
 <method name="setDuration"
  return="void"
  abstract="false"
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 99e513c..c8c142d 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -14,11 +14,14 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "BootAnimation"
+
 #include <stdint.h>
 #include <sys/types.h>
 #include <math.h>
 #include <fcntl.h>
 #include <utils/misc.h>
+#include <signal.h>
 
 #include <binder/IPCThreadState.h>
 #include <utils/threads.h>
@@ -58,13 +61,29 @@
 }
 
 void BootAnimation::onFirstRef() {
-    run("BootAnimation", PRIORITY_DISPLAY);
+    status_t err = mSession->linkToComposerDeath(this);
+    LOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
+    if (err != NO_ERROR) {
+        run("BootAnimation", PRIORITY_DISPLAY);
+    }
 }
 
-const sp<SurfaceComposerClient>& BootAnimation::session() const {
+sp<SurfaceComposerClient> BootAnimation::session() const {
     return mSession;
 }
 
+
+void BootAnimation::binderDied(const wp<IBinder>& who)
+{
+    // woah, surfaceflinger died!
+    LOGD("SurfaceFlinger died, exiting...");
+
+    // calling requestExit() is not enough here because the Surface code
+    // might be blocked on a condition variable that will never be updated.
+    kill( getpid(), SIGKILL );
+    requestExit();
+}
+
 status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
         const char* name) {
     Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 796077d..afd01fa 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -37,18 +37,19 @@
 
 // ---------------------------------------------------------------------------
 
-class BootAnimation : public Thread
+class BootAnimation : public Thread, public IBinder::DeathRecipient
 {
 public:
                 BootAnimation();
     virtual     ~BootAnimation();
 
-    const sp<SurfaceComposerClient>& session() const;
+    sp<SurfaceComposerClient> session() const;
 
 private:
     virtual bool        threadLoop();
     virtual status_t    readyToRun();
     virtual void        onFirstRef();
+    virtual void        binderDied(const wp<IBinder>& who);
 
     struct Texture {
         GLint   w;
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 32a2997..2d2e75f 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -73,6 +73,10 @@
 public class AccountManagerService
         extends IAccountManager.Stub
         implements RegisteredServicesCacheListener {
+    private static final String GOOGLE_ACCOUNT_TYPE = "com.google.GAIA";
+
+    private static final String NO_BROADCAST_FLAG = "nobroadcast";
+
     private static final String TAG = "AccountManagerService";
 
     private static final int TIMEOUT_DELAY_MS = 1000 * 60;
@@ -357,6 +361,14 @@
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         db.beginTransaction();
         try {
+            boolean noBroadcast = false;
+            if (account.type.equals(GOOGLE_ACCOUNT_TYPE)) {
+                // Look for the 'nobroadcast' flag and remove it since we don't want it to persist
+                // in the db.
+                noBroadcast = extras.getBoolean(NO_BROADCAST_FLAG, false);
+                extras.remove(NO_BROADCAST_FLAG);
+            }
+
             long numMatches = DatabaseUtils.longForQuery(db,
                     "select count(*) from " + TABLE_ACCOUNTS
                             + " WHERE " + ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
@@ -381,7 +393,9 @@
                 }
             }
             db.setTransactionSuccessful();
-            sendAccountsChangedBroadcast();
+            if (!noBroadcast) {
+                sendAccountsChangedBroadcast();
+            }
             return true;
         } finally {
             db.endTransaction();
@@ -608,6 +622,10 @@
     public void setUserData(Account account, String key, String value) {
         checkAuthenticateAccountsPermission(account);
         long identityToken = clearCallingIdentity();
+        if (account.type.equals(GOOGLE_ACCOUNT_TYPE) && key.equals("broadcast")) {
+            sendAccountsChangedBroadcast();
+            return;
+        }
         try {
             writeUserdataIntoDatabase(account, key, value);
         } finally {
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index eff6f52..1c61324d 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -208,6 +208,15 @@
         }
     };
 
+    private BroadcastReceiver mBackgroundDataSettingChanged = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            if (getConnectivityManager().getBackgroundDataSetting()) {
+                scheduleSync(null /* account */, null /* authority */, new Bundle(), 0 /* delay */,
+                        false /* onlyThoseWithUnknownSyncableState */);
+            }
+        }
+    };
+
     public void onAccountsUpdated(Account[] accounts) {
         // remember if this was the first time this was called after an update
         final boolean justBootedUp = mAccounts == null;
@@ -351,6 +360,9 @@
         intentFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
         context.registerReceiver(mBootCompletedReceiver, intentFilter);
 
+        intentFilter = new IntentFilter(ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
+        context.registerReceiver(mBackgroundDataSettingChanged, intentFilter);
+
         intentFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
         intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
         context.registerReceiver(mStorageIntentReceiver, intentFilter);
@@ -687,8 +699,8 @@
                             if (isLoggable) {
                                 Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority
                                         + " is not allowed, dropping request");
-                                continue;
                             }
+                            continue;
                         }
                     }
                     if (isLoggable) {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 5f1a3c5..e47ea84 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1093,17 +1093,18 @@
         }
 
         /**
-         * Sets the orientation of the device in degrees, which instructs the
-         * camera driver to rotate the picture and thumbnail, in order to match
-         * what the user sees from the viewfinder. For example, suppose the
-         * natural position of the device is landscape. If the user takes a
+         * Sets the orientation of the device in degrees. For example, suppose
+         * the natural position of the device is landscape. If the user takes a
          * picture in landscape mode in 2048x1536 resolution, the rotation
          * should be set to 0. If the user rotates the phone 90 degrees
          * clockwise, the rotation should be set to 90. Applications can use
          * {@link android.view.OrientationEventListener} to set this parameter.
          *
-         * Since the picture is rotated, the orientation in the EXIF header is
-         * missing or always 1 (row #0 is top and column #0 is left side).
+         * The camera driver may set orientation in the EXIF header without
+         * rotating the picture. Or the driver may rotate the picture and
+         * the EXIF thumbnail. If the Jpeg picture is rotated, the orientation
+         * in the EXIF header will be missing or 1 (row #0 is top and column #0
+         * is left side).
          *
          * @param rotation The orientation of the device in degrees. Rotation
          *                 can only be 0, 90, 180 or 270.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6cf8db6..8d10fde 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3215,12 +3215,6 @@
             "vending_carrier_cred_buf_ms";
 
         /**
-         * Setting which states if German Direct Debit support should be enabled.
-         */
-        public static final String VENDING_GDD_ENABLE =
-            "vending_gdd_enable";
-
-        /**
          * URL that points to the legal terms of service to display in Settings.
          * <p>
          * This should be a https URL. For a pretty user-friendly URL, use
diff --git a/core/java/android/text/util/Rfc822Token.java b/core/java/android/text/util/Rfc822Token.java
index 7fe11bc..0edeeb5 100644
--- a/core/java/android/text/util/Rfc822Token.java
+++ b/core/java/android/text/util/Rfc822Token.java
@@ -168,5 +168,31 @@
 
         return sb.toString();
     }
+
+    public int hashCode() {
+        int result = 17;
+        if (mName != null) result = 31 * result + mName.hashCode();
+        if (mAddress != null) result = 31 * result + mAddress.hashCode();
+        if (mComment != null) result = 31 * result + mComment.hashCode();
+        return result;
+    }
+
+    private static boolean stringEquals(String a, String b) {
+        if (a == null) {
+            return (b == null);
+        } else {
+            return (a.equals(b));
+        }
+    }
+
+    public boolean equals(Object o) {
+        if (!(o instanceof Rfc822Token)) {
+            return false;
+        }
+        Rfc822Token other = (Rfc822Token) o;
+        return (stringEquals(mName, other.mName) &&
+                stringEquals(mAddress, other.mAddress) &&
+                stringEquals(mComment, other.mComment));
+    }
 }
 
diff --git a/core/java/android/text/util/Rfc822Tokenizer.java b/core/java/android/text/util/Rfc822Tokenizer.java
index d4e78b0..cb39f7d 100644
--- a/core/java/android/text/util/Rfc822Tokenizer.java
+++ b/core/java/android/text/util/Rfc822Tokenizer.java
@@ -19,6 +19,7 @@
 import android.widget.MultiAutoCompleteTextView;
 
 import java.util.ArrayList;
+import java.util.Collection;
 
 /**
  * This class works as a Tokenizer for MultiAutoCompleteTextView for
@@ -27,18 +28,22 @@
  * into a series of Rfc822Tokens.
  */
 public class Rfc822Tokenizer implements MultiAutoCompleteTextView.Tokenizer {
+
     /**
      * This constructor will try to take a string like
      * "Foo Bar (something) &lt;foo\@google.com&gt;,
      * blah\@google.com (something)"
-     * and convert it into one or more Rfc822Tokens.
+     * and convert it into one or more Rfc822Tokens, output into the supplied
+     * collection.
+     *
      * It does *not* decode MIME encoded-words; charset conversion
      * must already have taken place if necessary.
      * It will try to be tolerant of broken syntax instead of
      * returning an error.
+     *
+     * @hide
      */
-    public static Rfc822Token[] tokenize(CharSequence text) {
-        ArrayList<Rfc822Token> out = new ArrayList<Rfc822Token>();
+    public static void tokenize(CharSequence text, Collection<Rfc822Token> out) {
         StringBuilder name = new StringBuilder();
         StringBuilder address = new StringBuilder();
         StringBuilder comment = new StringBuilder();
@@ -148,7 +153,21 @@
                                     name.toString(),
                                     comment.toString()));
         }
+    }
 
+    /**
+     * This method will try to take a string like
+     * "Foo Bar (something) &lt;foo\@google.com&gt;,
+     * blah\@google.com (something)"
+     * and convert it into one or more Rfc822Tokens.
+     * It does *not* decode MIME encoded-words; charset conversion
+     * must already have taken place if necessary.
+     * It will try to be tolerant of broken syntax instead of
+     * returning an error.
+     */
+    public static Rfc822Token[] tokenize(CharSequence text) {
+        ArrayList<Rfc822Token> out = new ArrayList<Rfc822Token>();
+        tokenize(text, out);
         return out.toArray(new Rfc822Token[out.size()]);
     }
 
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 2f5e601..c8396c4 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -175,6 +175,11 @@
      */
     private int mZAdjustment;
     
+    /**
+     * Don't animate the wallpaper.
+     */
+    private boolean mDetachWallpaper = false;
+
     private boolean mMore = true;
     private boolean mOneMoreTime = true;
 
@@ -218,6 +223,8 @@
 
         setZAdjustment(a.getInt(com.android.internal.R.styleable.Animation_zAdjustment, ZORDER_NORMAL));
         
+        setDetachWallpaper(a.getBoolean(com.android.internal.R.styleable.Animation_detachWallpaper, false));
+        
         ensureInterpolator();
 
         a.recycle();
@@ -515,6 +522,19 @@
     }
     
     /**
+     * If detachWallpaper is true, and this is a window animation of a window
+     * that has a wallpaper background, then the window will be detached from
+     * the wallpaper while it runs.  That is, the animation will only be applied
+     * to the window, and the wallpaper behind it will remain static.
+     *
+     * @param detachWallpaper true if the wallpaper should be detached from the animation
+     * @attr ref android.R.styleable#Animation_detachWallpaper
+     */
+    public void setDetachWallpaper(boolean detachWallpaper) {
+        mDetachWallpaper = detachWallpaper;
+    }
+
+    /**
      * Gets the acceleration curve type for this animation.
      *
      * @return the {@link Interpolator} associated to this animation
@@ -611,6 +631,14 @@
     }
 
     /**
+     * Return value of {@link #setDetachWallpaper(boolean)}.
+     * @attr ref android.R.styleable#Animation_detachWallpaper
+     */
+    public boolean getDetachWallpaper() {
+        return mDetachWallpaper;
+    }
+
+    /**
      * <p>Indicates whether or not this animation will affect the transformation
      * matrix. For instance, a fade animation will not affect the matrix whereas
      * a scale animation will.</p>
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 002d3db..8d52917 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -332,6 +332,7 @@
     const int               width = p->readInt32();

     const int               height = p->readInt32();

     const int               rowBytes = p->readInt32();

+    const int               density = p->readInt32();

 

     if (SkBitmap::kARGB_8888_Config != config &&

             SkBitmap::kRGB_565_Config != config &&

@@ -369,12 +370,13 @@
     memcpy(bitmap->getPixels(), p->readInplace(size), size);

     bitmap->unlockPixels();

 

-    return GraphicsJNI::createBitmap(env, bitmap, isMutable, NULL);

+    return GraphicsJNI::createBitmap(env, bitmap, isMutable, NULL, density);

 }

 

 static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject,

                                      const SkBitmap* bitmap,

-                                     jboolean isMutable, jobject parcel) {

+                                     jboolean isMutable, jint density,

+                                     jobject parcel) {

     if (parcel == NULL) {

         SkDebugf("------- writeToParcel null parcel\n");

         return false;

@@ -387,6 +389,7 @@
     p->writeInt32(bitmap->width());

     p->writeInt32(bitmap->height());

     p->writeInt32(bitmap->rowBytes());

+    p->writeInt32(density);

 

     if (bitmap->getConfig() == SkBitmap::kIndex8_Config) {

         SkColorTable* ctable = bitmap->getColorTable();

@@ -546,7 +549,7 @@
     {   "nativeCreateFromParcel",

         "(Landroid/os/Parcel;)Landroid/graphics/Bitmap;",

         (void*)Bitmap_createFromParcel },

-    {   "nativeWriteToParcel",      "(IZLandroid/os/Parcel;)Z",

+    {   "nativeWriteToParcel",      "(IZILandroid/os/Parcel;)Z",

         (void*)Bitmap_writeToParcel },

     {   "nativeExtractAlpha",       "(II[I)Landroid/graphics/Bitmap;",

         (void*)Bitmap_extractAlpha },

diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index ca1cb7d..2e0caed 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -351,7 +351,7 @@
 ///////////////////////////////////////////////////////////////////////////////////////////
 
 jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
-                                  jbyteArray ninepatch)
+                                  jbyteArray ninepatch, int density)
 {
     SkASSERT(bitmap != NULL);
     SkASSERT(NULL != bitmap->pixelRef());
@@ -359,7 +359,7 @@
     jobject obj = env->AllocObject(gBitmap_class);
     if (obj) {
         env->CallVoidMethod(obj, gBitmap_constructorMethodID,
-                            (jint)bitmap, isMutable, ninepatch);
+                            (jint)bitmap, isMutable, ninepatch, density);
         if (hasException(env)) {
             obj = NULL;
         }
@@ -541,7 +541,7 @@
     gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
     gBitmap_nativeInstanceID = getFieldIDCheck(env, gBitmap_class, "mNativeBitmap", "I");    
     gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
-                                            "(IZ[B)V");
+                                            "(IZ[BI)V");
 
     gBitmapConfig_class = make_globalref(env, "android/graphics/Bitmap$Config");
     gBitmapConfig_nativeInstanceID = getFieldIDCheck(env, gBitmapConfig_class,
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index f8b60a8..7adadbc 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -50,7 +50,7 @@
         then the bitmap must be an owner of its natively allocated pixels (via allocPixels).
         */
     static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
-                                jbyteArray ninePatch);
+                                jbyteArray ninePatch, int density = -1);
     
     static jobject createRegion(JNIEnv* env, SkRegion* region);
 
diff --git a/core/jni/android_emoji_EmojiFactory.cpp b/core/jni/android_emoji_EmojiFactory.cpp
index 4c213a31..63550fb 100644
--- a/core/jni/android_emoji_EmojiFactory.cpp
+++ b/core/jni/android_emoji_EmojiFactory.cpp
@@ -184,7 +184,7 @@
   jobject obj = env->AllocObject(gBitmap_class);
   if (obj) {
     env->CallVoidMethod(obj, gBitmap_constructorMethodID,
-                        reinterpret_cast<jint>(bitmap), false, NULL);
+                        reinterpret_cast<jint>(bitmap), false, NULL, -1);
     if (env->ExceptionCheck() != 0) {
       LOGE("*** Uncaught exception returned from Java call!\n");
       env->ExceptionDescribe();
@@ -297,7 +297,7 @@
 int register_android_emoji_EmojiFactory(JNIEnv* env) {
   gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
   gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
-                                                 "(IZ[B)V");
+                                                 "(IZ[BI)V");
   gEmojiFactory_class = make_globalref(env, "android/emoji/EmojiFactory");
   gEmojiFactory_constructorMethodID = env->GetMethodID(
       gEmojiFactory_class, "<init>", "(ILjava/lang/String;)V");
diff --git a/core/res/res/anim/wallpaper_close_enter.xml b/core/res/res/anim/wallpaper_close_enter.xml
index 0d13009..5bc299e 100644
--- a/core/res/res/anim/wallpaper_close_enter.xml
+++ b/core/res/res/anim/wallpaper_close_enter.xml
@@ -18,7 +18,21 @@
 -->
 
 <!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper, without zooming the wallpaper itself. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="2.0" android:toXScale="1.0"
+           android:fromYScale="2.0" android:toYScale="1.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="0" android:toAlpha="1.0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
+
+<!-- This version zooms the new non-wallpaper down on top of the
      wallpaper. -->
+<!-- 
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
     <scale android:fromXScale="2.0" android:toXScale="1.0"
@@ -26,6 +40,7 @@
            android:pivotX="50%p" android:pivotY="50%p"
            android:duration="@android:integer/config_mediumAnimTime" />
 </set>
+-->
 
 <!-- This version is a variation on the inter-activity slide that
     also scales the wallpaper. -->
diff --git a/core/res/res/anim/wallpaper_close_exit.xml b/core/res/res/anim/wallpaper_close_exit.xml
index 5d91e30..c3ae620 100644
--- a/core/res/res/anim/wallpaper_close_exit.xml
+++ b/core/res/res/anim/wallpaper_close_exit.xml
@@ -18,7 +18,19 @@
 -->
 
 <!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper, without zooming the wallpaper itself. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:detachWallpaper="true">
+    <scale android:fromXScale="1.0" android:toXScale=".5"
+           android:fromYScale="1.0" android:toYScale=".5"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+</set>
+
+<!-- This version zooms the new non-wallpaper down on top of the
      wallpaper.  The wallpaper here just stays fixed behind. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator"
         android:zAdjustment="top">
@@ -29,6 +41,7 @@
     <alpha android:fromAlpha="1.0" android:toAlpha="0"
             android:duration="@android:integer/config_mediumAnimTime"/>
 </set>
+-->
 
 <!-- This version is a variation on the inter-activity slide that
     also scales the wallpaper. -->
diff --git a/core/res/res/anim/wallpaper_open_enter.xml b/core/res/res/anim/wallpaper_open_enter.xml
index cf27cf0..7fe7e1e 100644
--- a/core/res/res/anim/wallpaper_open_enter.xml
+++ b/core/res/res/anim/wallpaper_open_enter.xml
@@ -17,8 +17,20 @@
 */
 -->
 
+<!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper, without zooming the wallpaper itself. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:detachWallpaper="true">
+    <scale android:fromXScale=".5" android:toXScale="1.0"
+           android:fromYScale=".5" android:toYScale="1.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+</set>
+
 <!-- This version zooms the new non-wallpaper up off the wallpaper the
      wallpaper.  The wallpaper here just stays fixed behind. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator"
         android:zAdjustment="top">
@@ -29,6 +41,7 @@
     <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
             android:duration="@android:integer/config_mediumAnimTime"/>
 </set>
+-->
 
 <!-- This version is a variation on the inter-activity slide that
     also scales the wallpaper. -->
diff --git a/core/res/res/anim/wallpaper_open_exit.xml b/core/res/res/anim/wallpaper_open_exit.xml
index b7a539c..9489c6d 100644
--- a/core/res/res/anim/wallpaper_open_exit.xml
+++ b/core/res/res/anim/wallpaper_open_exit.xml
@@ -18,7 +18,21 @@
 -->
 
 <!-- This version zooms the new non-wallpaper down on top of the
+     wallpaper, without zooming the wallpaper itself. -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="1.0" android:toXScale="2.0"
+           android:fromYScale="1.0" android:toYScale="2.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
+
+<!-- This version zooms the new non-wallpaper down on top of the
      wallpaper. -->
+<!--
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@anim/decelerate_interpolator">
     <scale android:fromXScale="1.0" android:toXScale="2.0"
@@ -26,6 +40,7 @@
            android:pivotX="50%p" android:pivotY="50%p"
            android:duration="@android:integer/config_mediumAnimTime" />
 </set>
+-->
 
 <!-- This version is a variation on the inter-activity slide that
     also scales the wallpaper. -->
diff --git a/core/res/res/drawable-hdpi/textfield_default.9.png b/core/res/res/drawable-hdpi/textfield_default.9.png
index a2f022a..4c20179 100644
--- a/core/res/res/drawable-hdpi/textfield_default.9.png
+++ b/core/res/res/drawable-hdpi/textfield_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled.9.png b/core/res/res/drawable-hdpi/textfield_disabled.9.png
index 6a28cb4..81569d1 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_disabled_selected.9.png b/core/res/res/drawable-hdpi/textfield_disabled_selected.9.png
index 0de9cda..2591490 100644
--- a/core/res/res/drawable-hdpi/textfield_disabled_selected.9.png
+++ b/core/res/res/drawable-hdpi/textfield_disabled_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_pressed.9.png b/core/res/res/drawable-hdpi/textfield_pressed.9.png
index d5892c8..a42d87f 100644
--- a/core/res/res/drawable-hdpi/textfield_pressed.9.png
+++ b/core/res/res/drawable-hdpi/textfield_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_selected.9.png b/core/res/res/drawable-hdpi/textfield_selected.9.png
index 7a072dd..a36ed72 100644
--- a/core/res/res/drawable-hdpi/textfield_selected.9.png
+++ b/core/res/res/drawable-hdpi/textfield_selected.9.png
Binary files differ
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 193fdb2..df2a715 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2639,6 +2639,9 @@
                  content for the duration of the animation. -->
             <enum name="bottom" value="-1" />
         </attr>
+        <!-- Special option for window animations: if this window is on top
+             of a wallpaper, don't animate the wallpaper with it. -->
+        <attr name="detachWallpaper" format="boolean" />
     </declare-styleable>
 
     <declare-styleable name="RotateAnimation">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 4d23ef4..305e415 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1170,6 +1170,7 @@
   <public type="attr" name="detailColumn" />
   <public type="attr" name="detailSocialSummary" />
   <public type="attr" name="thumbnail" />
+  <public type="attr" name="detachWallpaper" />
 
   <public type="style" name="Theme.Wallpaper" />
   <public type="style" name="Theme.Wallpaper.NoTitleBar" />
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index eef1096..216dea0 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -77,7 +77,8 @@
 
         This can be called from JNI code.
     */
-    private Bitmap(int nativeBitmap, boolean isMutable, byte[] ninePatchChunk) {
+    private Bitmap(int nativeBitmap, boolean isMutable, byte[] ninePatchChunk,
+            int density) {
         if (nativeBitmap == 0) {
             throw new RuntimeException("internal error: native bitmap is 0");
         }
@@ -86,6 +87,9 @@
         mNativeBitmap = nativeBitmap;
         mIsMutable = isMutable;
         mNinePatchChunk = ninePatchChunk;
+        if (density >= 0) {
+            mDensity = density;
+        }
     }
 
     /**
@@ -892,7 +896,7 @@
      */
     public void writeToParcel(Parcel p, int flags) {
         checkRecycled("Can't parcel a recycled bitmap");
-        if (!nativeWriteToParcel(mNativeBitmap, mIsMutable, p)) {
+        if (!nativeWriteToParcel(mNativeBitmap, mIsMutable, mDensity, p)) {
             throw new RuntimeException("native writeToParcel failed");
         }
     }
@@ -1006,6 +1010,7 @@
     // returns true on success
     private static native boolean nativeWriteToParcel(int nativeBitmap,
                                                       boolean isMutable,
+                                                      int density,
                                                       Parcel p);
     // returns a new bitmap built from the native bitmap's alpha, and the paint
     private static native Bitmap nativeExtractAlpha(int nativeBitmap,
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
new file mode 100644
index 0000000..ab327f1
--- /dev/null
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -0,0 +1,110 @@
+/*
+ * 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 android.util.Config;
+import android.util.Log;
+
+
+/**
+ * @hide
+ *
+ **/
+public class ProgramRaster extends BaseObj {
+    boolean mPointSmooth;
+    boolean mLineSmooth;
+    boolean mPointSprite;
+    float mPointSize;
+    float mLineWidth;
+    Element mIn;
+    Element mOut;
+
+    ProgramRaster(int id, RenderScript rs) {
+        super(rs);
+        mID = id;
+
+        mPointSize = 1.0f;
+        mLineWidth = 1.0f;
+        mPointSmooth = false;
+        mLineSmooth = false;
+        mPointSprite = false;
+    }
+
+    public void setLineWidth(float w) {
+        mLineWidth = w;
+        mRS.nProgramRasterSetLineWidth(mID, w);
+    }
+
+    public void setPointSize(float s) {
+        mPointSize = s;
+        mRS.nProgramRasterSetPointSize(mID, s);
+    }
+
+    void internalInit() {
+        int inID = 0;
+        int outID = 0;
+        if (mIn != null) {
+            inID = mIn.mID;
+        }
+        if (mOut != null) {
+            outID = mOut.mID;
+        }
+        mID = mRS.nProgramRasterCreate(inID, outID, mPointSmooth, mLineSmooth, mPointSprite);
+    }
+
+
+    public static class Builder {
+        RenderScript mRS;
+        ProgramRaster mPR;
+
+        public Builder(RenderScript rs, Element in, Element out) {
+            mRS = rs;
+            mPR = new ProgramRaster(0, rs);
+        }
+
+        public void setPointSpriteEnable(boolean enable) {
+            mPR.mPointSprite = enable;
+        }
+
+        public void setPointSmoothEnable(boolean enable) {
+            mPR.mPointSmooth = enable;
+        }
+
+        public void setLineSmoothEnable(boolean enable) {
+            mPR.mLineSmooth = enable;
+        }
+
+
+        static synchronized ProgramRaster internalCreate(RenderScript rs, Builder b) {
+            b.mPR.internalInit();
+            ProgramRaster pr = b.mPR;
+            b.mPR = new ProgramRaster(0, b.mRS);
+            return pr;
+        }
+
+        public ProgramRaster create() {
+            return internalCreate(mRS, this);
+        }
+    }
+
+}
+
+
+
+
+
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index a3f1ded..3d6acc9 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -133,14 +133,19 @@
 
     // ----------------------------------------------------------------------
 
-    public RenderScript createRenderScript(boolean useDepth) {
+    public RenderScript createRenderScript(boolean useDepth, boolean forceSW) {
         Surface sur = null;
         while ((sur == null) || (mSurfaceHolder == null)) {
             sur = getHolder().getSurface();
         }
-        RenderScript rs = new RenderScript(sur, useDepth);
+        RenderScript rs = new RenderScript(sur, useDepth, forceSW);
         return rs;
     }
 
+    public RenderScript createRenderScript(boolean useDepth) {
+        return createRenderScript(useDepth, false);
+    }
+
+
 }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 5831d13..1ce7083 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -61,6 +61,7 @@
 
     native int  nDeviceCreate();
     native void nDeviceDestroy(int dev);
+    native void nDeviceSetConfig(int dev, int param, int value);
     native int  nContextCreate(int dev, Surface sur, int ver, boolean useDepth);
     native void nContextDestroy(int con);
 
@@ -71,6 +72,7 @@
     native void nContextBindProgramFragmentStore(int pfs);
     native void nContextBindProgramFragment(int pf);
     native void nContextBindProgramVertex(int pf);
+    native void nContextBindProgramRaster(int pr);
     native void nContextAddDefineI32(String name, int value);
     native void nContextAddDefineF(String name, float value);
 
@@ -163,6 +165,10 @@
     native void nProgramFragmentStoreDither(boolean enable);
     native int  nProgramFragmentStoreCreate();
 
+    native int  nProgramRasterCreate(int in, int out, boolean pointSmooth, boolean lineSmooth, boolean pointSprite);
+    native void nProgramRasterSetLineWidth(int pr, float v);
+    native void nProgramRasterSetPointSize(int pr, float v);
+
     native void nProgramFragmentBegin(int in, int out, boolean pointSpriteEnable);
     native void nProgramFragmentBindTexture(int vpf, int slot, int a);
     native void nProgramFragmentBindSampler(int vpf, int slot, int s);
@@ -200,9 +206,12 @@
     ///////////////////////////////////////////////////////////////////////////////////
     //
 
-    public RenderScript(Surface sur, boolean useDepth) {
+    public RenderScript(Surface sur, boolean useDepth, boolean forceSW) {
         mSurface = sur;
         mDev = nDeviceCreate();
+        if(forceSW) {
+            nDeviceSetConfig(mDev, 0, 1);
+        }
         mContext = nContextCreate(mDev, mSurface, 0, useDepth);
 
         // TODO: This should be protected by a lock
@@ -312,6 +321,10 @@
         nContextBindProgramFragment(pf.mID);
     }
 
+    public void contextBindProgramRaster(ProgramRaster pf) {
+        nContextBindProgramRaster(pf.mID);
+    }
+
     public void contextBindProgramVertex(ProgramVertex pf) {
         nContextBindProgramVertex(pf.mID);
     }
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 56a4223..4a8f8a3 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -143,6 +143,13 @@
     return rsDeviceDestroy((RsDevice)dev);
 }
 
+static void
+nDeviceSetConfig(JNIEnv *_env, jobject _this, jint dev, jint p, jint value)
+{
+    LOG_API("nDeviceSetConfig  dev(%p), param(%i), value(%i)", (void *)dev, p, value);
+    return rsDeviceSetConfig((RsDevice)dev, (RsDeviceParam)p, value);
+}
+
 static jint
 nContextCreate(JNIEnv *_env, jobject _this, jint dev, jobject wnd, jint ver, jboolean useDepth)
 {
@@ -1132,6 +1139,34 @@
 }
 
 
+// ---------------------------------------------------------------------------
+
+static jint
+nProgramRasterCreate(JNIEnv *_env, jobject _this, jint in, jint out,
+                     jboolean pointSmooth, jboolean lineSmooth, jboolean pointSprite)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramRasterCreate, con(%p), in(%p), out(%p), pointSmooth(%i), lineSmooth(%i), pointSprite(%i)",
+            con, (RsElement)in, (RsElement)out, pointSmooth, lineSmooth, pointSprite);
+    return (jint)rsProgramRasterCreate(con, (RsElement)in, (RsElement)out, pointSmooth, lineSmooth, pointSprite);
+}
+
+static void
+nProgramRasterSetPointSize(JNIEnv *_env, jobject _this, jint vpr, jfloat v)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramRasterSetPointSize, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v);
+    rsProgramRasterSetPointSize(con, (RsProgramFragment)vpr, v);
+}
+
+static void
+nProgramRasterSetLineWidth(JNIEnv *_env, jobject _this, jint vpr, jfloat v)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nProgramRasterSetLineWidth, con(%p), vpf(%p), value(%f)", con, (RsProgramRaster)vpr, v);
+    rsProgramRasterSetLineWidth(con, (RsProgramFragment)vpr, v);
+}
+
 
 // ---------------------------------------------------------------------------
 
@@ -1168,6 +1203,14 @@
 }
 
 static void
+nContextBindProgramRaster(JNIEnv *_env, jobject _this, jint pf)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nContextBindProgramRaster, con(%p), pf(%p)", con, (RsProgramRaster)pf);
+    rsContextBindProgramRaster(con, (RsProgramRaster)pf);
+}
+
+static void
 nContextAddDefineI32(JNIEnv *_env, jobject _this, jstring name, jint value)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -1306,6 +1349,7 @@
 
 {"nDeviceCreate",                  "()I",                                  (void*)nDeviceCreate },
 {"nDeviceDestroy",                 "(I)V",                                 (void*)nDeviceDestroy },
+{"nDeviceSetConfig",               "(III)V",                               (void*)nDeviceSetConfig },
 {"nContextCreate",                 "(ILandroid/view/Surface;IZ)I",         (void*)nContextCreate },
 {"nContextDestroy",                "(I)V",                                 (void*)nContextDestroy },
 {"nAssignName",                    "(I[B)V",                               (void*)nAssignName },
@@ -1396,6 +1440,10 @@
 {"nProgramFragmentSetSlot",        "(IZII)V",                              (void*)nProgramFragmentSetSlot },
 {"nProgramFragmentCreate",         "()I",                                  (void*)nProgramFragmentCreate },
 
+{"nProgramRasterCreate",           "(IIZZZ)I",                             (void*)nProgramRasterCreate },
+{"nProgramRasterSetPointSize",     "(IF)V",                                (void*)nProgramRasterSetPointSize },
+{"nProgramRasterSetLineWidth",     "(IF)V",                                (void*)nProgramRasterSetLineWidth },
+
 {"nProgramVertexBindAllocation",   "(II)V",                                (void*)nProgramVertexBindAllocation },
 {"nProgramVertexBegin",            "(II)V",                                (void*)nProgramVertexBegin },
 {"nProgramVertexSetTextureMatrixEnable",   "(Z)V",                         (void*)nProgramVertexSetTextureMatrixEnable },
@@ -1413,6 +1461,7 @@
 {"nContextBindProgramFragmentStore","(I)V",                                (void*)nContextBindProgramFragmentStore },
 {"nContextBindProgramFragment",    "(I)V",                                 (void*)nContextBindProgramFragment },
 {"nContextBindProgramVertex",      "(I)V",                                 (void*)nContextBindProgramVertex },
+{"nContextBindProgramRaster",      "(I)V",                                 (void*)nContextBindProgramRaster },
 
 {"nSamplerBegin",                  "()V",                                  (void*)nSamplerBegin },
 {"nSamplerSet",                    "(II)V",                                (void*)nSamplerSet },
diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h
index 269959c..8701928 100644
--- a/include/ui/SurfaceComposerClient.h
+++ b/include/ui/SurfaceComposerClient.h
@@ -20,6 +20,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <binder/IBinder.h>
+
 #include <utils/SortedVector.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
@@ -106,6 +108,8 @@
     static ssize_t getDisplayHeight(DisplayID dpy);
     static ssize_t getDisplayOrientation(DisplayID dpy);
 
+    status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
+            void* cookie = NULL, uint32_t flags = 0);
 
 private:
     friend class Surface;
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index bc466be..2c17599 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -90,6 +90,7 @@
 	rsProgram.cpp \
 	rsProgramFragment.cpp \
 	rsProgramFragmentStore.cpp \
+	rsProgramRaster.cpp \
 	rsProgramVertex.cpp \
 	rsSampler.cpp \
 	rsScript.cpp \
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 1e24cd2..9f18b78 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -45,9 +45,16 @@
 typedef void * RsProgramVertex;
 typedef void * RsProgramFragment;
 typedef void * RsProgramFragmentStore;
+typedef void * RsProgramRaster;
+
+enum RsDeviceParam {
+    RS_DEVICE_PARAM_FORCE_SOFTWARE_GL,
+    RS_DEVICE_PARAM_COUNT
+};
 
 RsDevice rsDeviceCreate();
 void rsDeviceDestroy(RsDevice);
+void rsDeviceSetConfig(RsDevice, RsDeviceParam, int32_t value);
 
 RsContext rsContextCreate(RsDevice, void *, uint32_t version, bool useDepth);
 void rsContextDestroy(RsContext);
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 7826161..1b07f98 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
@@ -52,7 +52,7 @@
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
         super.surfaceChanged(holder, format, w, h);
 
-        mRS = createRenderScript(false);
+        mRS = createRenderScript(false, true);
         mRender = new FountainRS();
         mRender.init(mRS, getResources(), w, h);
     }
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 87ad97c..d7ae532 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -16,6 +16,10 @@
 	param RsProgramVertex pgm
 	}
 
+ContextBindProgramRaster {
+	param RsProgramRaster pgm
+	}
+
 ContextSetDefineF {
     param const char* name
     param float value
@@ -369,6 +373,24 @@
 	ret RsProgramFragmentStore
 	}
 
+ProgramRasterCreate {
+	param RsElement in
+	param RsElement out
+	param bool pointSmooth
+	param bool lineSmooth
+	param bool pointSprite
+	ret RsProgramRaster
+}
+
+ProgramRasterSetLineWidth {
+	param RsProgramRaster pr
+	param float lw
+}
+
+ProgramRasterSetPointSize{
+	param RsProgramRaster pr
+	param float ps
+}
 
 
 ProgramFragmentBegin {
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 3e4c9af..cc11ab2 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -20,12 +20,16 @@
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/EGLUtils.h>
 
+#include <cutils/properties.h>
+
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
 using namespace android;
 using namespace android::renderscript;
 
+bool g_logTimes = -1;
+
 pthread_key_t Context::gThreadTLSKey = 0;
 
 void Context::initEGL()
@@ -46,6 +50,12 @@
         configAttribsPtr += 2;
     }
 
+    if (mDev->mForceSW) {
+        configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
+        configAttribsPtr[1] = EGL_SLOW_CONFIG;
+        configAttribsPtr += 2;
+    }
+
     configAttribsPtr[0] = EGL_NONE;
     rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint))));
 
@@ -107,16 +117,16 @@
 
 bool Context::runRootScript()
 {
-#if RS_LOG_TIMES
-    timerSet(RS_TIMER_CLEAR_SWAP);
-#endif
+    if (this->logTimes) {
+        timerSet(RS_TIMER_CLEAR_SWAP);
+    }
     rsAssert(mRootScript->mEnviroment.mIsRoot);
 
     eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
     eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_HEIGHT, &mEGL.mHeight);
     glViewport(0, 0, mEGL.mWidth, mEGL.mHeight);
     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-    glEnable(GL_POINT_SMOOTH);
+    //glEnable(GL_POINT_SMOOTH);
 
     glClearColor(mRootScript->mEnviroment.mClearColor[0],
                  mRootScript->mEnviroment.mClearColor[1],
@@ -130,9 +140,9 @@
         glClear(GL_COLOR_BUFFER_BIT);
     }
 
-#if RS_LOG_TIMES
-    timerSet(RS_TIMER_SCRIPT);
-#endif
+    if (this->logTimes) {
+        timerSet(RS_TIMER_SCRIPT);
+    }
     bool ret = runScript(mRootScript.get(), 0);
     return ret;
 }
@@ -192,23 +202,25 @@
 
 void Context::setupCheck()
 {
-    if (mFragmentStore.get()) {
-        mFragmentStore->setupGL(this, &mStateFragmentStore);
-    }
-    if (mFragment.get()) {
-        mFragment->setupGL(this, &mStateFragment);
-    }
-    if (mVertex.get()) {
-        mVertex->setupGL(this, &mStateVertex);
-    }
-
+    mFragmentStore->setupGL(this, &mStateFragmentStore);
+    mFragment->setupGL(this, &mStateFragment);
+    mRaster->setupGL(this, &mStateRaster);
+    mVertex->setupGL(this, &mStateVertex);
 }
 
+static bool get_log_times()
+{
+    char buf[PROPERTY_VALUE_MAX];
+    property_get("debug.rs.profile", buf, "0");
+    return 0 != strcmp(buf, "0");
+}
 
 void * Context::threadProc(void *vrsc)
 {
      Context *rsc = static_cast<Context *>(vrsc);
 
+     rsc->logTimes = get_log_times();
+
      rsc->initEGL();
 
      ScriptTLSStruct *tlsStruct = new ScriptTLSStruct;
@@ -223,6 +235,8 @@
          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);
@@ -238,16 +252,16 @@
 
          if (mDraw) {
              mDraw = rsc->runRootScript();
-#if RS_LOG_TIMES
-             rsc->timerSet(RS_TIMER_CLEAR_SWAP);
-#endif
+             if (rsc->logTimes) {
+                 rsc->timerSet(RS_TIMER_CLEAR_SWAP);
+             }
              eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
-#if RS_LOG_TIMES
-             rsc->timerFrame();
-             rsc->timerSet(RS_TIMER_INTERNAL);
-             rsc->timerPrint();
-             rsc->timerReset();
-#endif
+             if (rsc->logTimes) {
+                 rsc->timerFrame();
+                 rsc->timerSet(RS_TIMER_INTERNAL);
+                 rsc->timerPrint();
+                 rsc->timerReset();
+             }
          }
          if (rsc->mObjDestroy.mNeedToEmpty) {
              rsc->objDestroyOOBRun();
@@ -350,6 +364,15 @@
     }
 }
 
+void Context::setRaster(ProgramRaster *pr)
+{
+    if (pr == NULL) {
+        mRaster.set(mStateRaster.mDefault);
+    } else {
+        mRaster.set(pr);
+    }
+}
+
 void Context::allocationCheck(const Allocation *a)
 {
     mVertex->checkUpdatedAllocation(a);
@@ -519,6 +542,12 @@
     rsc->setFragment(pf);
 }
 
+void rsi_ContextBindProgramRaster(Context *rsc, RsProgramRaster vpr)
+{
+    ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
+    rsc->setRaster(pr);
+}
+
 void rsi_ContextBindProgramVertex(Context *rsc, RsProgramVertex vpv)
 {
     ProgramVertex *pv = static_cast<ProgramVertex *>(vpv);
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 634416b..1fb697a 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -36,6 +36,7 @@
 #include "rsLight.h"
 #include "rsProgramFragment.h"
 #include "rsProgramFragmentStore.h"
+#include "rsProgramRaster.h"
 #include "rsProgramVertex.h"
 
 #include "rsgApiStructs.h"
@@ -65,6 +66,7 @@
     SamplerState mStateSampler;
     ProgramFragmentState mStateFragment;
     ProgramFragmentStoreState mStateFragmentStore;
+    ProgramRasterState mStateRaster;
     ProgramVertexState mStateVertex;
     LightState mStateLight;
 
@@ -74,6 +76,7 @@
 
     void swapBuffers();
     void setRootScript(Script *);
+    void setRaster(ProgramRaster *);
     void setVertex(ProgramVertex *);
     void setFragment(ProgramFragment *);
     void setFragmentStore(ProgramFragmentStore *);
@@ -82,6 +85,7 @@
 
     const ProgramFragment * getFragment() {return mFragment.get();}
     const ProgramFragmentStore * getFragmentStore() {return mFragmentStore.get();}
+    const ProgramRaster * getRaster() {return mRaster.get();}
     const ProgramVertex * getVertex() {return mVertex.get();}
 
     void setupCheck();
@@ -102,6 +106,9 @@
     ProgramFragmentStore * getDefaultProgramFragmentStore() const {
         return mStateFragmentStore.mDefault.get();
     }
+    ProgramRaster * getDefaultProgramRaster() const {
+        return mStateRaster.mDefault.get();
+    }
 
     void addInt32Define(const char* name, int32_t value) {
         mInt32Defines.add(String8(name), value);
@@ -136,6 +143,8 @@
     bool checkVersion1_1() const {return (mGL.mMajorVersion > 1) || (mGL.mMinorVersion >= 1); }
     bool checkVersion2_0() const {return mGL.mMajorVersion >= 2; }
 
+    bool logTimes;
+
 protected:
     Device *mDev;
 
@@ -172,6 +181,7 @@
     ObjectBaseRef<ProgramFragment> mFragment;
     ObjectBaseRef<ProgramVertex> mVertex;
     ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
+    ObjectBaseRef<ProgramRaster> mRaster;
 
 
     struct ObjDestroyOOB {
@@ -207,7 +217,6 @@
     uint64_t mTimeLastFrame;
 };
 
-
 }
 }
 #endif
diff --git a/libs/rs/rsDevice.cpp b/libs/rs/rsDevice.cpp
index 1b3c41b..b670ad4 100644
--- a/libs/rs/rsDevice.cpp
+++ b/libs/rs/rsDevice.cpp
@@ -22,6 +22,7 @@
 
 Device::Device()
 {
+    mForceSW = false;
 
 }
 
@@ -60,3 +61,13 @@
 
 }
 
+void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value)
+{
+    Device * d = static_cast<Device *>(dev);
+    if (p == RS_DEVICE_PARAM_FORCE_SOFTWARE_GL) {
+        d->mForceSW = value != 0;
+        return;
+    }
+    rsAssert(0);
+}
+
diff --git a/libs/rs/rsDevice.h b/libs/rs/rsDevice.h
index 156315f..a8a4e77 100644
--- a/libs/rs/rsDevice.h
+++ b/libs/rs/rsDevice.h
@@ -33,6 +33,8 @@
     void addContext(Context *);
     void removeContext(Context *);
 
+    bool mForceSW;
+
 protected:
     Vector<Context *> mContexts;
 
diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp
new file mode 100644
index 0000000..0f5ec51
--- /dev/null
+++ b/libs/rs/rsProgramRaster.cpp
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+#include "rsContext.h"
+#include "rsProgramRaster.h"
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+
+ProgramRaster::ProgramRaster(Element *in,
+                             Element *out,
+                             bool pointSmooth,
+                             bool lineSmooth,
+                             bool pointSprite) :
+    Program(in, out)
+{
+    mPointSmooth = pointSmooth;
+    mLineSmooth = lineSmooth;
+    mPointSprite = pointSprite;
+
+    mPointSize = 1.0f;
+    mLineWidth = 1.0f;
+}
+
+ProgramRaster::~ProgramRaster()
+{
+}
+
+void ProgramRaster::setLineWidth(float s)
+{
+    mLineWidth = s;
+}
+
+void ProgramRaster::setPointSize(float s)
+{
+    mPointSize = s;
+}
+
+void ProgramRaster::setupGL(const Context *rsc, ProgramRasterState *state)
+{
+    if (state->mLast.get() == this) {
+        return;
+    }
+    state->mLast.set(this);
+
+    LOGE("setup %i %i %i %f %f", mPointSmooth, mLineSmooth, mPointSprite, mPointSize, mLineWidth);
+
+    glPointSize(mPointSize);
+    if (mPointSmooth) {
+        glEnable(GL_POINT_SMOOTH);
+    } else {
+        glDisable(GL_POINT_SMOOTH);
+    }
+
+    glLineWidth(mLineWidth);
+    if (mLineSmooth) {
+        glEnable(GL_LINE_SMOOTH);
+    } else {
+        glEnable(GL_LINE_SMOOTH);
+    }
+
+    if (rsc->checkVersion1_1()) {
+        if (mPointSprite) {
+            glEnable(GL_POINT_SPRITE_OES);
+        } else {
+            glDisable(GL_POINT_SPRITE_OES);
+        }
+    }
+}
+
+
+
+ProgramRasterState::ProgramRasterState()
+{
+}
+
+ProgramRasterState::~ProgramRasterState()
+{
+}
+
+void ProgramRasterState::init(Context *rsc, int32_t w, int32_t h)
+{
+    ProgramRaster *pr = new ProgramRaster(NULL, NULL, false, false, false);
+    mDefault.set(pr);
+}
+
+
+namespace android {
+namespace renderscript {
+
+RsProgramRaster rsi_ProgramRasterCreate(Context * rsc, RsElement in, RsElement out,
+                                      bool pointSmooth,
+                                      bool lineSmooth,
+                                      bool pointSprite)
+{
+    ProgramRaster *pr = new ProgramRaster(static_cast<Element *>(in),
+                                          static_cast<Element *>(out),
+                                          pointSmooth,
+                                          lineSmooth,
+                                          pointSprite);
+    pr->incUserRef();
+    return pr;
+}
+
+void rsi_ProgramRasterSetPointSize(Context * rsc, RsProgramRaster vpr, float s)
+{
+    ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
+    pr->setPointSize(s);
+}
+
+void rsi_ProgramRasterSetLineWidth(Context * rsc, RsProgramRaster vpr, float s)
+{
+    ProgramRaster *pr = static_cast<ProgramRaster *>(vpr);
+    pr->setLineWidth(s);
+}
+
+
+}
+}
+
diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h
new file mode 100644
index 0000000..5984868
--- /dev/null
+++ b/libs/rs/rsProgramRaster.h
@@ -0,0 +1,72 @@
+/*
+ * 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_PROGRAM_RASTER_H
+#define ANDROID_RS_PROGRAM_RASTER_H
+
+#include "rsProgram.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class ProgramRasterState;
+
+class ProgramRaster : public Program
+{
+public:
+    ProgramRaster(Element *in,
+                  Element *out,
+                  bool pointSmooth,
+                  bool lineSmooth,
+                  bool pointSprite);
+    virtual ~ProgramRaster();
+
+    virtual void setupGL(const Context *, ProgramRasterState *);
+
+    void setLineWidth(float w);
+    void setPointSize(float s);
+
+protected:
+    bool mPointSmooth;
+    bool mLineSmooth;
+    bool mPointSprite;
+
+    float mPointSize;
+    float mLineWidth;
+
+
+};
+
+class ProgramRasterState
+{
+public:
+    ProgramRasterState();
+    ~ProgramRasterState();
+    void init(Context *rsc, int32_t w, int32_t h);
+
+    ObjectBaseRef<ProgramRaster> mDefault;
+    ObjectBaseRef<ProgramRaster> mLast;
+};
+
+
+}
+}
+#endif
+
+
+
+
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index db4bb81..4072f06 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -42,13 +42,13 @@
         uint32_t cmdID = 0;
         uint32_t cmdSize = 0;
         ret = true;
-#if RS_LOG_TIMES
-        con->timerSet(Context::RS_TIMER_IDLE);
-#endif
+        if (con->logTimes) {
+            con->timerSet(Context::RS_TIMER_IDLE);
+        }
         const void * data = mToCore.get(&cmdID, &cmdSize);
-#if RS_LOG_TIMES
-        con->timerSet(Context::RS_TIMER_INTERNAL);
-#endif
+        if (con->logTimes) {
+            con->timerSet(Context::RS_TIMER_INTERNAL);
+        }
         waitForCommand = false;
         //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize);
 
diff --git a/libs/rs/rsUtils.h b/libs/rs/rsUtils.h
index ec928db..63d73a1 100644
--- a/libs/rs/rsUtils.h
+++ b/libs/rs/rsUtils.h
@@ -41,8 +41,6 @@
 #define rsAssert(v) while(0)
 #endif
 
-#define RS_LOG_TIMES 0
-
 template<typename T>
 T rsMin(T in1, T in2)
 {
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 5ff9284..8dfc2cf 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -88,6 +88,7 @@
         mBuffers[i].clear();
         mWidth = mHeight = 0;
     }
+    mSurface.clear();
 }
 
 sp<LayerBaseClient::Surface> Layer::createSurface() const
@@ -98,8 +99,7 @@
 status_t Layer::ditch()
 {
     // the layer is not on screen anymore. free as much resources as possible
-    //destroy();
-    mSurface.clear();
+    destroy();
     return NO_ERROR;
 }
 
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 831c446..e87b563 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1084,12 +1084,9 @@
 
 status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
 {
-    // First add the layer to the purgatory list, which makes sure it won't 
-    // go away, then remove it from the main list (through a transaction).
+    // remove the layer from the main list (through a transaction).
     ssize_t err = removeLayer_l(layerBase);
-    if (err >= 0) {
-        mLayerPurgatory.add(layerBase);
-    }
+
     // it's possible that we don't find a layer, because it might
     // have been destroyed already -- this is not technically an error
     // from the user because there is a race between BClient::destroySurface(),
@@ -1362,18 +1359,8 @@
              * to use the purgatory.
              */
             status_t err = flinger->removeLayer_l(l);
-            if (err == NAME_NOT_FOUND) {
-                // The surface wasn't in the current list, which means it was
-                // removed already, which means it is in the purgatory, 
-                // and need to be removed from there.
-                // This needs to happen from the main thread since its dtor
-                // must run from there (b/c of OpenGL ES). Additionally, we
-                // can't really acquire our internal lock from 
-                // destroySurface() -- see postMessage() below.
-                ssize_t idx = flinger->mLayerPurgatory.remove(l);
-                LOGE_IF(idx < 0,
-                        "layer=%p is not in the purgatory list", l.get());
-            }
+            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
+                    "error removing layer=%p (%s)", l.get(), strerror(-err));
             return true;
         }
     };
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 493e777..e446070 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -314,7 +314,6 @@
     volatile    int32_t                 mTransactionCount;
                 Condition               mTransactionCV;
                 bool                    mResizeTransationPending;
-                SortedVector< sp<LayerBase> > mLayerPurgatory;
                 
                 // protected by mStateLock (but we could use another lock)
                 Tokenizer                               mTokens;
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
index 8401cb6..3baa281 100644
--- a/libs/ui/SurfaceComposerClient.cpp
+++ b/libs/ui/SurfaceComposerClient.cpp
@@ -62,34 +62,42 @@
 static sp<IMemoryHeap>                                      gServerCblkMemory;
 static volatile surface_flinger_cblk_t*                     gServerCblk;
 
-const sp<ISurfaceComposer>& _get_surface_manager()
+static sp<ISurfaceComposer> getComposerService()
 {
-    if (gSurfaceManager != 0) {
-        return gSurfaceManager;
-    }
-
-    sp<IBinder> binder;
-    sp<IServiceManager> sm = defaultServiceManager();
-    do {
-        binder = sm->getService(String16("SurfaceFlinger"));
-        if (binder == 0) {
-            LOGW("SurfaceFlinger not published, waiting...");
-            usleep(500000); // 0.5 s
-        }
-    } while(binder == 0);
-    sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
-
+    sp<ISurfaceComposer> sc;
     Mutex::Autolock _l(gLock);
-    if (gSurfaceManager == 0) {
-        gSurfaceManager = sc;
+    if (gSurfaceManager != 0) {
+        sc = gSurfaceManager;
+    } else {
+        // release the lock while we're waiting...
+        gLock.unlock();
+
+        sp<IBinder> binder;
+        sp<IServiceManager> sm = defaultServiceManager();
+        do {
+            binder = sm->getService(String16("SurfaceFlinger"));
+            if (binder == 0) {
+                LOGW("SurfaceFlinger not published, waiting...");
+                usleep(500000); // 0.5 s
+            }
+        } while(binder == 0);
+
+        // grab the lock again for updating gSurfaceManager
+        gLock.lock();
+        if (gSurfaceManager == 0) {
+            sc = interface_cast<ISurfaceComposer>(binder);
+            gSurfaceManager = sc;
+        } else {
+            sc = gSurfaceManager;
+        }
     }
-    return gSurfaceManager;
+    return sc;
 }
 
 static volatile surface_flinger_cblk_t const * get_cblk()
 {
     if (gServerCblk == 0) {
-        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        sp<ISurfaceComposer> sm(getComposerService());
         Mutex::Autolock _l(gLock);
         if (gServerCblk == 0) {
             gServerCblkMemory = sm->getCblk();
@@ -112,7 +120,7 @@
 
 SurfaceComposerClient::SurfaceComposerClient()
 {
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     if (sm == 0) {
         _init(0, 0);
         return;
@@ -133,6 +141,15 @@
     _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
 }
 
+
+status_t SurfaceComposerClient::linkToComposerDeath(
+        const sp<IBinder::DeathRecipient>& recipient,
+        void* cookie, uint32_t flags)
+{
+    sp<ISurfaceComposer> sm(getComposerService());
+    return sm->asBinder()->linkToDeath(recipient, cookie, flags);    
+}
+
 void SurfaceComposerClient::_init(
         const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
 {
@@ -183,7 +200,7 @@
 
     if (client == 0) {
         // Need to make a new client.
-        const sp<ISurfaceComposer>& sm(_get_surface_manager());
+        sp<ISurfaceComposer> sm(getComposerService());
         client = new SurfaceComposerClient(sm, conn);
         if (client != 0 && client->initCheck() == NO_ERROR) {
             Mutex::Autolock _l(gLock);
@@ -377,7 +394,7 @@
     const size_t N = clients.size();
     VERBOSE("closeGlobalTransaction (%ld clients)", N);
 
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     sm->openGlobalTransaction();
     for (size_t i=0; i<N; i++) {
         clients[i]->closeTransaction();
@@ -389,20 +406,20 @@
 
 status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
 {
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     return sm->freezeDisplay(dpy, flags);
 }
 
 status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
 {
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     return sm->unfreezeDisplay(dpy, flags);
 }
 
 int SurfaceComposerClient::setOrientation(DisplayID dpy, 
         int orientation, uint32_t flags)
 {
-    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sp<ISurfaceComposer> sm(getComposerService());
     return sm->setOrientation(dpy, orientation, flags);
 }
 
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 49f8cdd..3e9ba33 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -196,7 +196,7 @@
     // Since internally SkBitmap uses reference count to manage the reference to
     // its pixels, it is important that the pixels (along with SkBitmap) be
     // available after creating the Bitmap is returned to Java app.
-    return env->NewObject(fields.bitmapClazz, fields.bitmapConstructor, (int) bitmap, true, NULL);
+    return env->NewObject(fields.bitmapClazz, fields.bitmapConstructor, (int) bitmap, true, NULL, -1);
 }
 
 static jbyteArray android_media_MediaMetadataRetriever_extractAlbumArt(JNIEnv *env, jobject thiz)
@@ -293,7 +293,7 @@
         return;
     }
 
-    fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(IZ[B)V");
+    fields.bitmapConstructor = env->GetMethodID(fields.bitmapClazz, "<init>", "(IZ[BI)V");
     if (fields.bitmapConstructor == NULL) {
         jniThrowException(env, "java/lang/RuntimeException", "Can't find Bitmap constructor");
         return;
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index b3a19e3..4599b77 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -296,7 +296,7 @@
      * a context will be created with no shared context and
      * with a null attribute list.
      */
-    public void setContextFactory(EGLContextFactory factory) {
+    public void setEGLContextFactory(EGLContextFactory factory) {
         checkRenderThreadState();
         mEGLContextFactory = factory;
     }
@@ -311,7 +311,7 @@
      * If this method is not called, then by default
      * a window surface will be created with a null attribute list.
      */
-    public void setWindowSurfaceFactory(EGLWindowSurfaceFactory factory) {
+    public void setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory factory) {
         checkRenderThreadState();
         mEGLWindowSurfaceFactory = factory;
     }
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index f97d347..ba9a717 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -291,6 +291,7 @@
     for (;;) {
         renderFrame();
         eglSwapBuffers(dpy, surface);
+        checkEglError("eglSwapBuffers");
     }
 
     return 0;
diff --git a/opengl/tests/gl2_jni/Android.mk b/opengl/tests/gl2_jni/Android.mk
new file mode 100644
index 0000000..ff15814
--- /dev/null
+++ b/opengl/tests/gl2_jni/Android.mk
@@ -0,0 +1,53 @@
+#########################################################################
+# OpenGL ES JNI sample
+# This makefile builds both an activity and a shared library.
+#########################################################################
+ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := GL2JNI
+
+LOCAL_JNI_SHARED_LIBRARIES := libgl2jni
+
+include $(BUILD_PACKAGE)
+
+#########################################################################
+# Build JNI Shared Library
+#########################################################################
+
+LOCAL_PATH:= $(LOCAL_PATH)/jni
+
+include $(CLEAR_VARS)
+
+# Optional tag would mean it doesn't get installed by default
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -Werror
+
+LOCAL_SRC_FILES:= \
+  gl_code.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libutils \
+	libEGL \
+	libGLESv2
+
+LOCAL_MODULE := libgl2jni
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # TARGET_SIMULATOR
diff --git a/opengl/tests/gl2_jni/AndroidManifest.xml b/opengl/tests/gl2_jni/AndroidManifest.xml
new file mode 100644
index 0000000..a72a6a5
--- /dev/null
+++ b/opengl/tests/gl2_jni/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.gl2jni">
+    <application
+            android:label="@string/gl2jni_activity">
+        <activity android:name="GL2JNIActivity"
+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            	android:launchMode="singleTask"
+            	android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/opengl/tests/gl2_jni/jni/gl_code.cpp b/opengl/tests/gl2_jni/jni/gl_code.cpp
new file mode 100644
index 0000000..146d52a
--- /dev/null
+++ b/opengl/tests/gl2_jni/jni/gl_code.cpp
@@ -0,0 +1,165 @@
+// OpenGL ES 2.0 code
+
+#include <nativehelper/jni.h>
+#define LOG_TAG "GL2JNI gl_code.cpp"
+#include <utils/Log.h>
+

+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <stdio.h>

+#include <stdlib.h>
+#include <math.h>
+
+static void printGLString(const char *name, GLenum s) {
+    const char *v = (const char *) glGetString(s);
+    LOGI("GL %s = %s\n", name, v);
+}
+
+static void checkGlError(const char* op) {
+    for (GLint error = glGetError(); error; error
+            = glGetError()) {
+        LOGI("after %s() glError (0x%x)\n", op, error);
+    }
+}
+

+static const char gVertexShader[] = "attribute vec4 vPosition;\n"
+    "void main() {\n"
+    "  gl_Position = vPosition;\n"
+    "}\n";
+
+static const char gFragmentShader[] = "precision mediump float;\n"
+    "void main() {\n"
+    "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+    "}\n";
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+    GLuint shader = glCreateShader(shaderType);
+    if (shader) {
+        glShaderSource(shader, 1, &pSource, NULL);
+        glCompileShader(shader);
+        GLint compiled = 0;
+        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+        if (!compiled) {
+            GLint infoLen = 0;
+            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+            if (infoLen) {
+                char* buf = (char*) malloc(infoLen);
+                if (buf) {
+                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
+                    LOGE("Could not compile shader %d:\n%s\n",
+                            shaderType, buf);
+                    free(buf);
+                }
+                glDeleteShader(shader);
+                shader = 0;
+            }
+        }
+    }
+    return shader;
+}
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+    if (!vertexShader) {
+        return 0;
+    }
+
+    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+    if (!pixelShader) {
+        return 0;
+    }
+
+    GLuint program = glCreateProgram();
+    if (program) {
+        glAttachShader(program, vertexShader);
+        checkGlError("glAttachShader");
+        glAttachShader(program, pixelShader);
+        checkGlError("glAttachShader");
+        glLinkProgram(program);
+        GLint linkStatus = GL_FALSE;
+        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+        if (linkStatus != GL_TRUE) {
+            GLint bufLength = 0;
+            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+            if (bufLength) {
+                char* buf = (char*) malloc(bufLength);
+                if (buf) {
+                    glGetProgramInfoLog(program, bufLength, NULL, buf);
+                    LOGE("Could not link program:\n%s\n", buf);
+                    free(buf);
+                }
+            }
+            glDeleteProgram(program);
+            program = 0;
+        }
+    }
+    return program;
+}
+
+GLuint gProgram;
+GLuint gvPositionHandle;
+
+bool setupGraphics(int w, int h) {
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);
+
+    LOGI("setupGraphics(%d, %d)", w, h);
+    gProgram = createProgram(gVertexShader, gFragmentShader);
+    if (!gProgram) {
+        LOGE("Could not create program.");
+        return false;
+    }
+    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+    checkGlError("glGetAttribLocation");
+    LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
+            gvPositionHandle);
+
+    glViewport(0, 0, w, h);
+    checkGlError("glViewport");
+    return true;
+}
+
+const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+        0.5f, -0.5f };
+
+void renderFrame() {
+    static float grey;
+    grey += 0.01f;
+    if (grey > 1.0f) {
+        grey = 0.0f;
+    }
+    glClearColor(grey, grey, grey, 1.0f);
+    checkGlError("glClearColor");
+    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    checkGlError("glClear");
+
+    glUseProgram(gProgram);
+    checkGlError("glUseProgram");
+
+    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+    checkGlError("glVertexAttribPointer");
+    glEnableVertexAttribArray(gvPositionHandle);
+    checkGlError("glEnableVertexAttribArray");
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+    checkGlError("glDrawArrays");
+}
+
+extern "C" {
+    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height);
+    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);
+};

+

+JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height)

+{

+    setupGraphics(width, height);

+}

+
+JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)

+{

+    renderFrame();

+}

+
diff --git a/opengl/tests/gl2_jni/res/values/strings.xml b/opengl/tests/gl2_jni/res/values/strings.xml
new file mode 100644
index 0000000..e3f7331
--- /dev/null
+++ b/opengl/tests/gl2_jni/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2006, 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.
+*/
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="gl2jni_activity">GL2JNI</string>
+
+</resources>
+
diff --git a/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIActivity.java b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIActivity.java
new file mode 100644
index 0000000..c366a2c
--- /dev/null
+++ b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 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 com.android.gl2jni;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class GL2JNIActivity extends Activity {
+
+    GL2JNIView mView;
+
+    @Override protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mView = new GL2JNIView(getApplication());
+	setContentView(mView);
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+        mView.onPause();
+    }
+
+    @Override protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+}
diff --git a/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNILib.java b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNILib.java
new file mode 100644
index 0000000..040a984
--- /dev/null
+++ b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNILib.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 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 com.android.gl2jni;
+
+// Wrapper for native library
+
+public class GL2JNILib {
+
+     static {
+         System.loadLibrary("gl2jni");
+     }
+
+    /**
+     * @param width the current view width
+     * @param height the current view height
+     */
+     public static native void init(int width, int height);
+     public static native void step();
+}
diff --git a/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java
new file mode 100644
index 0000000..baa10af
--- /dev/null
+++ b/opengl/tests/gl2_jni/src/com/android/gl2jni/GL2JNIView.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gl2jni;
+/*
+ * 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.
+ */
+
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation.  This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+class GL2JNIView extends GLSurfaceView {
+    private static String TAG = "GL2JNIView";
+    GL2JNIView(Context context) {
+        super(context);
+        init();
+    }
+
+    public GL2JNIView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        setEGLContextFactory(new ContextFactory());
+        // setEGLConfigChooser(new ConfigChooser());
+        setRenderer(new Renderer());
+    }
+
+    private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
+        private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+            checkEglError("Before eglCreateContext", egl);
+            int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+            EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
+            checkEglError("After eglCreateContext", egl);
+            return context;
+        }
+
+        public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+            egl.eglDestroyContext(display, context);
+        } 
+    }
+
+    private static void checkEglError(String prompt, EGL10 egl) {
+        int error;
+        while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
+            Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
+        }
+    }
+
+    private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
+        private static int EGL_OPENGL_ES2_BIT = 4;
+        private static int[]  s_configAttribs2 =
+        {
+                EGL10.EGL_DEPTH_SIZE,     16,
+                // EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+                EGL10.EGL_NONE
+        };
+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+
+            int[] num_config = new int[1];
+            egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
+
+            int numConfigs = num_config[0];
+
+            if (numConfigs <= 0) {
+                throw new IllegalArgumentException("No configs match configSpec");
+            }
+            EGLConfig[] configs = new EGLConfig[numConfigs];
+            egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
+            return configs[0];
+        }
+    }
+
+    private static class Renderer implements GLSurfaceView.Renderer {
+        public void onDrawFrame(GL10 gl) {
+            GL2JNILib.step();
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            GL2JNILib.init(width, height);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            // Do nothing.
+        }
+    }
+}
+
diff --git a/opengl/tests/gl_jni/Android.mk b/opengl/tests/gl_jni/Android.mk
new file mode 100644
index 0000000..4029fa1
--- /dev/null
+++ b/opengl/tests/gl_jni/Android.mk
@@ -0,0 +1,53 @@
+#########################################################################
+# OpenGL ES JNI sample
+# This makefile builds both an activity and a shared library.
+#########################################################################
+ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := GLJNI
+
+LOCAL_JNI_SHARED_LIBRARIES := libgljni
+
+include $(BUILD_PACKAGE)
+
+#########################################################################
+# Build JNI Shared Library
+#########################################################################
+
+LOCAL_PATH:= $(LOCAL_PATH)/jni
+
+include $(CLEAR_VARS)
+
+# Optional tag would mean it doesn't get installed by default
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -Werror
+
+LOCAL_SRC_FILES:= \
+  gl_code.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libutils \
+	libEGL \
+	libGLESv1_CM
+
+LOCAL_MODULE := libgljni
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # TARGET_SIMULATOR
diff --git a/opengl/tests/gl_jni/AndroidManifest.xml b/opengl/tests/gl_jni/AndroidManifest.xml
new file mode 100644
index 0000000..64bd6bf
--- /dev/null
+++ b/opengl/tests/gl_jni/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.gljni">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <application
+            android:label="@string/gljni_activity">
+        <activity android:name="GLJNIActivity"
+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            	android:launchMode="singleTask"
+            	android:screenOrientation="landscape"
+            	android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/opengl/tests/gl_jni/jni/gl_code.cpp b/opengl/tests/gl_jni/jni/gl_code.cpp
new file mode 100644
index 0000000..b85a433
--- /dev/null
+++ b/opengl/tests/gl_jni/jni/gl_code.cpp
@@ -0,0 +1,177 @@
+// OpenGL ES 1.0 code
+
+#include <nativehelper/jni.h>
+#define LOG_TAG "GLJNI gl_code.cpp"
+#include <utils/Log.h>

+#include <GLES/gl.h>
+
+#include <stdio.h>

+#include <stdlib.h>
+#include <math.h>
+

+GLuint texture;

+

+#define FIXED_ONE 0x10000

+
+static void printGLString(const char *name, GLenum s) {
+    const char *v = (const char *) glGetString(s);
+    LOGI("GL %s = %s\n", name, v);
+}
+
+static void gluLookAt(float eyeX, float eyeY, float eyeZ,
+        float centerX, float centerY, float centerZ, float upX, float upY,
+        float upZ)
+{
+    // See the OpenGL GLUT documentation for gluLookAt for a description
+    // of the algorithm. We implement it in a straightforward way:
+
+    float fx = centerX - eyeX;
+    float fy = centerY - eyeY;
+    float fz = centerZ - eyeZ;
+
+    // Normalize f
+    float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
+    fx *= rlf;
+    fy *= rlf;
+    fz *= rlf;
+
+    // Normalize up
+    float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
+    upX *= rlup;
+    upY *= rlup;
+    upZ *= rlup;
+
+    // compute s = f x up (x means "cross product")
+
+    float sx = fy * upZ - fz * upY;
+    float sy = fz * upX - fx * upZ;
+    float sz = fx * upY - fy * upX;
+
+    // compute u = s x f
+    float ux = sy * fz - sz * fy;
+    float uy = sz * fx - sx * fz;
+    float uz = sx * fy - sy * fx;
+
+    float m[16] ;
+    m[0] = sx;
+    m[1] = ux;
+    m[2] = -fx;
+    m[3] = 0.0f;
+
+    m[4] = sy;
+    m[5] = uy;
+    m[6] = -fy;
+    m[7] = 0.0f;
+
+    m[8] = sz;
+    m[9] = uz;
+    m[10] = -fz;
+    m[11] = 0.0f;
+
+    m[12] = 0.0f;
+    m[13] = 0.0f;
+    m[14] = 0.0f;
+    m[15] = 1.0f;
+
+    glMultMatrixf(m);
+    glTranslatef(-eyeX, -eyeY, -eyeZ);
+}
+
+void init_scene(int width, int height)

+{
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);

+    glDisable(GL_DITHER);
+    glEnable(GL_CULL_FACE);
+
+
+    float ratio = width / height;
+    glViewport(0, 0, width, height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustumf(-ratio, ratio, -1, 1, 1, 10);

+
+
+    glMatrixMode(GL_MODELVIEW);

+    glLoadIdentity();
+    gluLookAt(
+            0, 0, 3,  // eye
+            0, 0, 0,  // center
+            0, 1, 0); // up
+

+    glEnable(GL_TEXTURE_2D);

+    glEnableClientState(GL_VERTEX_ARRAY);

+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+}

+

+void create_texture()

+{

+    const unsigned int on = 0xff0000ff;
+    const unsigned int off = 0xffffffff;
+    const unsigned int pixels[] =
+    {
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+    };

+    glGenTextures(1, &texture);

+    glBindTexture(GL_TEXTURE_2D, texture);

+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

+}
+
+extern "C" {
+    JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj,  jint width, jint height);
+    JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj);
+};
+

+

+JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj,  jint width, jint height)

+{

+    init_scene(width, height);

+    create_texture();

+}

+
+JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj)

+{

+    const GLfloat vertices[] = {

+            -1,  -1,  0,

+             1,  -1,  0,

+             1,   1,  0,

+            -1,   1,  0

+    };

+

+    const GLfixed texCoords[] = {

+            0,            0,

+            FIXED_ONE,    0,

+            FIXED_ONE,    FIXED_ONE,

+            0,            FIXED_ONE

+    };

+

+    const GLushort quadIndices[] = { 0, 1, 2,  0, 2, 3 };
+
+    glVertexPointer(3, GL_FLOAT, 0, vertices);

+    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+
+    int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]);
+    static float grey;
+    grey += 0.01f;
+    if (grey > 1.0f) {
+        grey = 0.0f;
+    }
+    glClearColor(grey, grey, grey, 1.0f);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, quadIndices);

+}

+
diff --git a/opengl/tests/gl_jni/res/values/strings.xml b/opengl/tests/gl_jni/res/values/strings.xml
new file mode 100644
index 0000000..880f5c9
--- /dev/null
+++ b/opengl/tests/gl_jni/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2006, 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.
+*/
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="gljni_activity">GLJNI</string>
+
+</resources>
+
diff --git a/opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java
new file mode 100644
index 0000000..df1f957
--- /dev/null
+++ b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 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 com.android.gljni;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class GLJNIActivity extends Activity {
+
+    GLJNIView mView;
+
+    @Override protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mView = new GLJNIView(getApplication());
+	setContentView(mView);
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+        mView.onPause();
+    }
+
+    @Override protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+}
diff --git a/opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java b/opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java
new file mode 100644
index 0000000..8662725
--- /dev/null
+++ b/opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 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 com.android.gljni;
+
+// Wrapper for native library
+
+public class GLJNILib {
+
+     static {
+         System.loadLibrary("gljni");
+     }
+
+    /**
+     * @param width the current view width
+     * @param height the current view height
+     */
+     public static native void init(int width, int height);
+     public static native void step();
+}
diff --git a/opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java
new file mode 100644
index 0000000..9ea1059
--- /dev/null
+++ b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gljni;
+/*
+ * 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.
+ */
+
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation.  This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+class GLJNIView extends GLSurfaceView {
+    GLJNIView(Context context) {
+        super(context);
+        init();
+    }
+
+    public GLJNIView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        setRenderer(new Renderer());
+    }
+
+    private class Renderer implements GLSurfaceView.Renderer {
+        private static final String TAG = "Renderer";
+        public void onDrawFrame(GL10 gl) {
+            GLJNILib.step();
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            GLJNILib.init(width, height);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            // Do nothing.
+        }
+    }
+}
+
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 5439f8b..3c46954 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -473,8 +473,10 @@
     public void stopListening(int hostId) {
         synchronized (mAppWidgetIds) {
             Host host = lookupHostLocked(getCallingUid(), hostId);
-            host.callbacks = null;
-            pruneHostLocked(host);
+            if (host != null) {
+                host.callbacks = null;
+                pruneHostLocked(host);
+            }
         }
     }
 
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 38d2304..f742f9f 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -7320,18 +7320,22 @@
             // are currently targeting.
             if (mAttrs.type == TYPE_WALLPAPER && mLowerWallpaperTarget == null
                     && mWallpaperTarget != null) {
-                if (mWallpaperTarget.mHasLocalTransformation) {
+                if (mWallpaperTarget.mHasLocalTransformation &&
+                        mWallpaperTarget.mAnimation != null &&
+                        !mWallpaperTarget.mAnimation.getDetachWallpaper()) {
                     attachedTransformation = mWallpaperTarget.mTransformation;
+                    if (DEBUG_WALLPAPER && attachedTransformation != null) {
+                        Log.v(TAG, "WP target attached xform: " + attachedTransformation);
+                    }
                 }
                 if (mWallpaperTarget.mAppToken != null &&
-                        mWallpaperTarget.mAppToken.hasTransformation) {
+                        mWallpaperTarget.mAppToken.hasTransformation &&
+                        mWallpaperTarget.mAppToken.animation != null &&
+                        !mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
                     appTransformation = mWallpaperTarget.mAppToken.transformation;
-                }
-                if (DEBUG_WALLPAPER && attachedTransformation != null) {
-                    Log.v(TAG, "WP target attached xform: " + attachedTransformation);
-                }
-                if (DEBUG_WALLPAPER && appTransformation != null) {
-                    Log.v(TAG, "WP target app xform: " + appTransformation);
+                    if (DEBUG_WALLPAPER && appTransformation != null) {
+                        Log.v(TAG, "WP target app xform: " + appTransformation);
+                    }
                 }
             }
             
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap.java
index 7dde634..ff1b295 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap.java
@@ -28,13 +28,13 @@
     private BufferedImage mImage;
 
     public Bitmap(File input) throws IOException {
-        super(1, true, null);
+        super(1, true, null, -1);
 
         mImage = ImageIO.read(input);
     }
 
     Bitmap(BufferedImage image) {
-        super(1, true, null);
+        super(1, true, null, -1);
         mImage = image;
     }