Merge change I8e7f5f07 into eclair

* changes:
  DO NOT MERGE: Fix loss of focus after wakeup into incall screen
diff --git a/docs/html/guide/appendix/api-levels.jd b/docs/html/guide/appendix/api-levels.jd
index b3b6371..0830032 100644
--- a/docs/html/guide/appendix/api-levels.jd
+++ b/docs/html/guide/appendix/api-levels.jd
@@ -324,22 +324,24 @@
 accessible to your application, based on the API Level that it specifies in 
 the <code>android:minSdkVersion</code> attribute of its manifest file. </p>
 
-<p>To use filtering, set the control to the same API Level as that specified
-by your application. Notice that APIs introduced in a later API Level are 
-then grayed out and their content is masked, since they would not be
-accessible to your application. </p>
+<p>To use filtering, select the checkbox to enable filtering, just below the
+page search box. Then set the "Filter by API Level" control to the same API
+Level as specified by your application. Notice that APIs introduced in a later
+API Level are then grayed out and their content is masked, since they would not
+be accessible to your application. </p>
 
 <p>Filtering by API Level in the documentation does not provide a view
 of what is new or introduced in each API Level &mdash; it simply provides a way
 to view the entire API associated with a given API Level, while excluding API
 elements introduced in later API Levels.</p>
 
-<p>By default, API Level filtering is enabled and set to show the latest API
-Level. If you do not want to use filtering reference documentation, 
-simply select the highest available API Level. </p>
+<p>If you decide that you don't want to filter the API documentation, just
+disable the feature using the checkbox. By default, API Level filtering is
+disabled, so that you can view the full framework API, regardless of API Level.
+</p>
 
 <p>Also note that the reference documentation for individual API elements
-specifies the API Level at which the elements were introduced. The API Level 
+specifies the API Level at which each element was introduced. The API Level 
 for packages and classes is specified as "Since &lt;api level&gt;" at the 
 top-right corner of the content area on each documentation page. The API Level 
 for class members is specified in their detailed description headers, 
diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd
index 1d16d88..88975f8 100644
--- a/docs/html/guide/practices/screens_support.jd
+++ b/docs/html/guide/practices/screens_support.jd
@@ -1069,29 +1069,30 @@
 various screen sizes, you should make sure to add the corresponding size
 attribute(s) to your application's manifest. -->
 
+<div id="f9.5" style="float:right;margin:0;padding:0;">
+  <img src="{@docRoot}images/screens_support/avds-config.png" style="padding:0;margin:0;">
+  <p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0 1em;"><strong>Figure 3.</strong>
+  A typical set of AVDs for testing screens support.</p>
+</div>
+
 <p>As a test environment for your applications, set up a series of AVDs that
 emulate the screen sizes and densities you want to support. The Android SDK
-includes four emulator skins to get you started. You can use the Android AVD
+includes six emulator skins to get you started. You can use the Android AVD
 Manager or the <code>android</code> tool to create AVDs that use the various
 emulator skins and you can also set up custom AVDs to test densities other than
 the defaults. For general information about working with AVDs, see 
 <a href="{@docRoot}guide/developing/tools/avd.html">Android Virtual
 Devices</a>.</p>
 
-<p>The Android 1.6 and higher platforms in the SDK include these emulator skins,
-which represent the primary screen configurations that your should test:</p>
+<p>The Android SDK provides a set of default emulator skins that you can use for 
+testing. The skins are included as part of each Android platform that you can
+install in your SDK. The Android 1.6 platform offers these default skins:</p>
 
 <ul>
   <li>
     QVGA (240x320, low density, small screen)
   </li>
   <li>
-    WQVGA400 (240x400, low density, normal screen)
-  </li>
-  <li>
-    WQVGA432 (240x432, low density, normal screen)
-  </li>
-  <li>
     HVGA (320x480, medium density, normal screen)
   </li>
   <li>
@@ -1102,6 +1103,18 @@
   </li>
 </ul>
 
+<p>The Android 2.0 platform offers all of the Android 1.6 default skins, 
+above, plus:</p>
+
+<ul>
+  <li>
+    WQVGA400 (240x400, low density, normal screen)
+  </li>
+  <li>
+    WQVGA432 (240x432, low density, normal screen)
+  </li>
+</ul>
+
 <p>If you are using the <code>android</code> tool command line to create your
 AVDs, here's an example of how to specify the skin you want to use:</p>
 
@@ -1131,6 +1144,12 @@
     QVGA, low density: 3.3"
   </li>
   <li>
+    WQVGA, low density: 3.9"
+  </li>
+  <li>
+    WQVGA432, low density: 4.1"
+  </li>
+  <li>
     HVGA, medium density: 3.6"
   </li>
   <li>
@@ -1141,6 +1160,12 @@
   </li>
 </ul>
 
+<div style="float: right;background-color:#fff;margin: 0;padding: 20px 0 20px 20px;width:520px;">
+  <img src="{@docRoot}images/screens_support/avd-density.png" style="padding:0;margin:0;">
+  <p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0 1em; width:280px;"><strong>Figure 4.</strong>
+  Resolution and density options that you can use, when creating an AVD using the AVD Manager.</p>
+</div>
+
 <p>You should also make sure to test your application on different physical
 screen sizes within a single size-density configuration. For example, according
 to <a href="#range">Table 1</a>, the minimum supported diagonal of QVGA is 2.8".
@@ -1150,21 +1175,35 @@
 
 <pre>emulator -avd &lt;name&gt; -scale 0.6</pre>
 
-<p>If you would like to test your application on a screen not supported by the
-built-in skins, you can either adjust an existing skin, or create a custom
-resolution.</p>
+<p>If you would like to test your application on a screen that uses a resolution
+or density not supported by the built-in skins, you can either adjust an
+existing skin, or create an AVD
+that uses a custom resolution or density.</p>
 
-<p>For example, to test on a large WVGA800 screen with medium density:</p>
+<p>In the AVD Manager, you can specify a custom skin resolution or density in
+the Create New AVD dialog, as shown in Figure 4, at right.</p>
+
+<p>In the <code>android</code> tool, follow these steps to create an AVD with a
+custom resolution or density:</p>
 
 <ol>
-  <li>Create an AVD based on the WVGA800 skin (using the <code>android</code>
-tool's command line.)<br></li>
-  <li>Answer "yes" when asked about using custom hardware</li>
-  <li>enter "160" when asked about the value for <em>hw.lcd.density</em>
-(120-low, 160-medium, 240-high).</li>
+  <li>Use the <code>create avd</code> command to create a new AVD, specifying
+the <code>--skin</code> option with a value that references either a default
+skin name (such as "WVGA800") or a custom skin resolution (such as 240x432).
+Here's an example:
+     <pre>android create avd -n &lt;name&gt; -t &lt;targetID&gt; --skin WVGA800</pre>
+  </li>
+  <li>To specify a custom density for the skin, answer "yes" when asked whether
+you want to create a custom hardware profile for the new AVD.</li>
+  <li>Continue through the various profile settings until the tool asks you to
+specify "Abstracted LCD density" (<em>hw.lcd.density</em>). Consult <a
+href="#range">Table 1</a>, earlier in this document, and enter the appropriate
+value. For example, enter "160" to use medium density for the WVGA800 screen.</li>
+  <li>Set any other hardware options and complete the AVD creation.</li>
 </ol>
 
-<p>When running this AVD, the emulator will emulate a 5.8" WVGA screen.</p>
+<p>In the example above (WVGA medium density), the new AVD will emulate a 5.8" 
+WVGA screen.</p>
 
 <p>As an alternative to adjusting the emulator skin configuration, you can use
 the emulator skin's default density and add the <code>-dpi-device</code> option
@@ -1172,25 +1211,6 @@
 
 <pre>emulator -avd WVGA800 -scale 96dpi -dpi-device 160</pre>
 
-<p>If you would like to test your application with a resolution not supported by
-the provided skins, you can use the desired resolution in place of the skin
-name. For instance, for FWQVGA you would use:</p>
-
-<pre>android create avd ... --skin 240x432</pre>
-
-<p>Next, you would need to set the proper density for the screen. When asked by
-the tool whether you want to create a custom hardware profile for the new AVD,
-enter "yes". Continue through the various profile settings until the tools asks
-you to specify "Abstracted LCD density". Consult <a href="#range">Table 1</a>,
-earlier in this document, and enter the appropriate value. For the FWQVGA
-screen, the density should be "160", or medium.</p>
-
-<div id="f9.5" style="text-align:left;margin:0;padding:0;">
-  <img src="{@docRoot}images/screens_support/avds-config.png" style="padding:0;margin:0;">
-  <p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0 1em;"><strong>Figure 3.</strong>
-  A typical set of AVDs for testing screens support.</p>
-</div>
-
 
 <h2 id="compatibility-examples">Screen-Compatibility Examples</h2>
 
diff --git a/docs/html/images/screens_support/avd-density.png b/docs/html/images/screens_support/avd-density.png
new file mode 100644
index 0000000..e3fc36e
--- /dev/null
+++ b/docs/html/images/screens_support/avd-density.png
Binary files differ
diff --git a/docs/html/sdk/android-1.5.jd b/docs/html/sdk/android-1.5.jd
index 15d1938..4612682 100644
--- a/docs/html/sdk/android-1.5.jd
+++ b/docs/html/sdk/android-1.5.jd
@@ -16,7 +16,6 @@
 	<li><a href="#apps">Built-in Applications</a></li>
 	<li><a href="#locs">Locales</a></li>
 	<li><a href="#skins">Emulator Skins</a></li>
-	<li><a href="#notes">Other Notes</a></li>
 	<li><a href="#api">Framework API</a>
         <ol>
 	<li><a href="#api-level">API level</a></li>
diff --git a/docs/html/sdk/android-1.6.jd b/docs/html/sdk/android-1.6.jd
index 38112b5..4b659a1a 100644
--- a/docs/html/sdk/android-1.6.jd
+++ b/docs/html/sdk/android-1.6.jd
@@ -16,7 +16,6 @@
 	<li><a href="#apps">Built-in Applications</a></li>
 	<li><a href="#locs">Locales</a></li>
 	<li><a href="#skins">Emulator Skins</a></li>
-	<li><a href="#notes">Other Notes</a></li>
 	<li><a href="#api">Framework API</a>
         <ol>
 	<li><a href="#api-level">API level</a></li>
diff --git a/docs/html/sdk/api_diff/3/changes.html b/docs/html/sdk/api_diff/3/changes.html
index bc0f879..9bc67b9 100644
--- a/docs/html/sdk/api_diff/3/changes.html
+++ b/docs/html/sdk/api_diff/3/changes.html
@@ -26,12 +26,12 @@
 body{background-image:url();padding:12px;}
 </style>
 </head>
-<FRAMESET COLS="242,**" frameborder="1" border="7" bordercolor="#e9e9e9"> 
-<frameset rows="164,**" frameborder="1" border="7" resizable="yes">
-    <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe">
-    <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe">
+<FRAMESET COLS="242,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9">
+<frameset rows="174,**" framespacing="1" frameborder="yes"  border="1" bordercolor="#e9e9e9">
+    <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe" frameborder="1">
+    <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe" frameborder="1">
   </FRAMESET>
-  <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe">
+  <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe" frameborder="1">
 </FRAMESET>
 <NOFRAMES>
 <H2>
diff --git a/docs/html/sdk/api_diff/3/stylesheet-jdiff.css b/docs/html/sdk/api_diff/3/stylesheet-jdiff.css
index b3c1b9a..abc4dd5 100644
--- a/docs/html/sdk/api_diff/3/stylesheet-jdiff.css
+++ b/docs/html/sdk/api_diff/3/stylesheet-jdiff.css
@@ -3,6 +3,7 @@
 
 div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;}
 table.diffspectable {border:1px;padding:0px;margin:0px;}
+table.jdiffIndex {margin-bottom:.5em;}
 .diffspechead {background-color:#eee;}
 .diffspectable tr {border:0px;padding:0px;}
 .diffspectable td  {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;}
@@ -29,7 +30,7 @@
   }
 .hiddenlink {
   font-size:96%;
-  line-height:.8em;
+/*  line-height:.8em; */
   text-decoration:none;}
 a {
   text-decoration:none;}
diff --git a/docs/html/sdk/api_diff/4/changes.html b/docs/html/sdk/api_diff/4/changes.html
index c1b66a1..9cfdc24 100644
--- a/docs/html/sdk/api_diff/4/changes.html
+++ b/docs/html/sdk/api_diff/4/changes.html
@@ -25,12 +25,12 @@
 <style type="text/css">
 </style>
 </HEAD>
-<FRAMESET COLS="242,**" frameborder="1" border="7" xframespacing="20" bordercolor="#e9e9e9"> 
-<frameset rows="164,**" frameborder="1" border="7" xframespacing="20" resizable="yes">
-    <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe" xframeborder="1" xborder="6" xframespacing="0">
-    <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe" xframeborder="1" xborder="1" xframespacing="0">
+<FRAMESET COLS="242,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9">
+<frameset rows="174,**" framespacing="1" frameborder="yes"  border="1" bordercolor="#e9e9e9">
+    <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe" frameborder="1">
+    <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe" frameborder="1">
   </FRAMESET>
-  <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe" xframeborder="1" xborder="1" xframespacing="0">
+  <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe" frameborder="1">
 </FRAMESET>
 <NOFRAMES>
 <H2>
diff --git a/docs/html/sdk/api_diff/4/stylesheet-jdiff.css b/docs/html/sdk/api_diff/4/stylesheet-jdiff.css
index b3c1b9a..824b3df 100644
--- a/docs/html/sdk/api_diff/4/stylesheet-jdiff.css
+++ b/docs/html/sdk/api_diff/4/stylesheet-jdiff.css
@@ -3,6 +3,7 @@
 
 div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;}
 table.diffspectable {border:1px;padding:0px;margin:0px;}
+table.jdiffIndex {margin-bottom:.5em;}
 .diffspechead {background-color:#eee;}
 .diffspectable tr {border:0px;padding:0px;}
 .diffspectable td  {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;}
@@ -29,7 +30,7 @@
   }
 .hiddenlink {
   font-size:96%;
-  line-height:.8em;
+/* line-height:.8em; */
   text-decoration:none;}
 a {
   text-decoration:none;}
diff --git a/docs/html/sdk/api_diff/5/changes.html b/docs/html/sdk/api_diff/5/changes.html
index dc3f7cb..671e890 100644
--- a/docs/html/sdk/api_diff/5/changes.html
+++ b/docs/html/sdk/api_diff/5/changes.html
@@ -25,12 +25,12 @@
 <style type="text/css">
 </style>
 </HEAD>
-<FRAMESET COLS="242,**" frameborder="1" border="7" xframespacing="20" bordercolor="#e9e9e9"> 
-<frameset rows="164,**" frameborder="1" border="7" xframespacing="20" resizable="yes">
-    <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe" xframeborder="1" xborder="6" xframespacing="0">
-    <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe" xframeborder="1" xborder="1" xframespacing="0">
+<FRAMESET COLS="242,**" framespacing="1" frameborder="yes" border="1" bordercolor="#e9e9e9">
+<frameset rows="174,**" framespacing="1" frameborder="yes"  border="1" bordercolor="#e9e9e9">
+    <FRAME SRC="changes/jdiff_topleftframe.html" SCROLLING="no" NAME="topleftframe" frameborder="1">
+    <FRAME SRC="changes/alldiffs_index_all.html" SCROLLING="auto" NAME="bottomleftframe" frameborder="1">
   </FRAMESET>
-  <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe" xframeborder="1" xborder="1" xframespacing="0">
+  <FRAME SRC="changes/changes-summary.html" SCROLLING="auto" NAME="rightframe" frameborder="1">
 </FRAMESET>
 <NOFRAMES>
 <H2>
diff --git a/docs/html/sdk/api_diff/5/stylesheet-jdiff.css b/docs/html/sdk/api_diff/5/stylesheet-jdiff.css
index b3c1b9a..abc4dd5 100644
--- a/docs/html/sdk/api_diff/5/stylesheet-jdiff.css
+++ b/docs/html/sdk/api_diff/5/stylesheet-jdiff.css
@@ -3,6 +3,7 @@
 
 div.and-diff-id {border: 1px solid #eee;position:relative;float:right;clear:both;padding:0px;}
 table.diffspectable {border:1px;padding:0px;margin:0px;}
+table.jdiffIndex {margin-bottom:.5em;}
 .diffspechead {background-color:#eee;}
 .diffspectable tr {border:0px;padding:0px;}
 .diffspectable td  {background-color:eee;border:0px;font-size:90%;font-weight:normal;padding:0px;padding-left:1px;padding-right:1px;text-align:center;color:777;}
@@ -29,7 +30,7 @@
   }
 .hiddenlink {
   font-size:96%;
-  line-height:.8em;
+/*  line-height:.8em; */
   text-decoration:none;}
 a {
   text-decoration:none;}
diff --git a/docs/html/videos/index.jd b/docs/html/videos/index.jd
index ddb9f86..4e53aac 100644
--- a/docs/html/videos/index.jd
+++ b/docs/html/videos/index.jd
@@ -37,12 +37,10 @@
  * Each playlist ID is paired with a custom video description.
  */
 var featured = {
-// Android 1.6 Release
-  'MBRFkLKRwFw' : "The Android 1.6 release includes new features and improvements to the Android platform. Here's an introduction to what's new in Android 1.6.",
+// Android 2.0 Release
+  'opZ69P-0Jbc' : "The Android 2.0 platform adds exciting new user features and developer APIs. Here's an introduction to what's new.",
 // How to Make your Android UI Fast..
   'N6YdwzAvwOA' : "Make your user interface fast, with more efficient AdapterViews, better bitmap scaling, faster redrawing, ViewStub layouts, fewer Views, and more.", 
-// Coding for Life: Battery Life
-//  'OUemfrKe65c' : "Learn what kinds of operations consume the most battery and how you can reduce your usage, with tips for parsing and zipping data, using wakelocks, and running a Service.",
 // How Do I Code Thee?
   'GARMe7Km_gk' : "If you'd like to augment your Android applications with pieces written in JavaScript or native code, watch this video."
 };
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 8897f03..2172536 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -66,7 +66,11 @@
     GraphicBuffer();
 
     // creates w * h buffer
-    GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t ssage);
+    GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage);
+
+    // create a buffer from an existing handle
+    GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage,
+            uint32_t stride, native_handle_t* handle, bool keepOwnership);
 
     // return status
     status_t initCheck() const;
@@ -94,9 +98,15 @@
     GraphicBuffer(const Parcel& reply);
     virtual ~GraphicBuffer();
 
+    enum {
+        ownNone   = 0,
+        ownHandle = 1,
+        ownData   = 2,
+    };
+
     inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
     inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
-    bool mOwner;
+    uint8_t mOwner;
 
 private:
     friend class Surface;
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index f84933e..1abfd68 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -256,12 +256,16 @@
     if (strstr(gl_extensions, "GL_OES_draw_texture")) {
         mFlags |= DRAW_TEXTURE_EXTENSION;
     }
+#ifdef EGL_ANDROID_image_native_buffer
     if (strstr( gl_extensions, "GL_OES_EGL_image") &&
         (strstr(egl_extensions, "EGL_KHR_image_base") || 
                 strstr(egl_extensions, "EGL_KHR_image")) &&
         strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) {
         mFlags |= DIRECT_TEXTURE;
     }
+#else
+#warning "EGL_ANDROID_image_native_buffer not supported"
+#endif
 
     // Unbind the context from this thread
     eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 2bb1e12..f5a5a0b 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -130,62 +130,6 @@
     return NO_ERROR;
 }
 
-status_t Layer::initializeEglImageLocked(
-        const sp<GraphicBuffer>& buffer, Texture* texture)
-{
-    status_t err = NO_ERROR;
-
-    // we need to recreate the texture
-    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
-
-    // free the previous image
-    if (texture->image != EGL_NO_IMAGE_KHR) {
-        eglDestroyImageKHR(dpy, texture->image);
-        texture->image = EGL_NO_IMAGE_KHR;
-    }
-
-    // construct an EGL_NATIVE_BUFFER_ANDROID
-    android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
-
-    // create the new EGLImageKHR
-    const EGLint attrs[] = {
-            EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
-            EGL_NONE,                   EGL_NONE
-    };
-    texture->image = eglCreateImageKHR(
-            dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-            (EGLClientBuffer)clientBuf, attrs);
-
-    LOGE_IF(texture->image == EGL_NO_IMAGE_KHR,
-            "eglCreateImageKHR() failed. err=0x%4x",
-            eglGetError());
-
-    if (texture->image != EGL_NO_IMAGE_KHR) {
-        glBindTexture(GL_TEXTURE_2D, texture->name);
-        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
-                (GLeglImageOES)texture->image);
-        GLint error = glGetError();
-        if (UNLIKELY(error != GL_NO_ERROR)) {
-            // this failed, for instance, because we don't support NPOT.
-            // FIXME: do something!
-            LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
-                 "failed err=0x%04x",
-                 this, texture->image, error);
-            mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
-            err = INVALID_OPERATION;
-        } else {
-            // Everything went okay!
-            texture->NPOTAdjust = false;
-            texture->dirty  = false;
-            texture->width  = clientBuf->width;
-            texture->height = clientBuf->height;
-        }
-    } else {
-        err = INVALID_OPERATION;
-    }
-    return err;
-}
-
 void Layer::reloadTexture(const Region& dirty)
 {
     Mutex::Autolock _l(mLock);
@@ -199,10 +143,11 @@
         mTextures[index].height = 0;
     }
 
+#ifdef EGL_ANDROID_image_native_buffer
     if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
         if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) {
             if (mTextures[index].dirty) {
-                initializeEglImageLocked(buffer, &mTextures[index]);
+                initializeEglImage(buffer, &mTextures[index]);
             }
         } else {
             if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width ||
@@ -212,7 +157,7 @@
                         buffer->width, buffer->height, buffer->format,
                         GraphicBuffer::USAGE_SW_WRITE_OFTEN |
                         GraphicBuffer::USAGE_HW_TEXTURE);
-                initializeEglImageLocked(
+                initializeEglImage(
                         mHybridBuffer, &mTextures[0]);
             }
 
@@ -279,7 +224,9 @@
                 buffer->unlock();
             }
         }
-    } else {
+    } else
+#endif
+    {
         for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
             mTextures[i].image = EGL_NO_IMAGE_KHR;
         }
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index 57b3dfa..1310ecc 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -85,8 +85,6 @@
     }
  
     void reloadTexture(const Region& dirty);
-    status_t initializeEglImageLocked(
-            const sp<GraphicBuffer>& buffer, Texture* texture);
 
     uint32_t getEffectiveUsage(uint32_t usage) const;
 
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index ecc7894..8003d22 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -617,6 +617,63 @@
     }
 }
 
+status_t LayerBase::initializeEglImage(
+        const sp<GraphicBuffer>& buffer, Texture* texture)
+{
+    status_t err = NO_ERROR;
+
+    // we need to recreate the texture
+    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+
+    // free the previous image
+    if (texture->image != EGL_NO_IMAGE_KHR) {
+        eglDestroyImageKHR(dpy, texture->image);
+        texture->image = EGL_NO_IMAGE_KHR;
+    }
+
+    // construct an EGL_NATIVE_BUFFER_ANDROID
+    android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
+
+    // create the new EGLImageKHR
+    const EGLint attrs[] = {
+            EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
+            EGL_NONE,                   EGL_NONE
+    };
+    texture->image = eglCreateImageKHR(
+            dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+            (EGLClientBuffer)clientBuf, attrs);
+
+    LOGE_IF(texture->image == EGL_NO_IMAGE_KHR,
+            "eglCreateImageKHR() failed. err=0x%4x",
+            eglGetError());
+
+    if (texture->image != EGL_NO_IMAGE_KHR) {
+        glBindTexture(GL_TEXTURE_2D, texture->name);
+        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
+                (GLeglImageOES)texture->image);
+        GLint error = glGetError();
+        if (UNLIKELY(error != GL_NO_ERROR)) {
+            // this failed, for instance, because we don't support NPOT.
+            // FIXME: do something!
+            LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
+                 "failed err=0x%04x",
+                 this, texture->image, error);
+            mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
+            err = INVALID_OPERATION;
+        } else {
+            // Everything went okay!
+            texture->NPOTAdjust = false;
+            texture->dirty  = false;
+            texture->width  = clientBuf->width;
+            texture->height = clientBuf->height;
+        }
+    } else {
+        err = INVALID_OPERATION;
+    }
+    return err;
+}
+
+
 // ---------------------------------------------------------------------------
 
 int32_t LayerBaseClient::sIdentity = 0;
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index efa4f8c..ed07b3f 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -261,6 +261,8 @@
           void drawWithOpenGL(const Region& clip, const Texture& texture) const;
           void loadTexture(Texture* texture, 
                   const Region& dirty, const GGLSurface& t) const;
+          status_t initializeEglImage(
+                  const sp<GraphicBuffer>& buffer, Texture* texture);
 
           
                 sp<SurfaceFlinger> mFlinger;
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 7e27a02..6590503 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -339,12 +339,6 @@
     mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
     mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
     mLayer.forceVisibilityTransaction();
-
-    hw_module_t const* module;
-    mBlitEngine = NULL;
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        copybit_open(module, &mBlitEngine);
-    }
 }
 
 LayerBuffer::BufferSource::~BufferSource()
@@ -352,8 +346,9 @@
     if (mTexture.name != -1U) {
         glDeleteTextures(1, &mTexture.name);
     }
-    if (mBlitEngine) {
-        copybit_close(mBlitEngine);
+    if (mTexture.image != EGL_NO_IMAGE_KHR) {
+        EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay());
+        eglDestroyImageKHR(dpy, mTexture.image);
     }
 }
 
@@ -421,122 +416,28 @@
     status_t err = NO_ERROR;
     NativeBuffer src(ourBuffer->getBuffer());
     const Rect transformedBounds(mLayer.getTransformedBounds());
-    copybit_device_t* copybit = mBlitEngine;
 
-    if (copybit)  {
-        const int src_width  = src.crop.r - src.crop.l;
-        const int src_height = src.crop.b - src.crop.t;
-        int W = transformedBounds.width();
-        int H = transformedBounds.height();
-        if (mLayer.getOrientation() & Transform::ROT_90) {
-            int t(W); W=H; H=t;
-        }
+    if (UNLIKELY(mTexture.name == -1LU)) {
+        mTexture.name = mLayer.createTexture();
+    }
 
-#ifdef EGL_ANDROID_get_render_buffer
-        EGLDisplay dpy = eglGetCurrentDisplay();
-        EGLSurface draw = eglGetCurrentSurface(EGL_DRAW); 
-        EGLClientBuffer clientBuf = eglGetRenderBufferANDROID(dpy, draw);
-        android_native_buffer_t* nb = (android_native_buffer_t*)clientBuf;
-        if (nb == 0) {
-            err = BAD_VALUE;
-        } else {
-            copybit_image_t dst;
-            dst.w       = nb->width;
-            dst.h       = nb->height;
-            dst.format  = nb->format;
-            dst.base    = NULL; // unused by copybit on msm7k
-            dst.handle  = (native_handle_t *)nb->handle;
+#if defined(EGL_ANDROID_image_native_buffer)
+    if (mLayer.mFlags & DisplayHardware::DIRECT_TEXTURE) {
+         // NOTE: Assume the buffer is  allocated with the proper USAGE flags
+        sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
+                src.crop.r, src.crop.b, src.img.format, 
+                GraphicBuffer::USAGE_HW_TEXTURE,
+                src.img.w, src.img.handle, false);
 
-            /* With LayerBuffer, it is likely that we'll have to rescale the
-             * surface, because this is often used for video playback or
-             * camera-preview. Since we want these operation as fast as possible
-             * we make sure we can use the 2D H/W even if it doesn't support
-             * the requested scale factor, in which case we perform the scaling
-             * in several passes. */
-
-            const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
-            const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
-
-            float xscale = 1.0f;
-            if (src_width > W*min)          xscale = 1.0f / min;
-            else if (src_width*mag < W)     xscale = mag;
-
-            float yscale = 1.0f;
-            if (src_height > H*min)         yscale = 1.0f / min;
-            else if (src_height*mag < H)    yscale = mag;
-
-            if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
-                const int tmp_w = floorf(src_width  * xscale);
-                const int tmp_h = floorf(src_height * yscale);
-                
-                if (mTempBitmap==0 || 
-                        mTempBitmap->getWidth() < size_t(tmp_w) || 
-                        mTempBitmap->getHeight() < size_t(tmp_h)) {
-                    mTempBitmap.clear();
-                    mTempBitmap = new GraphicBuffer(
-                            tmp_w, tmp_h, src.img.format, 
-                            GraphicBuffer::USAGE_HW_2D);
-                    err = mTempBitmap->initCheck();
-                }
-
-                if (LIKELY(err == NO_ERROR)) {
-                    NativeBuffer tmp;
-                    tmp.img.w = tmp_w;
-                    tmp.img.h = tmp_h;
-                    tmp.img.format = src.img.format;
-                    tmp.img.handle = (native_handle_t*)mTempBitmap->getNativeBuffer()->handle;
-                    tmp.crop.l = 0;
-                    tmp.crop.t = 0;
-                    tmp.crop.r = tmp.img.w;
-                    tmp.crop.b = tmp.img.h;
-
-                    region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b)));
-                    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-                    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-                    copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-                    err = copybit->stretch(copybit,
-                            &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it);
-                    src = tmp;
-                }
-            }
-
-            const Rect transformedBounds(mLayer.getTransformedBounds());
-            const copybit_rect_t& drect =
-                reinterpret_cast<const copybit_rect_t&>(transformedBounds);
-            const State& s(mLayer.drawingState());
-            region_iterator it(clip);
-
-            // pick the right orientation for this buffer
-            int orientation = mLayer.getOrientation();
-            if (UNLIKELY(mBufferHeap.transform)) {
-                Transform rot90;
-                GraphicPlane::orientationToTransfrom(
-                        ISurfaceComposer::eOrientation90, 0, 0, &rot90);
-                const Transform& planeTransform(mLayer.graphicPlane(0).transform());
-                const Layer::State& s(mLayer.drawingState());
-                Transform tr(planeTransform * s.transform * rot90);
-                orientation = tr.getOrientation();
-            }
-
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-
-            err = copybit->stretch(copybit,
-                    &dst, &src.img, &drect, &src.crop, &it);
-            if (err != NO_ERROR) {
-                LOGE("copybit failed (%s)", strerror(err));
-            }
-        }
+        err = mLayer.initializeEglImage(graphicBuffer, &mTexture);
     }
 #endif
-    
-    if (!copybit || err) 
-    {
+    else {
+        err = INVALID_OPERATION;
+    }
+
+    if (err != NO_ERROR) {
         // OpenGL fall-back
-        if (UNLIKELY(mTexture.name == -1LU)) {
-            mTexture.name = mLayer.createTexture();
-        }
         GLuint w = 0;
         GLuint h = 0;
         GGLSurface t;
@@ -549,11 +450,11 @@
         t.data = (GGLubyte*)src.img.base;
         const Region dirty(Rect(t.width, t.height));
         mLayer.loadTexture(&mTexture, dirty, t);
-        mTexture.transform = mBufferHeap.transform;
-        mLayer.drawWithOpenGL(clip, mTexture);
     }
-}
 
+    mTexture.transform = mBufferHeap.transform;
+    mLayer.drawWithOpenGL(clip, mTexture);
+}
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 5eb472c..438b711 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -132,7 +132,6 @@
         size_t                          mBufferSize;
         mutable sp<GraphicBuffer>       mTempBitmap;
         mutable LayerBase::Texture      mTexture;
-        copybit_device_t*               mBlitEngine;
     };
     
     class OverlaySource : public Source {
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
index 538dc77..fd61e30 100644
--- a/libs/surfaceflinger/LayerDim.cpp
+++ b/libs/surfaceflinger/LayerDim.cpp
@@ -55,8 +55,8 @@
     sHeight = h;
     sUseTexture = false;
     
-#ifdef DIM_WITH_TEXTURE
-    
+#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer)
+
 #warning "using a texture to implement LayerDim"
     
     /* On some h/w like msm7K, it is faster to use a texture because the
@@ -69,7 +69,6 @@
     uint32_t flags = hw.getFlags();
 
     if (LIKELY(flags & DisplayHardware::DIRECT_TEXTURE)) {
-        // TODO: api to pass the usage flags
         sp<GraphicBuffer> buffer = new GraphicBuffer(w, h, PIXEL_FORMAT_RGB_565,
                  GraphicBuffer::USAGE_SW_WRITE_OFTEN |
                  GraphicBuffer::USAGE_HW_TEXTURE);
@@ -123,7 +122,7 @@
         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
         glColor4x(0, 0, 0, alpha);
         
-#ifdef DIM_WITH_TEXTURE
+#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer)
         if (sUseTexture) {
             glBindTexture(GL_TEXTURE_2D, sTexId);
             glEnable(GL_TEXTURE_2D);
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 1cf20d7..efe2d78 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -37,7 +37,7 @@
 // ===========================================================================
 
 GraphicBuffer::GraphicBuffer()
-    : BASE(), mOwner(false), mBufferMapper(GraphicBufferMapper::get()),
+    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
       mInitCheck(NO_ERROR),  mVStride(0), mIndex(-1)
 {
     width  = 
@@ -50,7 +50,7 @@
 
 GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, 
         PixelFormat reqFormat, uint32_t reqUsage)
-    : BASE(), mOwner(false), mBufferMapper(GraphicBufferMapper::get()),
+    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
       mInitCheck(NO_ERROR),  mVStride(0), mIndex(-1)
 {
     width  = 
@@ -62,8 +62,23 @@
     mInitCheck = initSize(w, h, reqFormat, reqUsage);
 }
 
+GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
+        PixelFormat inFormat, uint32_t inUsage,
+        uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
+    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
+      mBufferMapper(GraphicBufferMapper::get()),
+      mInitCheck(NO_ERROR),  mVStride(0), mIndex(-1)
+{
+    width  = w;
+    height = h;
+    stride = inStride;
+    format = inFormat;
+    usage  = inUsage;
+    handle = inHandle;
+}
+
 GraphicBuffer::GraphicBuffer(const Parcel& data) 
-    : BASE(), mOwner(true), mBufferMapper(GraphicBufferMapper::get()),
+    : BASE(), mOwner(ownHandle), mBufferMapper(GraphicBufferMapper::get()),
       mInitCheck(NO_ERROR),  mVStride(0), mIndex(-1)
 {
     // we own the handle in this case
@@ -83,10 +98,10 @@
 GraphicBuffer::~GraphicBuffer()
 {
     if (handle) {
-        if (mOwner) {
+        if (mOwner == ownHandle) {
             native_handle_close(handle);
             native_handle_delete(const_cast<native_handle*>(handle));
-        } else {
+        } else if (mOwner == ownData) {
             GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
             allocator.free(handle);
         }
@@ -106,6 +121,9 @@
 status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f,
         uint32_t reqUsage)
 {
+    if (mOwner != ownData)
+        return INVALID_OPERATION;
+
     if (handle) {
         GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
         allocator.free(handle);
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index d90871e..58a0bba 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -959,10 +959,10 @@
     ///////////////////////////////////////////////////////////////////////////
 
     public class VolumeStreamState {
-        private final String mVolumeIndexSettingName;
-        private final String mLastAudibleVolumeIndexSettingName;
         private final int mStreamType;
 
+        private String mVolumeIndexSettingName;
+        private String mLastAudibleVolumeIndexSettingName;
         private int mIndexMax;
         private int mIndex;
         private int mLastAudibleIndex;
@@ -970,8 +970,7 @@
 
         private VolumeStreamState(String settingName, int streamType) {
 
-            mVolumeIndexSettingName = settingName;
-            mLastAudibleVolumeIndexSettingName = settingName + System.APPEND_FOR_LAST_AUDIBLE;
+            setVolumeIndexSettingName(settingName);
 
             mStreamType = streamType;
 
@@ -991,6 +990,11 @@
             mDeathHandlers = new ArrayList<VolumeDeathHandler>();
         }
 
+        public void setVolumeIndexSettingName(String settingName) {
+            mVolumeIndexSettingName = settingName;
+            mLastAudibleVolumeIndexSettingName = settingName + System.APPEND_FOR_LAST_AUDIBLE;
+        }
+
         public boolean adjustIndex(int deltaIndex) {
             return setIndex(mIndex + deltaIndex * 10, true);
         }
@@ -1370,11 +1374,17 @@
                     mNotificationsUseRingVolume = notificationsUseRingVolume;
                     if (mNotificationsUseRingVolume == 1) {
                         STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
+                        mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
+                                System.VOLUME_SETTINGS[AudioSystem.STREAM_RING]);
                     } else {
                         STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION;
+                        mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
+                                System.VOLUME_SETTINGS[AudioSystem.STREAM_NOTIFICATION]);
                         // Persist notification volume volume as it was not persisted while aliased to ring volume
+                        //  and persist with no delay as there might be registered observers of the persisted
+                        //  notification volume.
                         sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, AudioSystem.STREAM_NOTIFICATION,
-                                SENDMSG_REPLACE, 0, 0, mStreamStates[AudioSystem.STREAM_NOTIFICATION], PERSIST_DELAY);
+                                SENDMSG_REPLACE, 0, 0, mStreamStates[AudioSystem.STREAM_NOTIFICATION], 0);
                     }
                 }
             }
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
index 2522656..9837845 100644
--- a/opengl/libagl/Android.mk
+++ b/opengl/libagl/Android.mk
@@ -25,6 +25,13 @@
 	primitives.cpp.arm	        \
 	vertex.cpp.arm
 
+LOCAL_CFLAGS += -DLOG_TAG=\"libagl\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+LOCAL_CFLAGS += -fvisibility=hidden
+
+LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger
+LOCAL_LDLIBS := -lpthread -ldl
+
 ifeq ($(TARGET_ARCH),arm)
 	LOCAL_SRC_FILES += fixed_asm.S iterators.S
 	LOCAL_CFLAGS += -fstrict-aliasing
@@ -38,15 +45,9 @@
 ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1)
     LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS
     LOCAL_SRC_FILES += copybit.cpp
+    LOCAL_SHARED_LIBRARIES += libui
 endif
 
-LOCAL_CFLAGS += -DLOG_TAG=\"libagl\"
-LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-
-LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger
-LOCAL_CFLAGS += -fvisibility=hidden
-
-LOCAL_LDLIBS := -lpthread -ldl
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
 LOCAL_MODULE:= libGLES_android
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
index 73b2355..0c3d0ee 100644
--- a/opengl/libagl/copybit.cpp
+++ b/opengl/libagl/copybit.cpp
@@ -33,6 +33,10 @@
 #include <hardware/copybit.h>
 #include <private/ui/android_natives_priv.h>
 
+#include <ui/GraphicBuffer.h>
+#include <ui/Region.h>
+#include <ui/Rect.h>
+
 
 #define DEBUG_COPYBIT true
 
@@ -175,16 +179,6 @@
         dtdy /= screen_h;
     }
     dtdy = -dtdy; // see equation of dtdy above
-    if (dsdx < c->copybits.minScale || dsdx > c->copybits.maxScale
-            || dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) {
-        // The requested scale is out of the range the hardware
-        // can support.
-        LOGD_IF(DEBUG_COPYBIT,
-                "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
-                "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d", 
-                dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
-        return false;
-    }
 
     // copybit doesn't say anything about filtering, so we can't
     // discriminate. On msm7k, copybit will always filter.
@@ -278,21 +272,93 @@
         return false;
     }
 
-
-    // LOGW("calling copybits");
-
     copybit_device_t* copybit = c->copybits.blitEngine;
+    copybit_image_t src;
+    buffer_handle_t source_hnd = textureObject->buffer->handle;
+    textureToCopyBitImage(&textureObject->surface, opFormat, source_hnd, &src);
+    copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
+
+    /*
+     *  Below we perform extra passes needed to emulate things the h/w
+     * cannot do.
+     */
+
+    const GLfixed minScaleInv = gglDivQ(0x10000, c->copybits.minScale, 16);
+    const GLfixed maxScaleInv = gglDivQ(0x10000, c->copybits.maxScale, 16);
+
+    sp<GraphicBuffer> tempBitmap;
+
+    if (dsdx < maxScaleInv || dsdx > minScaleInv ||
+        dtdy < maxScaleInv || dtdy > minScaleInv)
+    {
+        // The requested scale is out of the range the hardware
+        // can support.
+        LOGD_IF(DEBUG_COPYBIT,
+                "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
+                "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
+                dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
+
+        int32_t xscale=0x10000, yscale=0x10000;
+        if (dsdx > minScaleInv)         xscale = c->copybits.minScale;
+        else if (dsdx < maxScaleInv)    xscale = c->copybits.maxScale;
+        if (dtdy > minScaleInv)         yscale = c->copybits.minScale;
+        else if (dtdy < maxScaleInv)    yscale = c->copybits.maxScale;
+        dsdx = gglMulx(dsdx, xscale);
+        dtdy = gglMulx(dtdy, yscale);
+
+        /* we handle only one step of resizing below. Handling an arbitrary
+         * number is relatively easy (replace "if" above by "while"), but requires
+         * two intermediate buffers and so far we never had the need.
+         */
+
+        if (dsdx < maxScaleInv || dsdx > minScaleInv ||
+            dtdy < maxScaleInv || dtdy > minScaleInv) {
+            LOGD_IF(DEBUG_COPYBIT,
+                    "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
+                    "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
+                    dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
+            return false;
+        }
+
+        const int tmp_w = gglMulx(srect.r - srect.l, xscale, 16);
+        const int tmp_h = gglMulx(srect.b - srect.t, yscale, 16);
+
+        LOGD_IF(DEBUG_COPYBIT,
+                "xscale=%08x, yscale=%08x, dsdx=%08x, dtdy=%08x, tmp_w=%d, tmp_h=%d",
+                xscale, yscale, dsdx, dtdy, tmp_w, tmp_h);
+
+        tempBitmap = new GraphicBuffer(
+                    tmp_w, tmp_h, src.format,
+                    GraphicBuffer::USAGE_HW_2D);
+
+        status_t err = tempBitmap->initCheck();
+        if (err == NO_ERROR) {
+            copybit_image_t tmp_dst;
+            copybit_rect_t tmp_rect;
+            tmp_dst.w = tmp_w;
+            tmp_dst.h = tmp_h;
+            tmp_dst.format = src.format;
+            tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle;
+            tmp_rect.l = 0;
+            tmp_rect.t = 0;
+            tmp_rect.r = tmp_dst.w;
+            tmp_rect.b = tmp_dst.h;
+            region_iterator tmp_it(Region(Rect(tmp_rect.r, tmp_rect.b)));
+            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
+            err = copybit->stretch(copybit,
+                    &tmp_dst, &src, &tmp_rect, &srect, &tmp_it);
+            src = tmp_dst;
+            srect = tmp_rect;
+        }
+    }
 
     copybit_image_t dst;
     buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer;
     textureToCopyBitImage(&cbSurface, cbSurface.format, target_hnd, &dst);
     copybit_rect_t drect = {x, y, x+w, y+h};
 
-    copybit_image_t src;
-    buffer_handle_t source_hnd = textureObject->buffer->handle;
-    textureToCopyBitImage(&textureObject->surface, opFormat, source_hnd, &src);
-    copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
-
     copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
     copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha);
     copybit->set_parameter(copybit, COPYBIT_DITHER,
diff --git a/opengl/tests/linetex/Android.mk b/opengl/tests/linetex/Android.mk
new file mode 100644
index 0000000..6ff248d
--- /dev/null
+++ b/opengl/tests/linetex/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	linetex.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv1_CM \
+    libui
+
+LOCAL_MODULE:= test-opengl-linetex
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/linetex/linetex.cpp b/opengl/tests/linetex/linetex.cpp
new file mode 100644
index 0000000..e62fe03
--- /dev/null
+++ b/opengl/tests/linetex/linetex.cpp
@@ -0,0 +1,117 @@
+/*
+**
+** 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.
+*/
+
+#define LOG_TAG "fillrate"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <utils/StopWatch.h>
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/EGLUtils.h>
+
+using namespace android;
+
+int main(int argc, char** argv)
+{
+    EGLint configAttribs[] = {
+         EGL_DEPTH_SIZE, 0,
+         EGL_NONE
+     };
+     
+     EGLint majorVersion;
+     EGLint minorVersion;
+     EGLContext context;
+     EGLConfig config;
+     EGLSurface surface;
+     EGLint w, h;
+     EGLDisplay dpy;
+
+     EGLNativeWindowType window = android_createDisplaySurface();
+     
+     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+     eglInitialize(dpy, &majorVersion, &minorVersion);
+          
+     status_t err = EGLUtils::selectConfigForNativeWindow(
+             dpy, configAttribs, window, &config);
+     if (err) {
+         fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n");
+         return 0;
+     }
+
+     surface = eglCreateWindowSurface(dpy, config, window, NULL);
+     context = eglCreateContext(dpy, config, NULL, NULL);
+     eglMakeCurrent(dpy, surface, surface, context);   
+     eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+     eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+     
+     printf("w=%d, h=%d\n", w, h);
+     
+     glBindTexture(GL_TEXTURE_2D, 0);
+     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+     glDisable(GL_DITHER);
+     glDisable(GL_BLEND);
+     glEnable(GL_TEXTURE_2D);
+     glColor4f(1,1,1,1);
+
+     const uint32_t t32[] = {
+             0xFFFFFFFF, 0xFF0000FF, 0xFF00FF00, 0xFFFF0000,
+             0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF, 0xFF000000
+     };
+
+     const GLfloat vertices[4][2] = {
+             { 0,  0 },
+             { w,  h }
+     };
+
+     const GLfloat texCoords[4][2] = {
+             { 0,  0 },
+             { 1,  0 }
+     };
+
+     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, t32);
+
+     glViewport(0, 0, w, h);
+     glMatrixMode(GL_PROJECTION);
+     glLoadIdentity();
+     glOrthof(0, w, 0, h, 0, 1);
+
+     glEnableClientState(GL_VERTEX_ARRAY);
+     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+     glVertexPointer(2, GL_FLOAT, 0, vertices);
+     glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+
+     glClearColor(0,0,0,0);
+     glClear(GL_COLOR_BUFFER_BIT);
+     glDrawArrays(GL_LINES, 0, 2);
+     eglSwapBuffers(dpy, surface);
+
+     usleep(5*1000000);
+
+     eglTerminate(dpy);
+     
+     return 0;
+}
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 927c1b3..4bf606d 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -158,7 +158,6 @@
     private int mProximityCount = 0;
     private int mPowerState;
     private boolean mOffBecauseOfUser;
-    private boolean mAnimatingScreenOff;
     private int mUserState;
     private boolean mKeyboardVisible = false;
     private boolean mUserActivityAllowed = true;
@@ -1232,7 +1231,6 @@
                         Log.d(TAG,
                               "preventScreenOn: turning on after a prior preventScreenOn(true)!");
                     }
-                    mAnimatingScreenOff = false;
                     int err = setScreenStateLocked(true);
                     if (err != 0) {
                         Log.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
@@ -1394,7 +1392,6 @@
                         reallyTurnScreenOn = false;
                     }
                     if (reallyTurnScreenOn) {
-                        mAnimatingScreenOff = false;
                         err = setScreenStateLocked(true);
                         long identity = Binder.clearCallingIdentity();
                         try {
@@ -1436,7 +1433,6 @@
                     if (!mScreenBrightness.animating) {
                         err = screenOffFinishedAnimatingLocked(becauseOfUser);
                     } else {
-                        mAnimatingScreenOff = true;
                         mOffBecauseOfUser = becauseOfUser;
                         err = 0;
                         mLastTouchDown = 0;
@@ -1454,7 +1450,6 @@
                 mTotalTouchDownTime, mTouchCycles);
         mLastTouchDown = 0;
         int err = setScreenStateLocked(false);
-        mAnimatingScreenOff = false;
         if (mScreenOnStartTime != 0) {
             mScreenOnTime += SystemClock.elapsedRealtime() - mScreenOnStartTime;
             mScreenOnStartTime = 0;
@@ -1827,9 +1822,6 @@
             return;
         }
 
-        if (mAnimatingScreenOff) {
-            return;
-        }
         if (false) {
             if (((mPokey & POKE_LOCK_IGNORE_CHEEK_EVENTS) != 0)) {
                 Log.d(TAG, "userActivity !!!");//, new RuntimeException());
@@ -1847,6 +1839,11 @@
                         + " mProximitySensorActive=" + mProximitySensorActive
                         + " force=" + force);
             }
+            // ignore user activity if we are in the process of turning off the screen
+            if (mScreenBrightness.animating && mScreenBrightness.targetValue == 0) {
+                Log.d(TAG, "ignoring user activity while turning off screen");
+                return;
+            }
             if (mLastEventTime <= time || force) {
                 mLastEventTime = time;
                 if ((mUserActivityAllowed && !mProximitySensorActive) || force) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index ad1926e..56270f4 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2705,13 +2705,31 @@
 
             // Have the window manager re-evaluate the orientation of
             // the screen based on the new activity order.
-            Configuration config = mWindowManager.updateOrientationFromAppTokens(
-                    mConfiguration,
-                    next.mayFreezeScreenLocked(next.app) ? next : null);
-            if (config != null) {
-                next.frozenBeforeDestroy = true;
+            boolean updated;
+            synchronized (this) {
+                Configuration config = mWindowManager.updateOrientationFromAppTokens(
+                        mConfiguration,
+                        next.mayFreezeScreenLocked(next.app) ? next : null);
+                if (config != null) {
+                    /*
+                     * Explicitly restore the locale to the one from the
+                     * old configuration, since the one that comes back from
+                     * the window manager has the default (boot) locale.
+                     *
+                     * It looks like previously the locale picker only worked
+                     * by coincidence: usually it would do its setting of
+                     * the locale after the activity transition, so it didn't
+                     * matter that this lost it.  With the synchronized
+                     * block now keeping them from happening at the same time,
+                     * this one always would happen second and undo what the
+                     * locale picker had just done.
+                     */
+                    config.locale = mConfiguration.locale;
+                    next.frozenBeforeDestroy = true;
+                }
+                updated = updateConfigurationLocked(config, next);
             }
-            if (!updateConfigurationLocked(config, next)) {
+            if (!updated) {
                 // The configuration update wasn't able to keep the existing
                 // instance of the activity, and instead started a new one.
                 // We should be all done, but let's just make sure our activity