Merge "Don't recreate view's display list when size hasn't changed"
diff --git a/api/current.txt b/api/current.txt
index ecbc9d2..4997ae6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -207,6 +207,7 @@
     field public static final int actionModeCutDrawable = 16843537; // 0x1010311
     field public static final int actionModePasteDrawable = 16843539; // 0x1010313
     field public static final int actionModeSelectAllDrawable = 16843647; // 0x101037f
+    field public static final int actionModeStyle = 16843688; // 0x10103a8
     field public static final int actionOverflowButtonStyle = 16843510; // 0x10102f6
     field public static final int actionProviderClass = 16843677; // 0x101039d
     field public static final int actionViewClass = 16843516; // 0x10102fc
@@ -20494,6 +20495,14 @@
     ctor public Base64OutputStream(java.io.OutputStream, int);
   }
 
+  public final deprecated class Config {
+    field public static final deprecated boolean DEBUG = false;
+    field public static final deprecated boolean LOGD = true;
+    field public static final deprecated boolean LOGV = false;
+    field public static final deprecated boolean PROFILE = false;
+    field public static final deprecated boolean RELEASE = true;
+  }
+
   public class DebugUtils {
     method public static boolean isObjectSelected(java.lang.Object);
   }
@@ -20922,11 +20931,13 @@
     method public abstract android.view.Menu getMenu();
     method public abstract android.view.MenuInflater getMenuInflater();
     method public abstract java.lang.CharSequence getSubtitle();
+    method public java.lang.Object getTag();
     method public abstract java.lang.CharSequence getTitle();
     method public abstract void invalidate();
     method public abstract void setCustomView(android.view.View);
     method public abstract void setSubtitle(java.lang.CharSequence);
     method public abstract void setSubtitle(int);
+    method public void setTag(java.lang.Object);
     method public abstract void setTitle(java.lang.CharSequence);
     method public abstract void setTitle(int);
   }
@@ -22039,9 +22050,12 @@
     method public android.graphics.SurfaceTexture getSurfaceTexture();
     method public android.view.TextureView.SurfaceTextureListener getSurfaceTextureListener();
     method public boolean isAvailable();
+    method public android.graphics.Canvas lockCanvas();
+    method public android.graphics.Canvas lockCanvas(android.graphics.Rect);
     method protected final void onDraw(android.graphics.Canvas);
     method public void setOpaque(boolean);
     method public void setSurfaceTextureListener(android.view.TextureView.SurfaceTextureListener);
+    method public void unlockCanvasAndPost(android.graphics.Canvas);
   }
 
   public static abstract interface TextureView.SurfaceTextureListener {
@@ -23894,7 +23908,7 @@
     method public boolean isWatchingCursor(android.view.View);
     method public void restartInput(android.view.View);
     method public void sendAppPrivateCommand(android.view.View, java.lang.String, android.os.Bundle);
-    method public boolean setAdditionalInputMethodSubtypes(android.os.IBinder, android.view.inputmethod.InputMethodSubtype[]);
+    method public boolean setAdditionalInputMethodSubtypes(java.lang.String, android.view.inputmethod.InputMethodSubtype[]);
     method public boolean setCurrentInputMethodSubtype(android.view.inputmethod.InputMethodSubtype);
     method public void setInputMethod(android.os.IBinder, java.lang.String);
     method public void setInputMethodAndSubtype(android.os.IBinder, java.lang.String, android.view.inputmethod.InputMethodSubtype);
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c6a746b..f6cd866 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -70,7 +70,7 @@
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewManager;
-import android.view.ViewAncestor;
+import android.view.ViewRootImpl;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
@@ -3558,6 +3558,7 @@
     }
 
     final void handleTrimMemory(int level) {
+        WindowManagerImpl.getDefault().trimMemory(level);
     }
 
     private final void handleBindApplication(AppBindData data) {
@@ -4071,7 +4072,7 @@
         sThreadLocal.set(this);
         mSystemThread = system;
         if (!system) {
-            ViewAncestor.addFirstDrawHandler(new Runnable() {
+            ViewRootImpl.addFirstDrawHandler(new Runnable() {
                 public void run() {
                     ensureJitEnabled();
                 }
@@ -4101,7 +4102,7 @@
             }
         }
         
-        ViewAncestor.addConfigCallback(new ComponentCallbacks() {
+        ViewRootImpl.addConfigCallback(new ComponentCallbacks() {
             public void onConfigurationChanged(Configuration newConfig) {
                 synchronized (mPackages) {
                     // We need to apply this change to the resources
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 42eda02..8e2d360 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -168,6 +168,7 @@
         SearchBar searchBar = (SearchBar) findViewById(com.android.internal.R.id.search_bar);
         searchBar.setSearchDialog(this);
         mSearchView = (SearchView) findViewById(com.android.internal.R.id.search_view);
+        mSearchView.setIconified(false);
         mSearchView.setOnCloseListener(mOnCloseListener);
         mSearchView.setOnQueryTextListener(mOnQueryChangeListener);
         mSearchView.setOnSuggestionListener(mOnSuggestionSelectionListener);
@@ -633,31 +634,6 @@
         }
 
         /**
-         * Overrides the handling of the back key to move back to the previous
-         * sources or dismiss the search dialog, instead of dismissing the input
-         * method.
-         */
-        @Override
-        public boolean dispatchKeyEventPreIme(KeyEvent event) {
-            if (DBG)
-                Log.d(LOG_TAG, "onKeyPreIme(" + event + ")");
-            if (mSearchDialog != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
-                KeyEvent.DispatcherState state = getKeyDispatcherState();
-                if (state != null) {
-                    if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
-                        state.startTracking(event, this);
-                        return true;
-                    } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled()
-                            && state.isTracking(event)) {
-                        mSearchDialog.onBackPressed();
-                        return true;
-                    }
-                }
-            }
-            return super.dispatchKeyEventPreIme(event);
-        }
-
-        /**
          * Don't allow action modes in a SearchBar, it looks silly.
          */
         @Override
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index c179b35..4c21d04 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -662,12 +662,6 @@
     protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         writer.println("nothing to dump");
     }
-    
-    @Override
-    protected void finalize() throws Throwable {
-        super.finalize();
-        //Log.i("Service", "Finalizing Service: " + this);
-    }
 
     // ------------------ Internal API ------------------
     
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 7fd5a7d..8472b31 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -40,7 +40,7 @@
 import android.os.ServiceManager;
 import android.util.DisplayMetrics;
 import android.util.Log;
-import android.view.ViewAncestor;
+import android.view.ViewRootImpl;
 
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -592,7 +592,7 @@
     public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) {
         try {
             //Log.v(TAG, "Sending new wallpaper offsets from app...");
-            ViewAncestor.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
+            ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
                     windowToken, xOffset, yOffset, mWallpaperXStep, mWallpaperYStep);
             //Log.v(TAG, "...app returning after sending offsets!");
         } catch (RemoteException e) {
@@ -630,7 +630,7 @@
             int x, int y, int z, Bundle extras) {
         try {
             //Log.v(TAG, "Sending new wallpaper offsets from app...");
-            ViewAncestor.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand(
+            ViewRootImpl.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand(
                     windowToken, action, x, y, z, extras, false);
             //Log.v(TAG, "...app returning after sending offsets!");
         } catch (RemoteException e) {
@@ -650,7 +650,7 @@
      */
     public void clearWallpaperOffsets(IBinder windowToken) {
         try {
-            ViewAncestor.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
+            ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
                     windowToken, -1, -1, -1, -1);
         } catch (RemoteException e) {
             // Ignore.
diff --git a/core/java/android/content/SearchRecentSuggestionsProvider.java b/core/java/android/content/SearchRecentSuggestionsProvider.java
index 3d89e92..e1a8d21 100644
--- a/core/java/android/content/SearchRecentSuggestionsProvider.java
+++ b/core/java/android/content/SearchRecentSuggestionsProvider.java
@@ -186,6 +186,9 @@
 
             mSuggestionProjection = new String [] {
                     "0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT,
+                    "'android.resource://system/"
+                            + com.android.internal.R.drawable.ic_menu_recent_history + "' AS "
+                            + SearchManager.SUGGEST_COLUMN_ICON_1,
                     "display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
                     "display2 AS " + SearchManager.SUGGEST_COLUMN_TEXT_2,
                     "query AS " + SearchManager.SUGGEST_COLUMN_QUERY,
@@ -196,6 +199,9 @@
 
             mSuggestionProjection = new String [] {
                     "0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT,
+                    "'android.resource://system/"
+                            + com.android.internal.R.drawable.ic_menu_recent_history + "' AS "
+                            + SearchManager.SUGGEST_COLUMN_ICON_1,
                     "display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
                     "query AS " + SearchManager.SUGGEST_COLUMN_QUERY,
                     "_id"
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 67d200c..b548623 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -409,9 +409,10 @@
 
     /**
      * Sets the current USB function.
+     * If function is null, then the current function is set to the default function.
      *
-     * @param function name of the USB function
-     * @param makeDefault true if this should be set as the default
+     * @param function name of the USB function, or null to restore the default function
+     * @param makeDefault true if the function should be set as the new default function
      *
      * {@hide}
      */
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 8fc8b9d..c51ba2a 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -51,7 +51,7 @@
 import android.view.SurfaceHolder;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewAncestor;
+import android.view.ViewRootImpl;
 import android.view.WindowManager;
 import android.view.WindowManagerImpl;
 import android.view.WindowManagerPolicy;
@@ -650,7 +650,7 @@
             mWindowToken = wrapper.mWindowToken;
             mSurfaceHolder.setSizeFromLayout();
             mInitializing = true;
-            mSession = ViewAncestor.getWindowSession(getMainLooper());
+            mSession = ViewRootImpl.getWindowSession(getMainLooper());
             
             mWindow.setSession(mSession);
             
diff --git a/core/java/android/util/Config.java b/core/java/android/util/Config.java
new file mode 100644
index 0000000..70dc9aa
--- /dev/null
+++ b/core/java/android/util/Config.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.util;
+
+/**
+ * @deprecated This class is not useful, it just returns the same value for
+ * all constants, and has always done this.  Do not use it.
+ */
+@Deprecated
+public final class Config {
+    /** @hide */ public Config() {}
+
+    /**
+     * @deprecated Always false.
+     */
+    @Deprecated
+    public static final boolean DEBUG = false;
+
+    /**
+     * @deprecated Always true.
+     */
+    @Deprecated
+    public static final boolean RELEASE = true;
+
+    /**
+     * @deprecated Always false.
+     */
+    @Deprecated
+    public static final boolean PROFILE = false;
+
+    /**
+     * @deprecated Always false.
+     */
+    @Deprecated
+    public static final boolean LOGV = false;
+
+    /**
+     * @deprecated Always true.
+     */
+    @Deprecated
+    public static final boolean LOGD = true;
+}
diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java
index bfafa98..e954983 100644
--- a/core/java/android/view/ActionMode.java
+++ b/core/java/android/view/ActionMode.java
@@ -23,6 +23,36 @@
  * Examples of good action modes include selection modes, search, content editing, etc.
  */
 public abstract class ActionMode {
+    private Object mTag;
+
+    /**
+     * Set a tag object associated with this ActionMode.
+     *
+     * <p>Like the tag available to views, this allows applications to associate arbitrary
+     * data with an ActionMode for later reference.
+     *
+     * @param tag Tag to associate with this ActionMode
+     *
+     * @see #getTag()
+     */
+    public void setTag(Object tag) {
+        mTag = tag;
+    }
+
+    /**
+     * Retrieve the tag object associated with this ActionMode.
+     *
+     * <p>Like the tag available to views, this allows applications to associate arbitrary
+     * data with an ActionMode for later reference.
+     *
+     * @return Tag associated with this ActionMode
+     *
+     * @see #setTag(Object)
+     */
+    public Object getTag() {
+        return mTag;
+    }
+
     /**
      * Set the title of the action mode. This method will have no visible effect if
      * a custom view has been set.
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 4987e2f..80244bb 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -286,6 +286,38 @@
 
     private static native boolean nCallDrawGLFunction(int renderer, int drawGLFunction);
 
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Memory
+    ///////////////////////////////////////////////////////////////////////////
+
+    /**
+     * @see #flushCaches(int) 
+     */
+    public static final int FLUSH_CACHES_MODERATE = 0;
+
+    /**
+     * @see #flushCaches(int) 
+     */
+    public static final int FLUSH_CACHES_FULL = 1;
+
+    /**
+     * Flush caches to reclaim as much memory as possible. The amount of memory
+     * to reclaim is indicate by the level parameter.
+     * 
+     * The level can be one of {@link #FLUSH_CACHES_MODERATE} or
+     * {@link #FLUSH_CACHES_FULL}.
+     * 
+     * @param level Hint about the amount of memory to reclaim
+     * 
+     * @hide
+     */
+    public static void flushCaches(int level) {
+        nFlushCaches(level);
+    }
+
+    private static native void nFlushCaches(int level);
+
     ///////////////////////////////////////////////////////////////////////////
     // Display list
     ///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 011e44c..9a2564f 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -17,6 +17,7 @@
 
 package android.view;
 
+import android.content.ComponentCallbacks;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
@@ -263,6 +264,18 @@
     }
 
     /**
+     * Invoke this method when the system is running out of memory. This
+     * method will attempt to recover as much memory as possible, based on
+     * the specified hint.
+     * 
+     * @param level Hint about the amount of memory that should be trimmed,
+     *              see {@link android.content.ComponentCallbacks}
+     */
+    static void trimMemory(int level) {
+        Gl20Renderer.flushCaches(level);
+    }
+
+    /**
      * Indicates whether hardware acceleration is currently enabled.
      * 
      * @return True if hardware acceleration is in use, false otherwise.
@@ -858,5 +871,16 @@
             }
             return null;
         }
+        
+        static void flushCaches(int level) {
+            switch (level) {
+                case ComponentCallbacks.TRIM_MEMORY_MODERATE:
+                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
+                    break;
+                case ComponentCallbacks.TRIM_MEMORY_COMPLETE:
+                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
+                    break;
+            }
+        }
     }
 }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 764899f..cbdb38e 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -426,7 +426,7 @@
         if (!mHaveFrame) {
             return;
         }
-        ViewAncestor viewRoot = (ViewAncestor) getRootView().getParent();
+        ViewRootImpl viewRoot = (ViewRootImpl) getRootView().getParent();
         if (viewRoot != null) {
             mTranslator = viewRoot.mTranslator;
         }
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index d656f31..96d6f09 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -20,6 +20,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -107,6 +108,14 @@
 
     private SurfaceTexture.OnFrameAvailableListener mUpdateListener;
 
+    private Canvas mCanvas;
+    private int mSaveCount;
+
+    private final Object[] mNativeWindowLock = new Object[0];
+    // Used from native code, do not write!
+    @SuppressWarnings({"UnusedDeclaration"})
+    private int mNativeWindow;
+
     /**
      * Creates a new TextureView.
      * 
@@ -190,7 +199,11 @@
                 mListener.onSurfaceTextureDestroyed(mSurface);
             }
 
-            mLayer.destroy();            
+            synchronized (mNativeWindowLock) {
+                nDestroyNativeWindow();
+            }
+
+            mLayer.destroy();
             mSurface = null;
             mLayer = null;
         }
@@ -274,6 +287,7 @@
             mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(mOpaque);
             mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
             nSetDefaultBufferSize(mSurface, getWidth(), getHeight());
+            nCreateNativeWindow(mSurface);            
 
             mUpdateListener = new SurfaceTexture.OnFrameAvailableListener() {
                 @Override
@@ -431,6 +445,79 @@
     }
 
     /**
+     * <p>Start editing the pixels in the surface.  The returned Canvas can be used
+     * to draw into the surface's bitmap.  A null is returned if the surface has
+     * not been created or otherwise cannot be edited. You will usually need
+     * to implement
+     * {@link SurfaceTextureListener#onSurfaceTextureAvailable(android.graphics.SurfaceTexture, int, int)}
+     * to find out when the Surface is available for use.</p>
+     * 
+     * <p>The content of the Surface is never preserved between unlockCanvas()
+     * and lockCanvas(), for this reason, every pixel within the Surface area
+     * must be written. The only exception to this rule is when a dirty
+     * rectangle is specified, in which case, non-dirty pixels will be
+     * preserved.</p>
+     * 
+     * @return A Canvas used to draw into the surface.
+     * 
+     * @see #lockCanvas(android.graphics.Rect) 
+     * @see #unlockCanvasAndPost(android.graphics.Canvas) 
+     */
+    public Canvas lockCanvas() {
+        return lockCanvas(null);
+    }
+
+    /**
+     * Just like {@link #lockCanvas()} but allows specification of a dirty
+     * rectangle. Every pixel within that rectangle must be written; however
+     * pixels outside the dirty rectangle will be preserved by the next call
+     * to lockCanvas().
+     * 
+     * @param dirty Area of the surface that will be modified.
+
+     * @return A Canvas used to draw into the surface.
+     * 
+     * @see #lockCanvas() 
+     * @see #unlockCanvasAndPost(android.graphics.Canvas) 
+     */
+    public Canvas lockCanvas(Rect dirty) {
+        if (!isAvailable()) return null;
+
+        if (mCanvas == null) {
+            mCanvas = new Canvas();
+        }
+
+        synchronized (mNativeWindowLock) {
+            nLockCanvas(mNativeWindow, mCanvas, dirty);
+        }
+        mSaveCount = mCanvas.save();
+
+        return mCanvas;
+    }
+
+    /**
+     * Finish editing pixels in the surface. After this call, the surface's
+     * current pixels will be shown on the screen, but its content is lost,
+     * in particular there is no guarantee that the content of the Surface
+     * will remain unchanged when lockCanvas() is called again.
+     * 
+     * @param canvas The Canvas previously returned by lockCanvas()
+     * 
+     * @see #lockCanvas()
+     * @see #lockCanvas(android.graphics.Rect) 
+     */
+    public void unlockCanvasAndPost(Canvas canvas) {
+        if (mCanvas != null && canvas == mCanvas) {
+            canvas.restoreToCount(mSaveCount);
+            mSaveCount = 0;
+
+            synchronized (mNativeWindowLock) {
+                nUnlockCanvasAndPost(mNativeWindow, mCanvas);
+            }
+        }
+    }
+
+    /**
      * Returns the {@link SurfaceTexture} used by this view. This method
      * may return null if the view is not attached to a window or if the surface
      * texture has not been initialized yet.
@@ -506,6 +593,12 @@
         public void onSurfaceTextureUpdated(SurfaceTexture surface);
     }
 
+    private native void nCreateNativeWindow(SurfaceTexture surface);
+    private native void nDestroyNativeWindow();
+
     private static native void nSetDefaultBufferSize(SurfaceTexture surfaceTexture,
             int width, int height);
+
+    private static native void nLockCanvas(int nativeWindow, Canvas canvas, Rect dirty);
+    private static native void nUnlockCanvasAndPost(int nativeWindow, Canvas canvas);
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index dba6d31..59cb216 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5043,9 +5043,9 @@
     }
 
     /** Gets the ViewAncestor, or null if not attached. */
-    /*package*/ ViewAncestor getViewAncestor() {
+    /*package*/ ViewRootImpl getViewRootImpl() {
         View root = getRootView();
-        return root != null ? (ViewAncestor)root.getParent() : null;
+        return root != null ? (ViewRootImpl)root.getParent() : null;
     }
 
     /**
@@ -5061,7 +5061,7 @@
     public final boolean requestFocusFromTouch() {
         // Leave touch mode if we need to
         if (isInTouchMode()) {
-            ViewAncestor viewRoot = getViewAncestor();
+            ViewRootImpl viewRoot = getViewRootImpl();
             if (viewRoot != null) {
                 viewRoot.ensureTouchMode(false);
             }
@@ -5653,7 +5653,7 @@
         if (mAttachInfo != null) {
             return mAttachInfo.mInTouchMode;
         } else {
-            return ViewAncestor.isInTouchMode();
+            return ViewRootImpl.isInTouchMode();
         }
     }
 
@@ -8254,7 +8254,7 @@
             handler = attachInfo.mHandler;
         } else {
             // Assume that post will succeed later
-            ViewAncestor.getRunQueue().post(action);
+            ViewRootImpl.getRunQueue().post(action);
             return true;
         }
 
@@ -8284,7 +8284,7 @@
             handler = attachInfo.mHandler;
         } else {
             // Assume that post will succeed later
-            ViewAncestor.getRunQueue().postDelayed(action, delayMillis);
+            ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
             return true;
         }
 
@@ -8308,7 +8308,7 @@
             handler = attachInfo.mHandler;
         } else {
             // Assume that post will succeed later
-            ViewAncestor.getRunQueue().removeCallbacks(action);
+            ViewRootImpl.getRunQueue().removeCallbacks(action);
             return true;
         }
 
@@ -11580,9 +11580,9 @@
             viewParent = view.mParent;
         }
 
-        if (viewParent instanceof ViewAncestor) {
+        if (viewParent instanceof ViewRootImpl) {
             // *cough*
-            final ViewAncestor vr = (ViewAncestor)viewParent;
+            final ViewRootImpl vr = (ViewRootImpl)viewParent;
             location[1] -= vr.mCurScrollY;
         }
     }
@@ -12709,7 +12709,7 @@
                     surface.unlockCanvasAndPost(canvas);
                 }
 
-                final ViewAncestor root = getViewAncestor();
+                final ViewRootImpl root = getViewRootImpl();
 
                 // Cache the local state object for delivery with DragEvents
                 root.setLocalDragState(myLocalState);
@@ -13916,7 +13916,7 @@
         Canvas mCanvas;
 
         /**
-         * A Handler supplied by a view's {@link android.view.ViewAncestor}. This
+         * A Handler supplied by a view's {@link android.view.ViewRootImpl}. This
          * handler can be used to pump events in the UI events queue.
          */
         final Handler mHandler;
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index f7f5a21..b85159b 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -366,7 +366,7 @@
     }
 
     private static BufferedWriter sHierarchyTraces;
-    private static ViewAncestor sHierarhcyRoot;
+    private static ViewRootImpl sHierarhcyRoot;
     private static String sHierarchyTracePrefix;
 
     /**
@@ -415,7 +415,7 @@
      * @hide
      */
     public static long getViewAncestorInstanceCount() {
-        return Debug.countInstancesOfClass(ViewAncestor.class);
+        return Debug.countInstancesOfClass(ViewRootImpl.class);
     }
 
     /**
@@ -748,7 +748,7 @@
             return;
         }
 
-        sHierarhcyRoot = (ViewAncestor) view.getRootView().getParent();
+        sHierarhcyRoot = (ViewRootImpl) view.getRootView().getParent();
     }
 
     /**
@@ -1100,7 +1100,7 @@
 
     private static void outputDisplayList(View root, String parameter) throws IOException {
         final View view = findView(root, parameter);
-        view.getViewAncestor().outputDisplayList(view);
+        view.getViewRootImpl().outputDisplayList(view);
     }
 
     private static void capture(View root, final OutputStream clientStream, String parameter)
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index cb3e9c6..5f7673a 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -954,7 +954,7 @@
         final float tx = event.mX;
         final float ty = event.mY;
 
-        ViewAncestor root = getViewAncestor();
+        ViewRootImpl root = getViewRootImpl();
 
         // Dispatch down the view hierarchy
         switch (event.mAction) {
@@ -3839,13 +3839,13 @@
                     if (drawAnimation) {
                         if (view != null) {
                             view.mPrivateFlags |= DRAW_ANIMATION;
-                        } else if (parent instanceof ViewAncestor) {
-                            ((ViewAncestor) parent).mIsAnimating = true;
+                        } else if (parent instanceof ViewRootImpl) {
+                            ((ViewRootImpl) parent).mIsAnimating = true;
                         }
                     }
 
-                    if (parent instanceof ViewAncestor) {
-                        ((ViewAncestor) parent).invalidate();
+                    if (parent instanceof ViewRootImpl) {
+                        ((ViewRootImpl) parent).invalidate();
                         parent = null;
                     } else if (view != null) {
                         if ((view.mPrivateFlags & DRAWN) == DRAWN ||
@@ -3902,8 +3902,8 @@
                     if (drawAnimation) {
                         if (view != null) {
                             view.mPrivateFlags |= DRAW_ANIMATION;
-                        } else if (parent instanceof ViewAncestor) {
-                            ((ViewAncestor) parent).mIsAnimating = true;
+                        } else if (parent instanceof ViewRootImpl) {
+                            ((ViewRootImpl) parent).mIsAnimating = true;
                         }
                     }
 
@@ -4426,7 +4426,7 @@
             // If this group is dirty, check that the parent is dirty as well
             if ((mPrivateFlags & DIRTY_MASK) != 0) {
                 final ViewParent parent = getParent();
-                if (parent != null && !(parent instanceof ViewAncestor)) {
+                if (parent != null && !(parent instanceof ViewRootImpl)) {
                     if ((((View) parent).mPrivateFlags & DIRTY_MASK) == 0) {
                         result = false;
                         android.util.Log.d(ViewDebug.CONSISTENCY_LOG_TAG,
@@ -4995,7 +4995,7 @@
      * @hide
      */
     public void requestTransitionStart(LayoutTransition transition) {
-        ViewAncestor viewAncestor = getViewAncestor();
+        ViewRootImpl viewAncestor = getViewRootImpl();
         viewAncestor.requestTransitionStart(transition);
     }
 
diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewRootImpl.java
similarity index 98%
rename from core/java/android/view/ViewAncestor.java
rename to core/java/android/view/ViewRootImpl.java
index ac73611..470493d 100644
--- a/core/java/android/view/ViewAncestor.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -92,7 +92,7 @@
  * {@hide}
  */
 @SuppressWarnings({"EmptyCatchBlock", "PointlessBooleanExpression"})
-public final class ViewAncestor extends Handler implements ViewParent,
+public final class ViewRootImpl extends Handler implements ViewParent,
         View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {
     private static final String TAG = "ViewAncestor";
     private static final boolean DBG = false;
@@ -303,7 +303,7 @@
         }
     }
     
-    public ViewAncestor(Context context) {
+    public ViewRootImpl(Context context) {
         super();
 
         if (MEASURE_LATENCY) {
@@ -3807,14 +3807,14 @@
     }
     
     static class InputMethodCallback extends IInputMethodCallback.Stub {
-        private WeakReference<ViewAncestor> mViewAncestor;
+        private WeakReference<ViewRootImpl> mViewAncestor;
 
-        public InputMethodCallback(ViewAncestor viewAncestor) {
-            mViewAncestor = new WeakReference<ViewAncestor>(viewAncestor);
+        public InputMethodCallback(ViewRootImpl viewAncestor) {
+            mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
         }
 
         public void finishedEvent(int seq, boolean handled) {
-            final ViewAncestor viewAncestor = mViewAncestor.get();
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchFinishedEvent(seq, handled);
             }
@@ -3826,15 +3826,15 @@
     }
 
     static class W extends IWindow.Stub {
-        private final WeakReference<ViewAncestor> mViewAncestor;
+        private final WeakReference<ViewRootImpl> mViewAncestor;
 
-        W(ViewAncestor viewAncestor) {
-            mViewAncestor = new WeakReference<ViewAncestor>(viewAncestor);
+        W(ViewRootImpl viewAncestor) {
+            mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
         }
 
         public void resized(int w, int h, Rect coveredInsets, Rect visibleInsets,
                 boolean reportDraw, Configuration newConfig) {
-            final ViewAncestor viewAncestor = mViewAncestor.get();
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchResized(w, h, coveredInsets, visibleInsets, reportDraw,
                         newConfig);
@@ -3842,21 +3842,21 @@
         }
 
         public void dispatchAppVisibility(boolean visible) {
-            final ViewAncestor viewAncestor = mViewAncestor.get();
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchAppVisibility(visible);
             }
         }
 
         public void dispatchGetNewSurface() {
-            final ViewAncestor viewAncestor = mViewAncestor.get();
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchGetNewSurface();
             }
         }
 
         public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
-            final ViewAncestor viewAncestor = mViewAncestor.get();
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.windowFocusChanged(hasFocus, inTouchMode);
             }
@@ -3872,7 +3872,7 @@
         }
 
         public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
-            final ViewAncestor viewAncestor = mViewAncestor.get();
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 final View view = viewAncestor.mView;
                 if (view != null) {
@@ -3903,7 +3903,7 @@
         }
         
         public void closeSystemDialogs(String reason) {
-            final ViewAncestor viewAncestor = mViewAncestor.get();
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchCloseSystemDialogs(reason);
             }
@@ -3931,14 +3931,14 @@
 
         /* Drag/drop */
         public void dispatchDragEvent(DragEvent event) {
-            final ViewAncestor viewAncestor = mViewAncestor.get();
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchDragEvent(event);
             }
         }
 
         public void dispatchSystemUiVisibilityChanged(int visibility) {
-            final ViewAncestor viewAncestor = mViewAncestor.get();
+            final ViewRootImpl viewAncestor = mViewAncestor.get();
             if (viewAncestor != null) {
                 viewAncestor.dispatchSystemUiVisibilityChanged(visibility);
             }
@@ -4269,7 +4269,7 @@
             if (!registered) {
                 mAttachInfo.mAccessibilityWindowId =
                     mAccessibilityManager.addAccessibilityInteractionConnection(mWindow,
-                            new AccessibilityInteractionConnection(ViewAncestor.this));
+                            new AccessibilityInteractionConnection(ViewRootImpl.this));
             }
         }
 
@@ -4289,10 +4289,10 @@
      */
     final class AccessibilityInteractionConnection
             extends IAccessibilityInteractionConnection.Stub {
-        private final WeakReference<ViewAncestor> mViewAncestor;
+        private final WeakReference<ViewRootImpl> mViewAncestor;
 
-        AccessibilityInteractionConnection(ViewAncestor viewAncestor) {
-            mViewAncestor = new WeakReference<ViewAncestor>(viewAncestor);
+        AccessibilityInteractionConnection(ViewRootImpl viewAncestor) {
+            mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
         }
 
         public void findAccessibilityNodeInfoByAccessibilityId(int accessibilityId,
@@ -4421,7 +4421,7 @@
             try {
                 FindByAccessibilitytIdPredicate predicate = mFindByAccessibilityIdPredicate;
                 predicate.init(accessibilityId);
-                View root = ViewAncestor.this.mView;
+                View root = ViewRootImpl.this.mView;
                 View target = root.findViewByPredicate(predicate);
                 if (target != null && target.isShown()) {
                     info = target.createAccessibilityNodeInfo();
@@ -4453,7 +4453,7 @@
 
             AccessibilityNodeInfo info = null;
             try {
-                View root = ViewAncestor.this.mView;
+                View root = ViewRootImpl.this.mView;
                 View target = root.findViewById(viewId);
                 if (target != null && target.isShown()) {
                     info = target.createAccessibilityNodeInfo();
@@ -4499,7 +4499,7 @@
                 if (accessibilityViewId != View.NO_ID) {
                     root = findViewByAccessibilityId(accessibilityViewId);
                 } else {
-                    root = ViewAncestor.this.mView;
+                    root = ViewRootImpl.this.mView;
                 }
 
                 if (root == null || !root.isShown()) {
@@ -4624,7 +4624,7 @@
         }
 
         private View findViewByAccessibilityId(int accessibilityId) {
-            View root = ViewAncestor.this.mView;
+            View root = ViewRootImpl.this.mView;
             if (root == null) {
                 return null;
             }
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 54e7c04..a451bb5 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -16,18 +16,16 @@
 
 package android.view;
 
-import java.util.HashMap;
-
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.PixelFormat;
 import android.os.IBinder;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
-import android.util.Slog;
-import android.view.WindowManager;
 import android.view.inputmethod.InputMethodManager;
 
+import java.util.HashMap;
+
 final class WindowLeaked extends AndroidRuntimeException {
     public WindowLeaked(String msg) {
         super(msg);
@@ -80,7 +78,7 @@
     public static final int ADD_PERMISSION_DENIED = -8;
 
     private View[] mViews;
-    private ViewAncestor[] mRoots;
+    private ViewRootImpl[] mRoots;
     private WindowManager.LayoutParams[] mParams;
 
     private final static Object sLock = new Object();
@@ -204,7 +202,7 @@
         final WindowManager.LayoutParams wparams
                 = (WindowManager.LayoutParams)params;
         
-        ViewAncestor root;
+        ViewRootImpl root;
         View panelParentView = null;
         
         synchronized (this) {
@@ -241,7 +239,7 @@
                 }
             }
             
-            root = new ViewAncestor(view.getContext());
+            root = new ViewRootImpl(view.getContext());
             root.mAddNesting = 1;
             if (cih == null) {
                 root.mCompatibilityInfo = new CompatibilityInfoHolder();
@@ -254,7 +252,7 @@
             if (mViews == null) {
                 index = 1;
                 mViews = new View[1];
-                mRoots = new ViewAncestor[1];
+                mRoots = new ViewRootImpl[1];
                 mParams = new WindowManager.LayoutParams[1];
             } else {
                 index = mViews.length + 1;
@@ -262,7 +260,7 @@
                 mViews = new View[index];
                 System.arraycopy(old, 0, mViews, 0, index-1);
                 old = mRoots;
-                mRoots = new ViewAncestor[index];
+                mRoots = new ViewRootImpl[index];
                 System.arraycopy(old, 0, mRoots, 0, index-1);
                 old = mParams;
                 mParams = new WindowManager.LayoutParams[index];
@@ -290,7 +288,7 @@
 
         synchronized (this) {
             int index = findViewLocked(view, true);
-            ViewAncestor root = mRoots[index];
+            ViewRootImpl root = mRoots[index];
             mParams[index] = wparams;
             root.setLayoutParams(wparams, false);
         }
@@ -312,7 +310,7 @@
     public void removeViewImmediate(View view) {
         synchronized (this) {
             int index = findViewLocked(view, true);
-            ViewAncestor root = mRoots[index];
+            ViewRootImpl root = mRoots[index];
             View curView = root.getView();
             
             root.mAddNesting = 0;
@@ -328,7 +326,7 @@
     }
     
     View removeViewLocked(int index) {
-        ViewAncestor root = mRoots[index];
+        ViewRootImpl root = mRoots[index];
         View view = root.getView();
         
         // Don't really remove until we have matched all calls to add().
@@ -356,7 +354,7 @@
         removeItem(tmpViews, mViews, index);
         mViews = tmpViews;
         
-        ViewAncestor[] tmpRoots = new ViewAncestor[count-1];
+        ViewRootImpl[] tmpRoots = new ViewRootImpl[count-1];
         removeItem(tmpRoots, mRoots, index);
         mRoots = tmpRoots;
         
@@ -383,7 +381,7 @@
                 //Log.i("foo", "@ " + i + " token " + mParams[i].token
                 //        + " view " + mRoots[i].getView());
                 if (token == null || mParams[i].token == token) {
-                    ViewAncestor root = mRoots[i];
+                    ViewRootImpl root = mRoots[i];
                     root.mAddNesting = 1;
                     
                     //Log.i("foo", "Force closing " + root);
@@ -402,7 +400,16 @@
             }
         }
     }
-    
+
+    /**
+     * @param level See {@link android.content.ComponentCallbacks}
+     */
+    public void trimMemory(int level) {
+        if (HardwareRenderer.isAvailable()) {
+            HardwareRenderer.trimMemory(level);
+        }
+    }
+
     public void setStoppedState(IBinder token, boolean stopped) {
         synchronized (this) {
             if (mViews == null)
@@ -410,7 +417,7 @@
             int count = mViews.length;
             for (int i=0; i<count; i++) {
                 if (token == null || mParams[i].token == token) {
-                    ViewAncestor root = mRoots[i];
+                    ViewRootImpl root = mRoots[i];
                     root.setStopped(stopped);
                 }
             }
@@ -422,7 +429,7 @@
             int count = mViews.length;
             config = new Configuration(config);
             for (int i=0; i<count; i++) {
-                ViewAncestor root = mRoots[i];
+                ViewRootImpl root = mRoots[i];
                 root.requestUpdateConfiguration(config);
             }
         }
@@ -430,13 +437,13 @@
 
     public WindowManager.LayoutParams getRootViewLayoutParameter(View view) {
         ViewParent vp = view.getParent();
-        while (vp != null && !(vp instanceof ViewAncestor)) {
+        while (vp != null && !(vp instanceof ViewRootImpl)) {
             vp = vp.getParent();
         }
         
         if (vp == null) return null;
         
-        ViewAncestor vr = (ViewAncestor)vp;
+        ViewRootImpl vr = (ViewRootImpl)vp;
         
         int N = mRoots.length;
         for (int i = 0; i < N; ++i) {
@@ -456,8 +463,7 @@
         return new Display(Display.DEFAULT_DISPLAY, null);
     }
 
-    private static void removeItem(Object[] dst, Object[] src, int index)
-    {
+    private static void removeItem(Object[] dst, Object[] src, int index) {
         if (dst.length > 0) {
             if (index > 0) {
                 System.arraycopy(src, 0, dst, 0, index);
@@ -468,8 +474,7 @@
         }
     }
 
-    private int findViewLocked(View view, boolean required)
-    {
+    private int findViewLocked(View view, boolean required) {
         synchronized (this) {
             final int count = mViews != null ? mViews.length : 0;
             for (int i=0; i<count; i++) {
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index abe3c2c..5ec1ec3 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -34,7 +34,7 @@
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.View;
-import android.view.ViewAncestor;
+import android.view.ViewRootImpl;
 
 class ComposingText implements NoCopySpan {
 }
@@ -502,7 +502,7 @@
                 }
             }
             if (h != null) {
-                h.sendMessage(h.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME,
+                h.sendMessage(h.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
                         event));
             }
         }
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index a1a7281..da5baf8 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -26,6 +26,7 @@
 import com.android.internal.view.InputBindResult;
 
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Handler;
@@ -42,7 +43,7 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewAncestor;
+import android.view.ViewRootImpl;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -655,7 +656,7 @@
                 if (vh != null) {
                     // This will result in a call to reportFinishInputConnection()
                     // below.
-                    vh.sendMessage(vh.obtainMessage(ViewAncestor.FINISH_INPUT_CONNECTION,
+                    vh.sendMessage(vh.obtainMessage(ViewRootImpl.FINISH_INPUT_CONNECTION,
                             mServedInputConnection));
                 }
             }
@@ -1112,9 +1113,9 @@
 
     void scheduleCheckFocusLocked(View view) {
         Handler vh = view.getHandler();
-        if (vh != null && !vh.hasMessages(ViewAncestor.CHECK_FOCUS)) {
+        if (vh != null && !vh.hasMessages(ViewRootImpl.CHECK_FOCUS)) {
             // This will result in a call to checkFocus() below.
-            vh.sendMessage(vh.obtainMessage(ViewAncestor.CHECK_FOCUS));
+            vh.sendMessage(vh.obtainMessage(ViewRootImpl.CHECK_FOCUS));
         }
     }
     
@@ -1580,16 +1581,16 @@
     }
 
     /**
-     * Set additional input method subtypes.
-     * @param imeToken Supplies the identifying token given to an input method.
+     * Set additional input method subtypes. Only a process which shares the same uid with the IME
+     * can add additional input method subtypes to the IME.
+     * @param imiId Id of InputMethodInfo which additional input method subtypes will be added to.
      * @param subtypes subtypes will be added as additional subtypes of the current input method.
      * @return true if the additional input method subtypes are successfully added.
      */
-    public boolean setAdditionalInputMethodSubtypes(
-            IBinder imeToken, InputMethodSubtype[] subtypes) {
+    public boolean setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {
         synchronized (mH) {
             try {
-                return mService.setAdditionalInputMethodSubtypes(imeToken, subtypes);
+                return mService.setAdditionalInputMethodSubtypes(imiId, subtypes);
             } catch (RemoteException e) {
                 Log.w(TAG, "IME died: " + mCurId, e);
                 return false;
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 5aa60f4..738bcb9 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -35,7 +35,7 @@
 import android.util.Log;
 import android.util.TypedValue;
 import android.view.Surface;
-import android.view.ViewAncestor;
+import android.view.ViewRootImpl;
 import android.view.WindowManager;
 
 import junit.framework.Assert;
@@ -228,7 +228,7 @@
             sConfigCallback = new ConfigCallback(
                     (WindowManager) appContext.getSystemService(
                             Context.WINDOW_SERVICE));
-            ViewAncestor.addConfigCallback(sConfigCallback);
+            ViewRootImpl.addConfigCallback(sConfigCallback);
         }
         sConfigCallback.addHandler(this);
 
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index b9eb5ff..f82c61a 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -28,7 +28,7 @@
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
-import com.android.internal.R.styleable;
+import com.android.internal.R;
 
 import java.lang.reflect.Array;
 import java.util.ArrayList;
@@ -167,7 +167,7 @@
     // Misc constants
 
     private static final String TAG = GridLayout.class.getName();
-    static final boolean DEBUG = false;
+    static boolean DEBUG = false;
     private static final int PRF = 1;
 
     // Defaults
@@ -178,19 +178,17 @@
     private static final boolean DEFAULT_ORDER_PRESERVED = false;
     private static final int DEFAULT_ALIGNMENT_MODE = ALIGN_MARGINS;
     private static final int DEFAULT_CONTAINER_MARGIN = 0;
-    private static final int DEFAULT_MARGIN = 8;
-    private static final int DEFAULT_CONTAINER_PADDING = 16;
     private static final int MAX_SIZE = 100000;
 
     // TypedArray indices
 
-    private static final int ORIENTATION = styleable.GridLayout_orientation;
-    private static final int ROW_COUNT = styleable.GridLayout_rowCount;
-    private static final int COLUMN_COUNT = styleable.GridLayout_columnCount;
-    private static final int USE_DEFAULT_MARGINS = styleable.GridLayout_useDefaultMargins;
-    private static final int ALIGNMENT_MODE = styleable.GridLayout_alignmentMode;
-    private static final int ROW_ORDER_PRESERVED = styleable.GridLayout_rowOrderPreserved;
-    private static final int COLUMN_ORDER_PRESERVED = styleable.GridLayout_columnOrderPreserved;
+    private static final int ORIENTATION = R.styleable.GridLayout_orientation;
+    private static final int ROW_COUNT = R.styleable.GridLayout_rowCount;
+    private static final int COLUMN_COUNT = R.styleable.GridLayout_columnCount;
+    private static final int USE_DEFAULT_MARGINS = R.styleable.GridLayout_useDefaultMargins;
+    private static final int ALIGNMENT_MODE = R.styleable.GridLayout_alignmentMode;
+    private static final int ROW_ORDER_PRESERVED = R.styleable.GridLayout_rowOrderPreserved;
+    private static final int COLUMN_ORDER_PRESERVED = R.styleable.GridLayout_columnOrderPreserved;
 
     // Instance variables
 
@@ -201,6 +199,7 @@
     private boolean mUseDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS;
     private int mAlignmentMode = DEFAULT_ALIGNMENT_MODE;
     private int mDefaultGravity = Gravity.NO_GRAVITY;
+    private int mDefaultGap;
 
     // Constructors
 
@@ -212,7 +211,8 @@
         if (DEBUG) {
             setWillNotDraw(false);
         }
-        TypedArray a = context.obtainStyledAttributes(attrs, styleable.GridLayout);
+        mDefaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap);
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridLayout);
         try {
             setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT));
             setColumnCount(a.getInt(COLUMN_COUNT, DEFAULT_COUNT));
@@ -382,7 +382,7 @@
     public void setUseDefaultMargins(boolean useDefaultMargins) {
         mUseDefaultMargins = useDefaultMargins;
         if (useDefaultMargins) {
-            int padding = DEFAULT_CONTAINER_PADDING;
+            int padding = mDefaultGap;
             setPadding(padding, padding, padding, padding);
         }
         requestLayout();
@@ -538,7 +538,7 @@
     }
 
     private int getDefaultMargin(View c, boolean horizontal, boolean leading) {
-        return DEFAULT_MARGIN;
+        return mDefaultGap / 2;
     }
 
     private int getDefaultMargin(View c, boolean isAtEdge, boolean horizontal, boolean leading) {
@@ -787,6 +787,12 @@
         invalidateStructure();
     }
 
+    @Override
+    public void removeAllViews() {
+        super.removeAllViews();
+        invalidateStructure();
+    }
+
     // Measurement
 
     private boolean isGone(View c) {
@@ -1596,8 +1602,8 @@
      * each cell group. The fundamental parameters associated with each cell group are
      * gathered into their vertical and horizontal components and stored
      * in the {@link #rowSpec} and {@link #columnSpec} layout parameters.
-     * {@link android.widget.GridLayout.Spec Specs} are immutable structures and may be shared between the layout
-     * parameters of different children.
+     * {@link android.widget.GridLayout.Spec Specs} are immutable structures
+     * and may be shared between the layout parameters of different children.
      * <p>
      * The row and column specs contain the leading and trailing indices along each axis
      * and together specify the four grid indices that delimit the cells of this cell group.
@@ -1667,24 +1673,25 @@
 
         // TypedArray indices
 
-        private static final int MARGIN = styleable.ViewGroup_MarginLayout_layout_margin;
-        private static final int LEFT_MARGIN = styleable.ViewGroup_MarginLayout_layout_marginLeft;
-        private static final int TOP_MARGIN = styleable.ViewGroup_MarginLayout_layout_marginTop;
-        private static final int RIGHT_MARGIN = styleable.ViewGroup_MarginLayout_layout_marginRight;
+        private static final int MARGIN = R.styleable.ViewGroup_MarginLayout_layout_margin;
+        private static final int LEFT_MARGIN = R.styleable.ViewGroup_MarginLayout_layout_marginLeft;
+        private static final int TOP_MARGIN = R.styleable.ViewGroup_MarginLayout_layout_marginTop;
+        private static final int RIGHT_MARGIN =
+                R.styleable.ViewGroup_MarginLayout_layout_marginRight;
         private static final int BOTTOM_MARGIN =
-                styleable.ViewGroup_MarginLayout_layout_marginBottom;
+                R.styleable.ViewGroup_MarginLayout_layout_marginBottom;
 
-        private static final int COLUMN = styleable.GridLayout_Layout_layout_column;
-        private static final int COLUMN_SPAN = styleable.GridLayout_Layout_layout_columnSpan;
+        private static final int COLUMN = R.styleable.GridLayout_Layout_layout_column;
+        private static final int COLUMN_SPAN = R.styleable.GridLayout_Layout_layout_columnSpan;
         private static final int COLUMN_FLEXIBILITY =
-                styleable.GridLayout_Layout_layout_columnFlexibility;
+                R.styleable.GridLayout_Layout_layout_columnFlexibility;
 
-        private static final int ROW = styleable.GridLayout_Layout_layout_row;
-        private static final int ROW_SPAN = styleable.GridLayout_Layout_layout_rowSpan;
+        private static final int ROW = R.styleable.GridLayout_Layout_layout_row;
+        private static final int ROW_SPAN = R.styleable.GridLayout_Layout_layout_rowSpan;
         private static final int ROW_FLEXIBILITY =
-                styleable.GridLayout_Layout_layout_rowFlexibility;
+                R.styleable.GridLayout_Layout_layout_rowFlexibility;
 
-        private static final int GRAVITY = styleable.GridLayout_Layout_layout_gravity;
+        private static final int GRAVITY = R.styleable.GridLayout_Layout_layout_gravity;
 
         // Instance variables
 
@@ -1804,7 +1811,8 @@
 
         // This method could be parametrized and moved into MarginLayout.
         private void reInitSuper(Context context, AttributeSet attrs) {
-            TypedArray a = context.obtainStyledAttributes(attrs, styleable.ViewGroup_MarginLayout);
+            TypedArray a =
+                    context.obtainStyledAttributes(attrs, R.styleable.ViewGroup_MarginLayout);
             try {
                 int margin = a.getDimensionPixelSize(MARGIN, DEFAULT_MARGIN);
 
@@ -1840,7 +1848,7 @@
         }
 
         private void init(Context context, AttributeSet attrs, int defaultGravity) {
-            TypedArray a = context.obtainStyledAttributes(attrs, styleable.GridLayout_Layout);
+            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridLayout_Layout);
             try {
                 int gravity = a.getInt(GRAVITY, defaultGravity);
 
@@ -2301,10 +2309,10 @@
      */
     @Deprecated
     public static class Group extends Spec {
-    /**
-     * @deprecated  Please replace with {@link #spec(int, int, Alignment)}
-     * @hide
-     */
+        /**
+         * @deprecated Please replace with {@link #spec(int, int, Alignment)}
+         * @hide
+         */
         @Deprecated
         public Group(int start, int size, Alignment alignment) {
             super(start, size, alignment, UNDEFINED_FLEXIBILITY);
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index f3bda43..b2d1a1e 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -18,8 +18,6 @@
 
 import static android.widget.SuggestionsAdapter.getColumnString;
 
-import com.android.internal.R;
-
 import android.app.PendingIntent;
 import android.app.SearchManager;
 import android.app.SearchableInfo;
@@ -39,10 +37,14 @@
 import android.os.Bundle;
 import android.speech.RecognizerIntent;
 import android.text.Editable;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
 import android.text.TextWatcher;
+import android.text.style.ImageSpan;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.TypedValue;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -51,6 +53,8 @@
 import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.TextView.OnEditorActionListener;
 
+import com.android.internal.R;
+
 import java.util.WeakHashMap;
 
 /**
@@ -87,6 +91,8 @@
     private View mSearchEditFrame;
     private View mVoiceButton;
     private SearchAutoComplete mQueryTextView;
+    private View mDropDownAnchor;
+    private ImageView mSearchHintIcon;
     private boolean mSubmitButtonEnabled;
     private CharSequence mQueryHint;
     private boolean mQueryRefinement;
@@ -195,6 +201,7 @@
         mSubmitButton = findViewById(R.id.search_go_btn);
         mCloseButton = (ImageView) findViewById(R.id.search_close_btn);
         mVoiceButton = findViewById(R.id.search_voice_btn);
+        mSearchHintIcon = (ImageView) findViewById(R.id.search_mag_icon);
 
         mSearchButton.setOnClickListener(mOnClickListener);
         mCloseButton.setOnClickListener(mOnClickListener);
@@ -244,7 +251,20 @@
         mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
         mVoiceAppSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
+        mDropDownAnchor = findViewById(mQueryTextView.getDropDownAnchor());
+        if (mDropDownAnchor != null) {
+            mDropDownAnchor.addOnLayoutChangeListener(new OnLayoutChangeListener() {
+                @Override
+                public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                        int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                    adjustDropDownSizeAndPosition();
+                }
+
+            });
+        }
+
         updateViewsVisibility(mIconifiedByDefault);
+        updateQueryHint();
     }
 
     /**
@@ -263,7 +283,7 @@
         }
         // Cache the voice search capability
         mVoiceButtonEnabled = hasVoiceSearch();
-        updateViewsVisibility(mIconifiedByDefault);
+        updateViewsVisibility(isIconified());
     }
 
     /**
@@ -300,7 +320,6 @@
         mQueryTextView.clearFocus();
         setImeVisibility(false);
         mClearingFocus = false;
-        updateViewsVisibility(mIconifiedByDefault);
     }
 
     /**
@@ -555,6 +574,7 @@
         mSearchButton.setVisibility(visCollapsed);
         updateSubmitButton(hasText);
         mSearchEditFrame.setVisibility(collapsed ? GONE : VISIBLE);
+        mSearchHintIcon.setVisibility(mIconifiedByDefault ? GONE : VISIBLE);
         updateCloseButton();
         updateVoiceButton(!hasText);
         updateSubmitArea();
@@ -822,9 +842,29 @@
         return result;
     }
 
+    private int getSearchIconId() {
+        TypedValue outValue = new TypedValue();
+        getContext().getTheme().resolveAttribute(com.android.internal.R.attr.searchViewSearchIcon,
+                outValue, true);
+        return outValue.resourceId;
+    }
+
+    private CharSequence getDecoratedHint(CharSequence hintText) {
+        // If the field is always expanded, then don't add the search icon to the hint
+        if (!mIconifiedByDefault) return hintText;
+
+        SpannableStringBuilder ssb = new SpannableStringBuilder("   "); // for the icon
+        ssb.append(hintText);
+        Drawable searchIcon = getContext().getResources().getDrawable(getSearchIconId());
+        int textSize = (int) (mQueryTextView.getTextSize() * 1.25);
+        searchIcon.setBounds(0, 0, textSize, textSize);
+        ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+        return ssb;
+    }
+
     private void updateQueryHint() {
         if (mQueryHint != null) {
-            mQueryTextView.setHint(mQueryHint);
+            mQueryTextView.setHint(getDecoratedHint(mQueryHint));
         } else if (mSearchable != null) {
             CharSequence hint = null;
             int hintId = mSearchable.getHintId();
@@ -832,8 +872,10 @@
                 hint = getContext().getString(hintId);
             }
             if (hint != null) {
-                mQueryTextView.setHint(hint);
+                mQueryTextView.setHint(getDecoratedHint(hint));
             }
+        } else {
+            mQueryTextView.setHint(getDecoratedHint(""));
         }
     }
 
@@ -922,9 +964,13 @@
         CharSequence text = mQueryTextView.getText();
         if (TextUtils.isEmpty(text)) {
             if (mIconifiedByDefault) {
-                // query field already empty, hide the keyboard and remove focus
-                clearFocus();
-                setImeVisibility(false);
+                // If the app doesn't override the close behavior
+                if (mOnCloseListener == null || !mOnCloseListener.onClose()) {
+                    // hide the keyboard and remove focus
+                    clearFocus();
+                    // collapse the search field
+                    updateViewsVisibility(true);
+                }
             }
         } else {
             mQueryTextView.setText("");
@@ -932,10 +978,6 @@
             setImeVisibility(true);
         }
 
-        if (mIconifiedByDefault && (mOnCloseListener == null || !mOnCloseListener.onClose())) {
-            updateViewsVisibility(mIconifiedByDefault);
-            setImeVisibility(false);
-        }
     }
 
     private void onSearchClicked() {
@@ -975,6 +1017,28 @@
         updateFocusedState(mQueryTextView.hasFocus());
     }
 
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+    }
+
+    private void adjustDropDownSizeAndPosition() {
+        if (mDropDownAnchor.getWidth() > 1) {
+            Resources res = getContext().getResources();
+            int anchorPadding = mSearchPlate.getPaddingLeft();
+            Rect dropDownPadding = new Rect();
+            int iconOffset = mIconifiedByDefault
+                    ? res.getDimensionPixelSize(R.dimen.dropdownitem_icon_width)
+                    + res.getDimensionPixelSize(R.dimen.dropdownitem_text_padding_left)
+                    : 0;
+            mQueryTextView.getDropDownBackground().getPadding(dropDownPadding);
+            mQueryTextView.setDropDownHorizontalOffset(-(dropDownPadding.left + iconOffset)
+                    + anchorPadding);
+            mQueryTextView.setDropDownWidth(mDropDownAnchor.getWidth() + dropDownPadding.left
+                    + dropDownPadding.right + iconOffset - (anchorPadding));
+        }
+    }
+
     private boolean onItemClicked(int position, int actionKey, String actionMsg) {
         if (mOnSuggestionListener == null
                 || !mOnSuggestionListener.onSuggestionClick(position)) {
@@ -1393,5 +1457,32 @@
         public boolean enoughToFilter() {
             return mThreshold <= 0 || super.enoughToFilter();
         }
+
+        @Override
+        public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+            if (keyCode == KeyEvent.KEYCODE_BACK) {
+                // special case for the back key, we do not even try to send it
+                // to the drop down list but instead, consume it immediately
+                if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
+                    KeyEvent.DispatcherState state = getKeyDispatcherState();
+                    if (state != null) {
+                        state.startTracking(event, this);
+                    }
+                    return true;
+                } else if (event.getAction() == KeyEvent.ACTION_UP) {
+                    KeyEvent.DispatcherState state = getKeyDispatcherState();
+                    if (state != null) {
+                        state.handleUpEvent(event);
+                    }
+                    if (event.isTracking() && !event.isCanceled()) {
+                        mSearchView.clearFocus();
+                        mSearchView.setImeVisibility(false);
+                        return true;
+                    }
+                }
+            }
+            return super.onKeyPreIme(keyCode, event);
+        }
+
     }
 }
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index 2cfc016..9e32c9a 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -16,8 +16,6 @@
 
 package android.widget;
 
-import com.android.internal.R;
-
 import android.app.SearchDialog;
 import android.app.SearchManager;
 import android.app.SearchableInfo;
@@ -47,6 +45,8 @@
 import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 
+import com.android.internal.R;
+
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -88,8 +88,8 @@
     private int mIconName2Col = INVALID_INDEX;
     private int mFlagsCol = INVALID_INDEX;
 
-    private final Runnable mStartSpinnerRunnable;
-    private final Runnable mStopSpinnerRunnable;
+    // private final Runnable mStartSpinnerRunnable;
+    // private final Runnable mStopSpinnerRunnable;
 
     /**
      * The amount of time we delay in the filter when the user presses the delete key.
@@ -113,17 +113,18 @@
 
         mOutsideDrawablesCache = outsideDrawablesCache;
         
-        mStartSpinnerRunnable = new Runnable() {
-                public void run() {
-                // mSearchView.setWorking(true); // TODO:
-                }
-            };
 
-        mStopSpinnerRunnable = new Runnable() {
-            public void run() {
-                // mSearchView.setWorking(false); // TODO:
-            }
-        };
+        // mStartSpinnerRunnable = new Runnable() {
+        // public void run() {
+        // // mSearchView.setWorking(true); // TODO:
+        // }
+        // };
+        //
+        // mStopSpinnerRunnable = new Runnable() {
+        // public void run() {
+        // // mSearchView.setWorking(false); // TODO:
+        // }
+        // };
 
         // delay 500ms when deleting
         getFilter().setDelayer(new Filter.Delayer() {
@@ -341,10 +342,10 @@
         }
 
         if (views.mIcon1 != null) {
-            setViewDrawable(views.mIcon1, getIcon1(cursor));
+            setViewDrawable(views.mIcon1, getIcon1(cursor), View.INVISIBLE);
         }
         if (views.mIcon2 != null) {
-            setViewDrawable(views.mIcon2, getIcon2(cursor));
+            setViewDrawable(views.mIcon2, getIcon2(cursor), View.GONE);
         }
         if (mQueryRefinement == REFINE_ALL
                 || (mQueryRefinement == REFINE_BY_ENTRY
@@ -414,13 +415,13 @@
      * Sets the drawable in an image view, makes sure the view is only visible if there
      * is a drawable.
      */
-    private void setViewDrawable(ImageView v, Drawable drawable) {
+    private void setViewDrawable(ImageView v, Drawable drawable, int nullVisibility) {
         // Set the icon even if the drawable is null, since we need to clear any
         // previous icon.
         v.setImageDrawable(drawable);
 
         if (drawable == null) {
-            v.setVisibility(View.GONE);
+            v.setVisibility(nullVisibility);
         } else {
             v.setVisibility(View.VISIBLE);
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 769f5e3..66a07d3 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -117,7 +117,7 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewAncestor;
+import android.view.ViewRootImpl;
 import android.view.ViewConfiguration;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
@@ -3731,13 +3731,13 @@
         Handler h = getHandler();
         if (h != null) {
             long eventTime = SystemClock.uptimeMillis();
-            h.sendMessage(h.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME,
+            h.sendMessage(h.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
                     new KeyEvent(eventTime, eventTime,
                     KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, 0, 0,
                     KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
                     KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
                     | KeyEvent.FLAG_EDITOR_ACTION)));
-            h.sendMessage(h.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME,
+            h.sendMessage(h.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
                     new KeyEvent(SystemClock.uptimeMillis(), eventTime,
                     KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER, 0, 0,
                     KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index 9e37c7b..f3d891d 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -33,7 +33,7 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.view.ViewAncestor;
+import android.view.ViewRootImpl;
 import android.view.WindowManager;
 import android.view.View.OnClickListener;
 import android.view.WindowManager.LayoutParams;
@@ -501,7 +501,7 @@
 
         } else {
 
-            ViewAncestor viewRoot = getOwnerViewAncestor();
+            ViewRootImpl viewRoot = getOwnerViewRootImpl();
             if (viewRoot != null) {
                 viewRoot.dispatchKey(event);
             }
@@ -526,15 +526,15 @@
         }
     }
 
-    private ViewAncestor getOwnerViewAncestor() {
+    private ViewRootImpl getOwnerViewRootImpl() {
         View rootViewOfOwner = mOwnerView.getRootView();
         if (rootViewOfOwner == null) {
             return null;
         }
 
         ViewParent parentOfRootView = rootViewOfOwner.getParent();
-        if (parentOfRootView instanceof ViewAncestor) {
-            return (ViewAncestor) parentOfRootView;
+        if (parentOfRootView instanceof ViewRootImpl) {
+            return (ViewRootImpl) parentOfRootView;
         } else {
             return null;
         }
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 812f92b..ce0299c 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -68,5 +68,5 @@
     boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype);
     boolean switchToLastInputMethod(in IBinder token);
     boolean setInputMethodEnabled(String id, boolean enabled);
-    boolean setAdditionalInputMethodSubtypes(in IBinder token, in InputMethodSubtype[] subtypes);
+    boolean setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
 }
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index 3070e3e..fb33748 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -29,7 +29,7 @@
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.View;
-import android.view.ViewAncestor;
+import android.view.ViewRootImpl;
 import com.android.internal.R;
 
 public class PasswordEntryKeyboardHelper implements OnKeyboardActionListener {
@@ -150,7 +150,7 @@
                 KeyEvent event = events[i];
                 event = KeyEvent.changeFlags(event, event.getFlags()
                         | KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);
-                handler.sendMessage(handler.obtainMessage(ViewAncestor.DISPATCH_KEY, event));
+                handler.sendMessage(handler.obtainMessage(ViewRootImpl.DISPATCH_KEY, event));
             }
         }
     }
@@ -158,11 +158,11 @@
     public void sendDownUpKeyEvents(int keyEventCode) {
         long eventTime = SystemClock.uptimeMillis();
         Handler handler = mTargetView.getHandler();
-        handler.sendMessage(handler.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME,
+        handler.sendMessage(handler.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
                 new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, keyEventCode, 0, 0,
                         KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
                     KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)));
-        handler.sendMessage(handler.obtainMessage(ViewAncestor.DISPATCH_KEY_FROM_IME,
+        handler.sendMessage(handler.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
                 new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_UP, keyEventCode, 0, 0,
                         KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
                         KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)));
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 06dc083..514e59d 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -139,6 +139,7 @@
 	android_bluetooth_common.cpp \
 	android_bluetooth_BluetoothAudioGateway.cpp \
 	android_bluetooth_BluetoothSocket.cpp \
+	android_bluetooth_c.c \
 	android_server_BluetoothService.cpp \
 	android_server_BluetoothEventLoop.cpp \
 	android_server_BluetoothA2dpService.cpp \
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 6a13876..30fe298 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -323,9 +323,7 @@
 
 void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font,
         FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
-        size_t contextCount, int dirFlags) {
-    bool isRTL = dirFlags & 0x1;
-
+        size_t contextCount, bool isRTL) {
     font->klass = &harfbuzzSkiaClass;
     font->userData = 0;
     // The values which harfbuzzSkiaClass returns are already scaled to
@@ -374,10 +372,10 @@
 
 void TextLayoutCacheValue::shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font,
         FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count,
-        size_t contextCount, int dirFlags) {
+        size_t contextCount, bool isRTL) {
     // Setup Harfbuzz Shaper
     setupShaperItem(shaperItem, font, fontData, paint, chars, start, count,
-            contextCount, dirFlags);
+            contextCount, isRTL);
 
     // Shape
     resetGlyphArrays(shaperItem);
@@ -430,7 +428,7 @@
                     LOGD("computeValuesWithHarfbuzz -- forcing run with LTR=%d RTL=%d",
                             forceLTR, forceRTL);
 #endif
-            computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
+            computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, forceRTL,
                     outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
 
             if (forceRTL && *outGlyphsCount > 1) {
@@ -451,10 +449,15 @@
                     LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d", dirFlags, rc, paraDir);
 #endif
                     if (rc == 1 || !U_SUCCESS(status)) {
+                        bool isRTL = (paraDir == 1);
+#if DEBUG_GLYPHS
+                        LOGD("computeValuesWithHarfbuzz -- processing SINGLE run "
+                                "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
+#endif
                         computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount,
-                                dirFlags, outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
+                                isRTL, outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
 
-                        if (dirFlags == 1 && *outGlyphsCount > 1) {
+                        if (isRTL && *outGlyphsCount > 1) {
                             reverseGlyphArray(*outGlyphs, *outGlyphsCount);
                         }
                     } else {
@@ -485,14 +488,14 @@
 
                             lengthRun = endRun - startRun;
 
-                            int newFlags = (runDir == UBIDI_RTL) ? kDirection_RTL : kDirection_LTR;
+                            bool isRTL = (runDir == UBIDI_RTL);
                             jfloat runTotalAdvance = 0;
 #if DEBUG_GLYPHS
-                            LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d newFlags=%d",
-                                    startRun, lengthRun, newFlags);
+                            LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d",
+                                    startRun, lengthRun, isRTL);
 #endif
                             computeRunValuesWithHarfbuzz(paint, chars, startRun,
-                                    lengthRun, contextCount, newFlags,
+                                    lengthRun, contextCount, isRTL,
                                     outAdvances, &runTotalAdvance,
                                     &runGlyphs, &runGlyphsCount);
 
@@ -506,7 +509,7 @@
                                 LOGD("                          -- glyphs[%d]=%d", j, runGlyphs[j]);
                             }
 #endif
-                            glyphRuns.push(GlyphRun(runGlyphs, runGlyphsCount, newFlags));
+                            glyphRuns.push(GlyphRun(runGlyphs, runGlyphsCount, isRTL));
                         }
                         *outGlyphs = new jchar[*outGlyphsCount];
 
@@ -528,13 +531,15 @@
                 ubidi_close(bidi);
             } else {
                 // Cannot run BiDi, just consider one Run
+                bool isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
 #if DEBUG_GLYPHS
-                LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering only one Run");
+                LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering a SINGLE Run "
+                        "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
 #endif
-                computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags,
+                computeRunValuesWithHarfbuzz(paint, chars, start, count, contextCount, isRTL,
                         outAdvances, outTotalAdvance, outGlyphs, outGlyphsCount);
 
-                if (dirFlags == 1 && *outGlyphsCount > 1) {
+                if (isRTL && *outGlyphsCount > 1) {
                     reverseGlyphArray(*outGlyphs, *outGlyphsCount);
                 }
             }
@@ -545,17 +550,15 @@
 }
 
 void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars,
-        size_t start, size_t count, size_t contextCount, int dirFlags,
+        size_t start, size_t count, size_t contextCount, bool isRTL,
         jfloat* outAdvances, jfloat* outTotalAdvance,
         jchar** outGlyphs, size_t* outGlyphsCount) {
 
-    bool isRTL = dirFlags & 0x1;
-
     HB_ShaperItem shaperItem;
     HB_FontRec font;
     FontData fontData;
     shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count,
-            contextCount, dirFlags);
+            contextCount, isRTL);
 
 #if DEBUG_GLYPHS
     LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs,
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index 690caac..10dee87 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -128,11 +128,11 @@
 
     static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
             SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
-            int dirFlags);
+            bool isRTL);
 
     static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData,
             SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount,
-            int dirFlags);
+            bool isRTL);
 
     static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
             size_t count, size_t contextCount, int dirFlags,
@@ -179,7 +179,7 @@
     static void resetGlyphArrays(HB_ShaperItem* shaperItem);
 
     static void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start,
-            size_t count, size_t contextCount, int dirFlags,
+            size_t count, size_t contextCount, bool isRTL,
             jfloat* outAdvances, jfloat* outTotalAdvance,
             jchar** outGlyphs, size_t* outGlyphsCount);
 }; // TextLayoutCacheValue
diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
index cb742a3..29c9c2d 100755
--- a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
+++ b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "BluetoothAudioGateway.cpp"
 
 #include "android_bluetooth_common.h"
+#include "android_bluetooth_c.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "JNIHelp.h"
 #include "jni.h"
@@ -491,7 +492,8 @@
     }
 
     laddr.rc_family = AF_BLUETOOTH;
-    memcpy(&laddr.rc_bdaddr, BDADDR_ANY, sizeof(bdaddr_t));
+    bdaddr_t any = android_bluetooth_bdaddr_any();
+    memcpy(&laddr.rc_bdaddr, &any, sizeof(bdaddr_t));
     laddr.rc_channel = channel;
 
     if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp
index d09c4e9..4c84324 100644
--- a/core/jni/android_bluetooth_BluetoothSocket.cpp
+++ b/core/jni/android_bluetooth_BluetoothSocket.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "BluetoothSocket.cpp"
 
 #include "android_bluetooth_common.h"
+#include "android_bluetooth_c.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "JNIHelp.h"
 #include "utils/Log.h"
@@ -245,7 +246,7 @@
     jint type;
     socklen_t addr_sz;
     struct sockaddr *addr;
-    bdaddr_t bdaddr = *BDADDR_ANY;
+    bdaddr_t bdaddr = android_bluetooth_bdaddr_any();
     struct asocket *s = get_socketData(env, obj);
 
     if (!s)
diff --git a/core/jni/android_bluetooth_c.c b/core/jni/android_bluetooth_c.c
new file mode 100755
index 0000000..b4c6727
--- /dev/null
+++ b/core/jni/android_bluetooth_c.c
@@ -0,0 +1,31 @@
+/*
+** Copyright 2011, 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.
+*/
+
+#ifdef HAVE_BLUETOOTH
+
+#include "android_bluetooth_c.h"
+
+/*
+ * A C helper for creating a bdaddr_t object with the value BDADDR_ANY.
+ * We have to do this in C because the macro BDADDR_ANY in bluetooth.h
+ * is not valid C++ code.
+ */
+bdaddr_t android_bluetooth_bdaddr_any(void)
+{
+  bdaddr_t any = *BDADDR_ANY;
+  return any;
+}
+#endif
diff --git a/core/jni/android_bluetooth_c.h b/core/jni/android_bluetooth_c.h
new file mode 100644
index 0000000..e890244
--- /dev/null
+++ b/core/jni/android_bluetooth_c.h
@@ -0,0 +1,39 @@
+/*
+** Copyright 2010, 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_BLUETOOTH_C_H
+#define ANDROID_BLUETOOTH_C_H
+#ifdef HAVE_BLUETOOTH
+
+#include <bluetooth/bluetooth.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * A C helper for creating a bdaddr_t object with the value BDADDR_ANY.
+ * We have to do this in C because the macro BDADDR_ANY in bluetooth.h
+ * is not valid C++ code.
+ */
+bdaddr_t android_bluetooth_bdaddr_any(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*HAVE_BLUETOOTH*/
+#endif /*ANDROID_BLUETOOTH_C_H*/
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 681f43f..b0c2f2c 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -127,6 +127,13 @@
     }
 }
 
+static void android_view_GLES20Canvas_flushCaches(JNIEnv* env, jobject clazz,
+        Caches::FlushMode mode) {
+    if (Caches::hasInstance()) {
+        Caches::getInstance().flush(mode);
+    }
+}
+
 // ----------------------------------------------------------------------------
 // Constructors
 // ----------------------------------------------------------------------------
@@ -735,6 +742,7 @@
     { "nIsBackBufferPreserved", "()Z",         (void*) android_view_GLES20Canvas_isBackBufferPreserved },
     { "nPreserveBackBuffer",    "()Z",         (void*) android_view_GLES20Canvas_preserveBackBuffer },
     { "nDisableVsync",          "()V",         (void*) android_view_GLES20Canvas_disableVsync },
+    { "nFlushCaches",           "(I)V",        (void*) android_view_GLES20Canvas_flushCaches },
 
     { "nCreateRenderer",    "()I",             (void*) android_view_GLES20Canvas_createRenderer },
     { "nDestroyRenderer",   "(I)V",            (void*) android_view_GLES20Canvas_destroyRenderer },
@@ -859,10 +867,8 @@
 
 const char* const kActivityThreadPathName = "android/app/ActivityThread";
 
-int register_android_app_ActivityThread(JNIEnv* env)
-{
-    return AndroidRuntime::registerNativeMethods(
-            env, kActivityThreadPathName,
+int register_android_app_ActivityThread(JNIEnv* env) {
+    return AndroidRuntime::registerNativeMethods(env, kActivityThreadPathName,
             gActivityThreadMethods, NELEM(gActivityThreadMethods));
 }
 
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index b046b23..9484c6b 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -19,11 +19,48 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <android_runtime/android_graphics_SurfaceTexture.h>
 
+#include <ui/Region.h>
+#include <ui/Rect.h>
+
 #include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
+
+#include <SkBitmap.h>
+#include <SkCanvas.h>
 
 namespace android {
 
 // ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+static struct {
+    jmethodID set;
+    jfieldID left;
+    jfieldID top;
+    jfieldID right;
+    jfieldID bottom;
+} gRectClassInfo;
+
+static struct {
+    jfieldID nativeCanvas;
+    jfieldID surfaceFormat;
+} gCanvasClassInfo;
+
+static struct {
+    jfieldID nativeWindow;
+} gTextureViewClassInfo;
+
+#define GET_INT(object, field) \
+    env->GetIntField(object, field)
+
+#define SET_INT(object, field, value) \
+    env->SetIntField(object, field, value)
+
+#define INVOKEV(object, method, ...) \
+    env->CallVoidMethod(object, method, __VA_ARGS__)
+
+// ----------------------------------------------------------------------------
 // Native layer
 // ----------------------------------------------------------------------------
 
@@ -34,6 +71,118 @@
     surfaceTexture->setDefaultBufferSize(width, height);
 }
 
+static inline SkBitmap::Config convertPixelFormat(int32_t format) {
+    switch (format) {
+        case WINDOW_FORMAT_RGBA_8888:
+            return SkBitmap::kARGB_8888_Config;
+        case WINDOW_FORMAT_RGBX_8888:
+            return SkBitmap::kARGB_8888_Config;
+        case WINDOW_FORMAT_RGB_565:
+            return SkBitmap::kRGB_565_Config;
+        default:
+            return SkBitmap::kNo_Config;
+    }
+}
+
+/**
+ * This is a private API, and this implementation is also provided in the NDK.
+ * However, the NDK links against android_runtime, which means that using the
+ * NDK implementation would create a circular dependency between the libraries.
+ */
+static int32_t native_window_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
+        Rect* inOutDirtyBounds) {
+    return window->perform(window, NATIVE_WINDOW_LOCK, outBuffer, inOutDirtyBounds);
+}
+
+static int32_t native_window_unlockAndPost(ANativeWindow* window) {
+    return window->perform(window, NATIVE_WINDOW_UNLOCK_AND_POST);
+}
+
+static void android_view_TextureView_createNativeWindow(JNIEnv* env, jobject textureView,
+        jobject surface) {
+
+    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
+    sp<ANativeWindow> window = new SurfaceTextureClient(surfaceTexture);
+
+    window->incStrong(0);
+    SET_INT(textureView, gTextureViewClassInfo.nativeWindow, jint(window.get()));
+}
+
+static void android_view_TextureView_destroyNativeWindow(JNIEnv* env, jobject textureView) {
+
+    ANativeWindow* nativeWindow = (ANativeWindow*)
+            GET_INT(textureView, gTextureViewClassInfo.nativeWindow);
+
+    if (nativeWindow) {
+        sp<ANativeWindow> window(nativeWindow);
+            window->decStrong(0);
+        SET_INT(textureView, gTextureViewClassInfo.nativeWindow, 0);
+    }
+}
+
+static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
+        jint nativeWindow, jobject canvas, jobject dirtyRect) {
+
+    if (!nativeWindow) {
+        return;
+    }
+
+    ANativeWindow_Buffer buffer;
+
+    Rect rect;
+    if (dirtyRect) {
+        rect.left = GET_INT(dirtyRect, gRectClassInfo.left);
+        rect.top = GET_INT(dirtyRect, gRectClassInfo.top);
+        rect.right = GET_INT(dirtyRect, gRectClassInfo.right);
+        rect.bottom = GET_INT(dirtyRect, gRectClassInfo.bottom);
+    } else {
+        rect.set(Rect(0x3FFF, 0x3FFF));
+    }
+
+    sp<ANativeWindow> window((ANativeWindow*) nativeWindow);
+    native_window_lock(window.get(), &buffer, &rect);
+
+    ssize_t bytesCount = buffer.stride * bytesPerPixel(buffer.format);
+
+    SkBitmap bitmap;
+    bitmap.setConfig(convertPixelFormat(buffer.format), buffer.width, buffer.height, bytesCount);
+
+    if (buffer.format == WINDOW_FORMAT_RGBX_8888) {
+        bitmap.setIsOpaque(true);
+    }
+
+    if (buffer.width > 0 && buffer.height > 0) {
+        bitmap.setPixels(buffer.bits);
+    } else {
+        bitmap.setPixels(NULL);
+    }
+
+    SET_INT(canvas, gCanvasClassInfo.surfaceFormat, buffer.format);
+    SkCanvas* nativeCanvas = (SkCanvas*) GET_INT(canvas, gCanvasClassInfo.nativeCanvas);
+    nativeCanvas->setBitmapDevice(bitmap);
+
+    SkRect clipRect;
+    clipRect.set(rect.left, rect.top, rect.right, rect.bottom);
+    nativeCanvas->clipRect(clipRect);
+
+    if (dirtyRect) {
+        INVOKEV(dirtyRect, gRectClassInfo.set,
+                int(rect.left), int(rect.top), int(rect.right), int(rect.bottom));
+    }
+}
+
+static void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject,
+        jint nativeWindow, jobject canvas) {
+
+    SkCanvas* nativeCanvas = (SkCanvas*) GET_INT(canvas, gCanvasClassInfo.nativeCanvas);
+    nativeCanvas->setBitmapDevice(SkBitmap());
+
+    if (nativeWindow) {
+        sp<ANativeWindow> window((ANativeWindow*) nativeWindow);
+        native_window_unlockAndPost(window.get());
+    }
+}
+
 // ----------------------------------------------------------------------------
 // JNI Glue
 // ----------------------------------------------------------------------------
@@ -42,10 +191,47 @@
 
 static JNINativeMethod gMethods[] = {
     {   "nSetDefaultBufferSize", "(Landroid/graphics/SurfaceTexture;II)V",
-            (void*) android_view_TextureView_setDefaultBufferSize }
+            (void*) android_view_TextureView_setDefaultBufferSize },
+
+    {   "nCreateNativeWindow", "(Landroid/graphics/SurfaceTexture;)V",
+            (void*) android_view_TextureView_createNativeWindow },
+    {   "nDestroyNativeWindow", "()V",
+            (void*) android_view_TextureView_destroyNativeWindow },
+
+    {   "nLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V",
+            (void*) android_view_TextureView_lockCanvas },
+    {   "nUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V",
+            (void*) android_view_TextureView_unlockCanvasAndPost },
 };
 
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(!var, "Unable to find class " className);
+
+#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+        var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+        LOG_FATAL_IF(!var, "Unable to find method " methodName);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(!var, "Unable to find field" fieldName);
+
 int register_android_view_TextureView(JNIEnv* env) {
+    jclass clazz;
+    FIND_CLASS(clazz, "android/graphics/Rect");
+    GET_METHOD_ID(gRectClassInfo.set, clazz, "set", "(IIII)V");
+    GET_FIELD_ID(gRectClassInfo.left, clazz, "left", "I");
+    GET_FIELD_ID(gRectClassInfo.top, clazz, "top", "I");
+    GET_FIELD_ID(gRectClassInfo.right, clazz, "right", "I");
+    GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I");
+
+    FIND_CLASS(clazz, "android/graphics/Canvas");
+    GET_FIELD_ID(gCanvasClassInfo.nativeCanvas, clazz, "mNativeCanvas", "I");
+    GET_FIELD_ID(gCanvasClassInfo.surfaceFormat, clazz, "mSurfaceFormat", "I");
+
+    FIND_CLASS(clazz, "android/view/TextureView");
+    GET_FIELD_ID(gTextureViewClassInfo.nativeWindow, clazz, "mNativeWindow", "I");
+
     return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml
index 790ac6b..f6b5b53 100644
--- a/core/res/res/layout/search_bar.xml
+++ b/core/res/res/layout/search_bar.xml
@@ -66,7 +66,6 @@
             android:layout_height="wrap_content"
             android:layout_weight="1"
             android:maxWidth="600dip"
-            android:iconifiedByDefault="false"
             android:layout_gravity="center_vertical"
             />
 
diff --git a/core/res/res/layout/search_dropdown_item_icons_2line.xml b/core/res/res/layout/search_dropdown_item_icons_2line.xml
index 53906f9..acef2cc 100644
--- a/core/res/res/layout/search_dropdown_item_icons_2line.xml
+++ b/core/res/res/layout/search_dropdown_item_icons_2line.xml
@@ -19,21 +19,21 @@
 -->
 
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:paddingLeft="4dip"
-    android:paddingRight="2dip"
+    android:paddingLeft="@dimen/dropdownitem_text_padding_left"
+    android:paddingRight="4dip"
     android:layout_width="match_parent"
     android:layout_height="?android:attr/searchResultListItemHeight" >
 
     <!-- Icons come first in the layout, since their placement doesn't depend on
          the placement of the text views. -->
     <ImageView android:id="@android:id/icon1"
-        android:layout_width="48dip"
+        android:layout_width="@dimen/dropdownitem_icon_width"
         android:layout_height="48dip"
         android:scaleType="centerInside"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
         android:layout_alignParentBottom="true"
-        android:visibility="gone" />
+        android:visibility="invisible" />
 
     <ImageView android:id="@+id/edit_query"
         android:layout_width="48dip"
diff --git a/core/res/res/layout/search_view.xml b/core/res/res/layout/search_view.xml
index fee27eb..6b70d8d 100644
--- a/core/res/res/layout/search_view.xml
+++ b/core/res/res/layout/search_view.xml
@@ -22,6 +22,8 @@
     android:id="@+id/search_bar"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:paddingLeft="8dip"
+    android:paddingRight="8dip"
     android:orientation="horizontal"
     >
 
@@ -30,7 +32,7 @@
         android:id="@+id/search_badge"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:layout_gravity="center_vertical"
+        android:gravity="center_vertical"
         android:layout_marginBottom="2dip"
         android:drawablePadding="0dip"
         android:textAppearance="?android:attr/textAppearanceMedium"
@@ -54,12 +56,21 @@
         android:layout_height="wrap_content"
         android:layout_weight="1"
         android:layout_gravity="center_vertical"
-        android:layout_marginLeft="8dip"
-        android:layout_marginRight="8dip"
         android:layout_marginTop="4dip"
         android:layout_marginBottom="4dip"
         android:orientation="horizontal">
 
+        <ImageView
+            android:id="@+id/search_mag_icon"
+            android:layout_width="@dimen/dropdownitem_icon_width"
+            android:layout_height="wrap_content"
+            android:scaleType="centerInside"
+            android:layout_marginLeft="@dimen/dropdownitem_text_padding_left"
+            android:layout_gravity="center_vertical"
+            android:src="?android:attr/searchViewSearchIcon"
+            android:visibility="gone"
+        />
+
         <!-- Inner layout contains the app icon, button(s) and EditText -->
         <LinearLayout
             android:id="@+id/search_plate"
@@ -70,14 +81,6 @@
             android:orientation="horizontal"
             android:background="?android:attr/searchViewTextField">
 
-            <ImageView
-                android:id="@+id/search_app_icon"
-                android:layout_width="wrap_content"
-                android:layout_height="match_parent"
-                android:layout_gravity="center_vertical"
-                android:src="?android:attr/searchViewSearchIcon"
-            />
-
             <view class="android.widget.SearchView$SearchAutoComplete"
                 android:id="@+id/search_src_text"
                 android:layout_height="36dip"
@@ -85,8 +88,8 @@
                 android:layout_weight="1"
                 android:minWidth="@dimen/search_view_text_min_width"
                 android:layout_gravity="bottom"
-                android:paddingLeft="8dip"
-                android:paddingRight="6dip"
+                android:paddingLeft="@dimen/dropdownitem_text_padding_left"
+                android:paddingRight="@dimen/dropdownitem_text_padding_right"
                 android:singleLine="true"
                 android:ellipsize="end"
                 android:background="@null"
@@ -100,7 +103,7 @@
 
             <ImageView
                 android:id="@+id/search_close_btn"
-                android:layout_width="wrap_content"
+                android:layout_width="@dimen/dropdownitem_icon_width"
                 android:layout_height="match_parent"
                 android:paddingLeft="8dip"
                 android:paddingRight="8dip"
@@ -131,7 +134,7 @@
                 android:visibility="gone"
                 android:focusable="true"
             />
-    
+
             <ImageView
                 android:id="@+id/search_voice_btn"
                 android:layout_width="wrap_content"
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index abc56ec..2ba4e66 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -138,4 +138,16 @@
     <!-- Minimum popup width for selecting an activity in ActivityChooserDialog/ActivityChooserView. -->
     <dimen name="activity_chooser_popup_min_width">200dip</dimen>
 
+    <!-- The default gap between components in a layout. -->
+    <dimen name="default_gap">16dip</dimen>
+
+    <!-- Text padding for dropdown items -->
+    <dimen name="dropdownitem_text_padding_left">6dip</dimen>
+
+    <!-- Text padding for dropdown items -->
+    <dimen name="dropdownitem_text_padding_right">6dip</dimen>
+
+    <!-- Width of the icon in a dropdown list -->
+    <dimen name="dropdownitem_icon_width">48dip</dimen>
+
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 6dedc83..f464623 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1787,6 +1787,11 @@
   <public type="attr" name="colorActivatedHighlight" />
   <public type="attr" name="colorMultiSelectHighlight" />
 
+  <public type="attr" name="drawableStart" />
+  <public type="attr" name="drawableEnd" />
+
+  <public type="attr" name="actionModeStyle" />
+
   <public type="style" name="TextAppearance.SuggestionHighlight" />
   <public type="style" name="Theme.Holo.SplitActionBarWhenNarrow" />
   <public type="style" name="Theme.Holo.Light.SplitActionBarWhenNarrow" />
@@ -1826,7 +1831,4 @@
   <public type="color" name="holo_purple" />
   <public type="color" name="holo_blue_bright" />
 
-  <public type="attr" name="drawableStart" />
-  <public type="attr" name="drawableEnd" />
-
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 5b5e7c3..d647467 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -563,8 +563,8 @@
 
     <style name="Widget.DropDownItem">
         <item name="android:textAppearance">@style/TextAppearance.Widget.DropDownItem</item>
-        <item name="android:paddingLeft">6dip</item>
-        <item name="android:paddingRight">6dip</item>
+        <item name="android:paddingLeft">@dimen/dropdownitem_text_padding_left</item>
+        <item name="android:paddingRight">@dimen/dropdownitem_text_padding_right</item>
         <item name="android:gravity">center_vertical</item>
     </style>
     
diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h
index 5ec469e..cfe2aa1 100644
--- a/include/gui/SurfaceTextureClient.h
+++ b/include/gui/SurfaceTextureClient.h
@@ -21,6 +21,7 @@
 #include <gui/SurfaceTexture.h>
 
 #include <ui/egl/android_natives.h>
+#include <ui/Region.h>
 
 #include <utils/RefBase.h>
 #include <utils/threads.h>
@@ -37,29 +38,24 @@
 
     sp<ISurfaceTexture> getISurfaceTexture() const;
 
-private:
-    friend class Surface;
+protected:
+    SurfaceTextureClient();
+    void setISurfaceTexture(const sp<ISurfaceTexture>& surfaceTexture);
 
+private:
     // can't be copied
     SurfaceTextureClient& operator = (const SurfaceTextureClient& rhs);
     SurfaceTextureClient(const SurfaceTextureClient& rhs);
+    void init();
 
     // ANativeWindow hooks
-    static int cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
-    static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer);
-    static int lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
-    static int perform(ANativeWindow* window, int operation, ...);
-    static int query(const ANativeWindow* window, int what, int* value);
-    static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
-    static int setSwapInterval(ANativeWindow* window, int interval);
-
-    int cancelBuffer(ANativeWindowBuffer* buffer);
-    int dequeueBuffer(ANativeWindowBuffer** buffer);
-    int lockBuffer(ANativeWindowBuffer* buffer);
-    int perform(int operation, va_list args);
-    int query(int what, int* value) const;
-    int queueBuffer(ANativeWindowBuffer* buffer);
-    int setSwapInterval(int interval);
+    static int hook_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
+    static int hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer);
+    static int hook_lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
+    static int hook_perform(ANativeWindow* window, int operation, ...);
+    static int hook_query(const ANativeWindow* window, int what, int* value);
+    static int hook_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
+    static int hook_setSwapInterval(ANativeWindow* window, int interval);
 
     int dispatchConnect(va_list args);
     int dispatchDisconnect(va_list args);
@@ -71,26 +67,38 @@
     int dispatchSetBuffersTimestamp(va_list args);
     int dispatchSetCrop(va_list args);
     int dispatchSetUsage(va_list args);
+    int dispatchLock(va_list args);
+    int dispatchUnlockAndPost(va_list args);
 
-    int connect(int api);
-    int disconnect(int api);
-    int setBufferCount(int bufferCount);
-    int setBuffersDimensions(int w, int h);
-    int setBuffersFormat(int format);
-    int setBuffersTransform(int transform);
-    int setBuffersTimestamp(int64_t timestamp);
-    int setCrop(Rect const* rect);
-    int setUsage(uint32_t reqUsage);
+protected:
+    virtual int cancelBuffer(ANativeWindowBuffer* buffer);
+    virtual int dequeueBuffer(ANativeWindowBuffer** buffer);
+    virtual int lockBuffer(ANativeWindowBuffer* buffer);
+    virtual int perform(int operation, va_list args);
+    virtual int query(int what, int* value) const;
+    virtual int queueBuffer(ANativeWindowBuffer* buffer);
+    virtual int setSwapInterval(int interval);
 
-    void freeAllBuffers();
-    int getSlotFromBufferLocked(android_native_buffer_t* buffer) const;
-
-    int getConnectedApi() const;
+    virtual int connect(int api);
+    virtual int disconnect(int api);
+    virtual int setBufferCount(int bufferCount);
+    virtual int setBuffersDimensions(int w, int h);
+    virtual int setBuffersFormat(int format);
+    virtual int setBuffersTransform(int transform);
+    virtual int setBuffersTimestamp(int64_t timestamp);
+    virtual int setCrop(Rect const* rect);
+    virtual int setUsage(uint32_t reqUsage);
+    virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
+    virtual int unlockAndPost();
 
     enum { MIN_UNDEQUEUED_BUFFERS = SurfaceTexture::MIN_UNDEQUEUED_BUFFERS };
     enum { NUM_BUFFER_SLOTS = SurfaceTexture::NUM_BUFFER_SLOTS };
     enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
 
+private:
+    void freeAllBuffers();
+    int getSlotFromBufferLocked(android_native_buffer_t* buffer) const;
+
     // mSurfaceTexture is the interface to the surface texture server. All
     // operations on the surface texture client ultimately translate into
     // interactions with the server using this interface.
@@ -145,6 +153,12 @@
     // variables of SurfaceTexture objects. It must be locked whenever the
     // member variables are accessed.
     mutable Mutex mMutex;
+
+    // must be used from the lock/unlock thread
+    sp<GraphicBuffer>           mLockedBuffer;
+    sp<GraphicBuffer>           mPostedBuffer;
+    mutable Region              mOldDirtyRegion;
+    bool                        mConnectedToCpu;
 };
 
 }; // namespace android
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index ea5a9d3..1136f6c 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -25,6 +25,8 @@
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
 
+class ANativeWindow;
+
 namespace android {
 
 class Surface;
@@ -196,6 +198,8 @@
             status_t        prepareAsync_l();
             status_t        getDuration_l(int *msec);
             status_t        setDataSource(const sp<IMediaPlayer>& player);
+            void            disconnectNativeWindow();
+            status_t        reset_l();
 
     sp<IMediaPlayer>            mPlayer;
     thread_id_t                 mLockThreadId;
@@ -218,6 +222,8 @@
     int                         mVideoHeight;
     int                         mAudioSessionId;
     float                       mSendLevel;
+    sp<ANativeWindow>           mConnectedWindow;
+    sp<IBinder>                 mConnectedWindowBinder;
 };
 
 }; // namespace android
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index dc2a845..c2a494d 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -28,6 +28,8 @@
 #include <ui/Region.h>
 #include <ui/egl/android_natives.h>
 
+#include <gui/SurfaceTextureClient.h>
+
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/ISurfaceComposerClient.h>
 
@@ -37,14 +39,9 @@
 
 // ---------------------------------------------------------------------------
 
-class GraphicBuffer;
-class GraphicBufferMapper;
-class IOMX;
 class ISurfaceTexture;
-class Rect;
 class Surface;
 class SurfaceComposerClient;
-class SurfaceTextureClient;
 
 // ---------------------------------------------------------------------------
 
@@ -129,8 +126,7 @@
     
 // ---------------------------------------------------------------------------
 
-class Surface 
-    : public EGLNativeBase<ANativeWindow, Surface, RefBase>
+class Surface : public SurfaceTextureClient
 {
 public:
     struct SurfaceInfo {
@@ -158,32 +154,14 @@
     sp<ISurfaceTexture> getSurfaceTexture();
 
     // the lock/unlock APIs must be used from the same thread
-    status_t    lock(SurfaceInfo* info, bool blocking = true);
-    status_t    lock(SurfaceInfo* info, Region* dirty, bool blocking = true);
+    status_t    lock(SurfaceInfo* info, Region* dirty = NULL);
     status_t    unlockAndPost();
 
     sp<IBinder> asBinder() const;
 
 private:
-    /*
-     * Android frameworks friends
-     * (eventually this should go away and be replaced by proper APIs)
-     */
-    // camera and camcorder need access to the ISurface binder interface for preview
-    friend class CameraService;
-    friend class MediaRecorder;
-    // MediaPlayer needs access to ISurface for display
-    friend class MediaPlayer;
-    friend class IOMX;
-    friend class SoftwareRenderer;
     // this is just to be able to write some unit tests
     friend class Test;
-    // videoEditor preview classes
-    friend class VideoEditorPreviewController;
-    friend class PreviewRenderer;
-
-private:
-    friend class SurfaceComposerClient;
     friend class SurfaceControl;
 
     // can't be copied
@@ -194,62 +172,27 @@
     Surface(const Parcel& data, const sp<IBinder>& ref);
     ~Surface();
 
-
-    /*
-     *  ANativeWindow hooks
-     */
-    static int setSwapInterval(ANativeWindow* window, int interval);
-    static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer);
-    static int cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
-    static int lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
-    static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
-    static int query(const ANativeWindow* window, int what, int* value);
-    static int perform(ANativeWindow* window, int operation, ...);
-
-    int setSwapInterval(int interval);
-    int dequeueBuffer(ANativeWindowBuffer** buffer);
-    int lockBuffer(ANativeWindowBuffer* buffer);
-    int queueBuffer(ANativeWindowBuffer* buffer);
-    int cancelBuffer(ANativeWindowBuffer* buffer);
-    int query(int what, int* value) const;
-    int perform(int operation, va_list args);
-
     /*
      *  private stuff...
      */
     void init();
     status_t validate(bool inCancelBuffer = false) const;
 
-    int getConnectedApi() const;
-    
     static void cleanCachedSurfacesLocked();
 
+    virtual int query(int what, int* value) const;
+
     // constants
     status_t                    mInitCheck;
     sp<ISurface>                mSurface;
-    sp<SurfaceTextureClient>    mSurfaceTextureClient;
     uint32_t                    mIdentity;
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
-    
-    // protected by mSurfaceLock. These are also used from lock/unlock
-    // but in that case, they must be called form the same thread.
-    mutable Region              mDirtyRegion;
-
-    // must be used from the lock/unlock thread
-    sp<GraphicBuffer>           mLockedBuffer;
-    sp<GraphicBuffer>           mPostedBuffer;
-    mutable Region              mOldDirtyRegion;
-    bool                        mReserved;
 
     // query() must be called from dequeueBuffer() thread
     uint32_t                    mWidth;
     uint32_t                    mHeight;
 
-    // Inherently thread-safe
-    mutable Mutex               mSurfaceLock;
-    mutable Mutex               mApiLock;
-
     // A cache of Surface objects that have been deserialized into this process.
     static Mutex sCachedSurfacesLock;
     static DefaultKeyedVector<wp<IBinder>, wp<Surface> > sCachedSurfaces;
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 9185e1e..dabe643f 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -46,59 +46,6 @@
 
 namespace android {
 
-// ----------------------------------------------------------------------
-
-static status_t copyBlt(
-        const sp<GraphicBuffer>& dst, 
-        const sp<GraphicBuffer>& src, 
-        const Region& reg)
-{
-    // src and dst with, height and format must be identical. no verification
-    // is done here.
-    status_t err;
-    uint8_t const * src_bits = NULL;
-    err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
-    LOGE_IF(err, "error locking src buffer %s", strerror(-err));
-
-    uint8_t* dst_bits = NULL;
-    err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
-    LOGE_IF(err, "error locking dst buffer %s", strerror(-err));
-
-    Region::const_iterator head(reg.begin());
-    Region::const_iterator tail(reg.end());
-    if (head != tail && src_bits && dst_bits) {
-        const size_t bpp = bytesPerPixel(src->format);
-        const size_t dbpr = dst->stride * bpp;
-        const size_t sbpr = src->stride * bpp;
-
-        while (head != tail) {
-            const Rect& r(*head++);
-            ssize_t h = r.height();
-            if (h <= 0) continue;
-            size_t size = r.width() * bpp;
-            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
-            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
-            if (dbpr==sbpr && size==sbpr) {
-                size *= h;
-                h = 1;
-            }
-            do {
-                memcpy(d, s, size);
-                d += dbpr;
-                s += sbpr;
-            } while (--h > 0);
-        }
-    }
-    
-    if (src_bits)
-        src->unlock();
-    
-    if (dst_bits)
-        dst->unlock();
-    
-    return err;
-}
-
 // ============================================================================
 //  SurfaceControl
 // ============================================================================
@@ -277,7 +224,8 @@
 // ---------------------------------------------------------------------------
 
 Surface::Surface(const sp<SurfaceControl>& surface)
-    : mInitCheck(NO_INIT),
+    : SurfaceTextureClient(),
+      mInitCheck(NO_INIT),
       mSurface(surface->mSurface),
       mIdentity(surface->mIdentity),
       mFormat(surface->mFormat), mFlags(surface->mFlags),
@@ -287,7 +235,8 @@
 }
 
 Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
-    : mInitCheck(NO_INIT)
+    : SurfaceTextureClient(),
+      mInitCheck(NO_INIT)
 {
     mSurface    = interface_cast<ISurface>(ref);
     mIdentity   = parcel.readInt32();
@@ -363,36 +312,21 @@
 
 void Surface::init()
 {
-    ANativeWindow::setSwapInterval  = setSwapInterval;
-    ANativeWindow::dequeueBuffer    = dequeueBuffer;
-    ANativeWindow::cancelBuffer     = cancelBuffer;
-    ANativeWindow::lockBuffer       = lockBuffer;
-    ANativeWindow::queueBuffer      = queueBuffer;
-    ANativeWindow::query            = query;
-    ANativeWindow::perform          = perform;
-
     if (mSurface != NULL) {
         sp<ISurfaceTexture> surfaceTexture(mSurface->getSurfaceTexture());
         LOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface");
         if (surfaceTexture != NULL) {
-            mSurfaceTextureClient = new SurfaceTextureClient(surfaceTexture);
-            mSurfaceTextureClient->setUsage(GraphicBuffer::USAGE_HW_RENDER);
+            setISurfaceTexture(surfaceTexture);
+            setUsage(GraphicBuffer::USAGE_HW_RENDER);
         }
 
         DisplayInfo dinfo;
         SurfaceComposerClient::getDisplayInfo(0, &dinfo);
         const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
         const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
-
-        const_cast<int&>(ANativeWindow::minSwapInterval) =
-                mSurfaceTextureClient->minSwapInterval;
-
-        const_cast<int&>(ANativeWindow::maxSwapInterval) =
-                mSurfaceTextureClient->maxSwapInterval;
-
         const_cast<uint32_t&>(ANativeWindow::flags) = 0;
 
-        if (mSurfaceTextureClient != 0) {
+        if (surfaceTexture != NULL) {
             mInitCheck = NO_ERROR;
         }
     }
@@ -402,7 +336,6 @@
 {
     // clear all references and trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
-    mSurfaceTextureClient.clear();
     mSurface.clear();
     IPCThreadState::self()->flushCommands();
 }
@@ -431,77 +364,6 @@
 
 // ----------------------------------------------------------------------------
 
-int Surface::setSwapInterval(ANativeWindow* window, int interval) {
-    Surface* self = getSelf(window);
-    return self->setSwapInterval(interval);
-}
-
-int Surface::dequeueBuffer(ANativeWindow* window, 
-        ANativeWindowBuffer** buffer) {
-    Surface* self = getSelf(window);
-    return self->dequeueBuffer(buffer);
-}
-
-int Surface::cancelBuffer(ANativeWindow* window,
-        ANativeWindowBuffer* buffer) {
-    Surface* self = getSelf(window);
-    return self->cancelBuffer(buffer);
-}
-
-int Surface::lockBuffer(ANativeWindow* window, 
-        ANativeWindowBuffer* buffer) {
-    Surface* self = getSelf(window);
-    return self->lockBuffer(buffer);
-}
-
-int Surface::queueBuffer(ANativeWindow* window, 
-        ANativeWindowBuffer* buffer) {
-    Surface* self = getSelf(window);
-    return self->queueBuffer(buffer);
-}
-
-int Surface::query(const ANativeWindow* window,
-        int what, int* value) {
-    const Surface* self = getSelf(window);
-    return self->query(what, value);
-}
-
-int Surface::perform(ANativeWindow* window, 
-        int operation, ...) {
-    va_list args;
-    va_start(args, operation);
-    Surface* self = getSelf(window);
-    int res = self->perform(operation, args);
-    va_end(args);
-    return res;
-}
-
-// ----------------------------------------------------------------------------
-
-int Surface::setSwapInterval(int interval) {
-    return mSurfaceTextureClient->setSwapInterval(interval);
-}
-
-int Surface::dequeueBuffer(ANativeWindowBuffer** buffer) {
-    status_t err = mSurfaceTextureClient->dequeueBuffer(buffer);
-    if (err == NO_ERROR) {
-        mDirtyRegion.set(buffer[0]->width, buffer[0]->height);
-    }
-    return err;
-}
-
-int Surface::cancelBuffer(ANativeWindowBuffer* buffer) {
-    return mSurfaceTextureClient->cancelBuffer(buffer);
-}
-
-int Surface::lockBuffer(ANativeWindowBuffer* buffer) {
-    return mSurfaceTextureClient->lockBuffer(buffer);
-}
-
-int Surface::queueBuffer(ANativeWindowBuffer* buffer) {
-    return mSurfaceTextureClient->queueBuffer(buffer);
-}
-
 int Surface::query(int what, int* value) const {
     switch (what) {
     case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
@@ -509,141 +371,39 @@
         *value = 1;
         return NO_ERROR;
     case NATIVE_WINDOW_CONCRETE_TYPE:
-        // TODO: this is not needed anymore
         *value = NATIVE_WINDOW_SURFACE;
         return NO_ERROR;
     }
-    return mSurfaceTextureClient->query(what, value);
-}
-
-int Surface::perform(int operation, va_list args) {
-    return mSurfaceTextureClient->perform(operation, args);
+    return SurfaceTextureClient::query(what, value);
 }
 
 // ----------------------------------------------------------------------------
 
-int Surface::getConnectedApi() const {
-    return mSurfaceTextureClient->getConnectedApi();
-}
+status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn) {
+    ANativeWindow_Buffer outBuffer;
 
-// ----------------------------------------------------------------------------
-
-status_t Surface::lock(SurfaceInfo* info, bool blocking) {
-    return Surface::lock(info, NULL, blocking);
-}
-
-status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 
-{
-    if (getConnectedApi()) {
-        LOGE("Surface::lock(%p) failed. Already connected to another API",
-                (ANativeWindow*)this);
-        CallStack stack;
-        stack.update();
-        stack.dump("");
-        return INVALID_OPERATION;
+    ARect temp;
+    ARect* inOutDirtyBounds = NULL;
+    if (dirtyIn) {
+        temp = dirtyIn->getBounds();
+        inOutDirtyBounds = &temp;
     }
 
-    if (mApiLock.tryLock() != NO_ERROR) {
-        LOGE("calling Surface::lock from different threads!");
-        CallStack stack;
-        stack.update();
-        stack.dump("");
-        return WOULD_BLOCK;
-    }
+    status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);
 
-    /* Here we're holding mApiLock */
-    
-    if (mLockedBuffer != 0) {
-        LOGE("Surface::lock failed, already locked");
-        mApiLock.unlock();
-        return INVALID_OPERATION;
-    }
-
-    // we're intending to do software rendering from this point
-    mSurfaceTextureClient->setUsage(
-            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
-
-    ANativeWindowBuffer* out;
-    status_t err = mSurfaceTextureClient->dequeueBuffer(&out);
-    LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
     if (err == NO_ERROR) {
-        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
-        err = mSurfaceTextureClient->lockBuffer(backBuffer.get());
-        LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",
-                backBuffer->handle, strerror(-err));
-        if (err == NO_ERROR) {
-            const Rect bounds(backBuffer->width, backBuffer->height);
-            const Region boundsRegion(bounds);
-            Region scratch(boundsRegion);
-            Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
-            newDirtyRegion &= boundsRegion;
-
-            // figure out if we can copy the frontbuffer back
-            const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
-            const bool canCopyBack = (frontBuffer != 0 &&
-                    backBuffer->width  == frontBuffer->width &&
-                    backBuffer->height == frontBuffer->height &&
-                    backBuffer->format == frontBuffer->format &&
-                    !(mFlags & ISurfaceComposer::eDestroyBackbuffer));
-
-            // the dirty region we report to surfaceflinger is the one
-            // given by the user (as opposed to the one *we* return to the
-            // user).
-            mDirtyRegion = newDirtyRegion;
-
-            if (canCopyBack) {
-                // copy the area that is invalid and not repainted this round
-                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
-                if (!copyback.isEmpty())
-                    copyBlt(backBuffer, frontBuffer, copyback);
-            } else {
-                // if we can't copy-back anything, modify the user's dirty
-                // region to make sure they redraw the whole buffer
-                newDirtyRegion = boundsRegion;
-            }
-
-            // keep track of the are of the buffer that is "clean"
-            // (ie: that will be redrawn)
-            mOldDirtyRegion = newDirtyRegion;
-
-            void* vaddr;
-            status_t res = backBuffer->lock(
-                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
-                    newDirtyRegion.bounds(), &vaddr);
-            
-            LOGW_IF(res, "failed locking buffer (handle = %p)", 
-                    backBuffer->handle);
-
-            mLockedBuffer = backBuffer;
-            other->w      = backBuffer->width;
-            other->h      = backBuffer->height;
-            other->s      = backBuffer->stride;
-            other->usage  = backBuffer->usage;
-            other->format = backBuffer->format;
-            other->bits   = vaddr;
-        }
+        other->w = uint32_t(outBuffer.width);
+        other->h = uint32_t(outBuffer.height);
+        other->s = uint32_t(outBuffer.stride);
+        other->usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
+        other->format = uint32_t(outBuffer.format);
+        other->bits = outBuffer.bits;
     }
-    mApiLock.unlock();
     return err;
 }
-    
-status_t Surface::unlockAndPost() 
-{
-    if (mLockedBuffer == 0) {
-        LOGE("Surface::unlockAndPost failed, no locked buffer");
-        return INVALID_OPERATION;
-    }
 
-    status_t err = mLockedBuffer->unlock();
-    LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
-    
-    err = mSurfaceTextureClient->queueBuffer(mLockedBuffer.get());
-    LOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
-            mLockedBuffer->handle, strerror(-err));
-
-    mPostedBuffer = mLockedBuffer;
-    mLockedBuffer = 0;
-    return err;
+status_t Surface::unlockAndPost() {
+    return SurfaceTextureClient::unlockAndPost();
 }
 
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 1410481..a12d40a 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -495,7 +495,7 @@
 }
 
 status_t SurfaceTexture::connect(int api) {
-    LOGV("SurfaceTexture::connect");
+    LOGV("SurfaceTexture::connect(this=%p, %d)", this, api);
     Mutex::Autolock lock(mMutex);
     int err = NO_ERROR;
     switch (api) {
@@ -504,6 +504,8 @@
         case NATIVE_WINDOW_API_MEDIA:
         case NATIVE_WINDOW_API_CAMERA:
             if (mConnectedApi != NO_CONNECTED_API) {
+                LOGE("connect: already connected (cur=%d, req=%d)",
+                        mConnectedApi, api);
                 err = -EINVAL;
             } else {
                 mConnectedApi = api;
@@ -517,7 +519,7 @@
 }
 
 status_t SurfaceTexture::disconnect(int api) {
-    LOGV("SurfaceTexture::disconnect");
+    LOGV("SurfaceTexture::disconnect(this=%p, %d)", this, api);
     Mutex::Autolock lock(mMutex);
     int err = NO_ERROR;
     switch (api) {
@@ -528,6 +530,8 @@
             if (mConnectedApi == api) {
                 mConnectedApi = NO_CONNECTED_API;
             } else {
+                LOGE("disconnect: connected to another api (cur=%d, req=%d)",
+                        mConnectedApi, api);
                 err = -EINVAL;
             }
             break;
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index f39cabf..d5b7c89 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -24,24 +24,45 @@
 namespace android {
 
 SurfaceTextureClient::SurfaceTextureClient(
-        const sp<ISurfaceTexture>& surfaceTexture):
-        mSurfaceTexture(surfaceTexture), mAllocator(0), mReqWidth(0),
-        mReqHeight(0), mReqFormat(0), mReqUsage(0),
-        mTimestamp(NATIVE_WINDOW_TIMESTAMP_AUTO),
-        mQueryWidth(0), mQueryHeight(0), mQueryFormat(0),
-        mMutex() {
+        const sp<ISurfaceTexture>& surfaceTexture)
+{
+    SurfaceTextureClient::init();
+    SurfaceTextureClient::setISurfaceTexture(surfaceTexture);
+}
+
+SurfaceTextureClient::SurfaceTextureClient() {
+    SurfaceTextureClient::init();
+}
+
+void SurfaceTextureClient::init() {
     // Initialize the ANativeWindow function pointers.
-    ANativeWindow::setSwapInterval  = setSwapInterval;
-    ANativeWindow::dequeueBuffer    = dequeueBuffer;
-    ANativeWindow::cancelBuffer     = cancelBuffer;
-    ANativeWindow::lockBuffer       = lockBuffer;
-    ANativeWindow::queueBuffer      = queueBuffer;
-    ANativeWindow::query            = query;
-    ANativeWindow::perform          = perform;
+    ANativeWindow::setSwapInterval  = hook_setSwapInterval;
+    ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
+    ANativeWindow::cancelBuffer     = hook_cancelBuffer;
+    ANativeWindow::lockBuffer       = hook_lockBuffer;
+    ANativeWindow::queueBuffer      = hook_queueBuffer;
+    ANativeWindow::query            = hook_query;
+    ANativeWindow::perform          = hook_perform;
 
     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
 
+    mReqWidth = 0;
+    mReqHeight = 0;
+    mReqFormat = 0;
+    mReqUsage = 0;
+    mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
+    mQueryWidth = 0;
+    mQueryHeight = 0;
+    mQueryFormat = 0;
+    mConnectedToCpu = false;
+}
+
+void SurfaceTextureClient::setISurfaceTexture(
+        const sp<ISurfaceTexture>& surfaceTexture)
+{
+    mSurfaceTexture = surfaceTexture;
+
     // Get a reference to the allocator.
     mAllocator = mSurfaceTexture->getAllocator();
 }
@@ -50,42 +71,42 @@
     return mSurfaceTexture;
 }
 
-int SurfaceTextureClient::setSwapInterval(ANativeWindow* window, int interval) {
+int SurfaceTextureClient::hook_setSwapInterval(ANativeWindow* window, int interval) {
     SurfaceTextureClient* c = getSelf(window);
     return c->setSwapInterval(interval);
 }
 
-int SurfaceTextureClient::dequeueBuffer(ANativeWindow* window,
+int SurfaceTextureClient::hook_dequeueBuffer(ANativeWindow* window,
         ANativeWindowBuffer** buffer) {
     SurfaceTextureClient* c = getSelf(window);
     return c->dequeueBuffer(buffer);
 }
 
-int SurfaceTextureClient::cancelBuffer(ANativeWindow* window,
+int SurfaceTextureClient::hook_cancelBuffer(ANativeWindow* window,
         ANativeWindowBuffer* buffer) {
     SurfaceTextureClient* c = getSelf(window);
     return c->cancelBuffer(buffer);
 }
 
-int SurfaceTextureClient::lockBuffer(ANativeWindow* window,
+int SurfaceTextureClient::hook_lockBuffer(ANativeWindow* window,
         ANativeWindowBuffer* buffer) {
     SurfaceTextureClient* c = getSelf(window);
     return c->lockBuffer(buffer);
 }
 
-int SurfaceTextureClient::queueBuffer(ANativeWindow* window,
+int SurfaceTextureClient::hook_queueBuffer(ANativeWindow* window,
         ANativeWindowBuffer* buffer) {
     SurfaceTextureClient* c = getSelf(window);
     return c->queueBuffer(buffer);
 }
 
-int SurfaceTextureClient::query(const ANativeWindow* window,
+int SurfaceTextureClient::hook_query(const ANativeWindow* window,
                                 int what, int* value) {
     const SurfaceTextureClient* c = getSelf(window);
     return c->query(what, value);
 }
 
-int SurfaceTextureClient::perform(ANativeWindow* window, int operation, ...) {
+int SurfaceTextureClient::hook_perform(ANativeWindow* window, int operation, ...) {
     va_list args;
     va_start(args, operation);
     SurfaceTextureClient* c = getSelf(window);
@@ -219,7 +240,6 @@
         *value = 0;
         return NO_ERROR;
     case NATIVE_WINDOW_CONCRETE_TYPE:
-        // TODO: this is not needed anymore
         *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
         return NO_ERROR;
     }
@@ -260,6 +280,12 @@
     case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
         res = dispatchSetBuffersFormat(args);
         break;
+    case NATIVE_WINDOW_LOCK:
+        res = dispatchLock(args);
+        break;
+    case NATIVE_WINDOW_UNLOCK_AND_POST:
+        res = dispatchUnlockAndPost(args);
+        break;
     default:
         res = NAME_NOT_FOUND;
         break;
@@ -324,28 +350,37 @@
     return setBuffersTimestamp(timestamp);
 }
 
+int SurfaceTextureClient::dispatchLock(va_list args) {
+    ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
+    ARect* inOutDirtyBounds = va_arg(args, ARect*);
+    return lock(outBuffer, inOutDirtyBounds);
+}
+
+int SurfaceTextureClient::dispatchUnlockAndPost(va_list args) {
+    return unlockAndPost();
+}
+
+
 int SurfaceTextureClient::connect(int api) {
     LOGV("SurfaceTextureClient::connect");
     Mutex::Autolock lock(mMutex);
-    return mSurfaceTexture->connect(api);
+    int err = mSurfaceTexture->connect(api);
+    if (!err && api == NATIVE_WINDOW_API_CPU) {
+        mConnectedToCpu = true;
+    }
+    return err;
 }
 
 int SurfaceTextureClient::disconnect(int api) {
     LOGV("SurfaceTextureClient::disconnect");
     Mutex::Autolock lock(mMutex);
-    return mSurfaceTexture->disconnect(api);
+    int err = mSurfaceTexture->disconnect(api);
+    if (!err && api == NATIVE_WINDOW_API_CPU) {
+        mConnectedToCpu = false;
+    }
+    return err;
 }
 
-int SurfaceTextureClient::getConnectedApi() const
-{
-    // XXX: This method will be going away shortly, and is currently bogus.  It
-    // always returns "nothing is connected".  It will go away once Surface gets
-    // updated to actually connect as the 'CPU' API when locking a buffer.
-    Mutex::Autolock lock(mMutex);
-    return 0;
-}
-
-
 int SurfaceTextureClient::setUsage(uint32_t reqUsage)
 {
     LOGV("SurfaceTextureClient::setUsage");
@@ -443,4 +478,160 @@
     }
 }
 
+// ----------------------------------------------------------------------
+// the lock/unlock APIs must be used from the same thread
+
+static status_t copyBlt(
+        const sp<GraphicBuffer>& dst,
+        const sp<GraphicBuffer>& src,
+        const Region& reg)
+{
+    // src and dst with, height and format must be identical. no verification
+    // is done here.
+    status_t err;
+    uint8_t const * src_bits = NULL;
+    err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
+    LOGE_IF(err, "error locking src buffer %s", strerror(-err));
+
+    uint8_t* dst_bits = NULL;
+    err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
+    LOGE_IF(err, "error locking dst buffer %s", strerror(-err));
+
+    Region::const_iterator head(reg.begin());
+    Region::const_iterator tail(reg.end());
+    if (head != tail && src_bits && dst_bits) {
+        const size_t bpp = bytesPerPixel(src->format);
+        const size_t dbpr = dst->stride * bpp;
+        const size_t sbpr = src->stride * bpp;
+
+        while (head != tail) {
+            const Rect& r(*head++);
+            ssize_t h = r.height();
+            if (h <= 0) continue;
+            size_t size = r.width() * bpp;
+            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
+            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
+            if (dbpr==sbpr && size==sbpr) {
+                size *= h;
+                h = 1;
+            }
+            do {
+                memcpy(d, s, size);
+                d += dbpr;
+                s += sbpr;
+            } while (--h > 0);
+        }
+    }
+
+    if (src_bits)
+        src->unlock();
+
+    if (dst_bits)
+        dst->unlock();
+
+    return err;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t SurfaceTextureClient::lock(
+        ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
+{
+    if (mLockedBuffer != 0) {
+        LOGE("Surface::lock failed, already locked");
+        return INVALID_OPERATION;
+    }
+
+    if (!mConnectedToCpu) {
+        int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU);
+        if (err) {
+            return err;
+        }
+        // we're intending to do software rendering from this point
+        setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+    }
+
+    ANativeWindowBuffer* out;
+    status_t err = dequeueBuffer(&out);
+    LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
+    if (err == NO_ERROR) {
+        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
+        err = lockBuffer(backBuffer.get());
+        LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",
+                backBuffer->handle, strerror(-err));
+        if (err == NO_ERROR) {
+            const Rect bounds(backBuffer->width, backBuffer->height);
+
+            Region newDirtyRegion;
+            if (inOutDirtyBounds) {
+                newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
+                newDirtyRegion.andSelf(bounds);
+            } else {
+                newDirtyRegion.set(bounds);
+            }
+
+            // figure out if we can copy the frontbuffer back
+            const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
+            const bool canCopyBack = (frontBuffer != 0 &&
+                    backBuffer->width  == frontBuffer->width &&
+                    backBuffer->height == frontBuffer->height &&
+                    backBuffer->format == frontBuffer->format);
+
+            if (canCopyBack) {
+                // copy the area that is invalid and not repainted this round
+                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
+                if (!copyback.isEmpty())
+                    copyBlt(backBuffer, frontBuffer, copyback);
+            } else {
+                // if we can't copy-back anything, modify the user's dirty
+                // region to make sure they redraw the whole buffer
+                newDirtyRegion.set(bounds);
+            }
+
+            // keep track of the are of the buffer that is "clean"
+            // (ie: that will be redrawn)
+            mOldDirtyRegion = newDirtyRegion;
+
+            if (inOutDirtyBounds) {
+                *inOutDirtyBounds = newDirtyRegion.getBounds();
+            }
+
+            void* vaddr;
+            status_t res = backBuffer->lock(
+                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                    newDirtyRegion.bounds(), &vaddr);
+
+            LOGW_IF(res, "failed locking buffer (handle = %p)",
+                    backBuffer->handle);
+
+            mLockedBuffer = backBuffer;
+            outBuffer->width  = backBuffer->width;
+            outBuffer->height = backBuffer->height;
+            outBuffer->stride = backBuffer->stride;
+            outBuffer->format = backBuffer->format;
+            outBuffer->bits   = vaddr;
+        }
+    }
+    return err;
+}
+
+status_t SurfaceTextureClient::unlockAndPost()
+{
+    if (mLockedBuffer == 0) {
+        LOGE("Surface::unlockAndPost failed, no locked buffer");
+        return INVALID_OPERATION;
+    }
+
+    status_t err = mLockedBuffer->unlock();
+    LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
+
+    err = queueBuffer(mLockedBuffer.get());
+    LOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
+            mLockedBuffer->handle, strerror(-err));
+
+    mPostedBuffer = mLockedBuffer;
+    mLockedBuffer = 0;
+    return err;
+}
+
 }; // namespace android
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 519b40e..2b8f204 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -613,4 +613,90 @@
     }
 }
 
+class MultiSurfaceTextureClientTest : public ::testing::Test {
+
+public:
+    MultiSurfaceTextureClientTest() :
+            mEglDisplay(EGL_NO_DISPLAY),
+            mEglContext(EGL_NO_CONTEXT) {
+        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
+            mEglSurfaces[i] = EGL_NO_CONTEXT;
+        }
+    }
+
+protected:
+
+    enum { NUM_SURFACE_TEXTURES = 32 };
+
+    virtual void SetUp() {
+        mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
+
+        EGLint majorVersion, minorVersion;
+        EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        EGLConfig myConfig;
+        EGLint numConfigs = 0;
+        EGLint configAttribs[] = {
+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+            EGL_NONE
+        };
+        EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &myConfig, 1,
+                &numConfigs));
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+        mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT,
+                0);
+        ASSERT_EQ(EGL_SUCCESS, eglGetError());
+        ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
+
+        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
+            sp<SurfaceTexture> st(new SurfaceTexture(i));
+            sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st));
+            mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
+                    static_cast<ANativeWindow*>(stc.get()), NULL);
+            ASSERT_EQ(EGL_SUCCESS, eglGetError());
+            ASSERT_NE(EGL_NO_SURFACE, mEglSurfaces[i]);
+        }
+    }
+
+    virtual void TearDown() {
+        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                EGL_NO_CONTEXT);
+
+        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
+            if (mEglSurfaces[i] != EGL_NO_SURFACE) {
+                eglDestroySurface(mEglDisplay, mEglSurfaces[i]);
+            }
+        }
+
+        if (mEglContext != EGL_NO_CONTEXT) {
+            eglDestroyContext(mEglDisplay, mEglContext);
+        }
+
+        if (mEglDisplay != EGL_NO_DISPLAY) {
+            eglTerminate(mEglDisplay);
+        }
+    }
+
+    EGLDisplay mEglDisplay;
+    EGLSurface mEglSurfaces[NUM_SURFACE_TEXTURES];
+    EGLContext mEglContext;
+};
+
+// XXX: This test is disabled because it causes a hang on some devices.  See bug
+// 5015672.
+TEST_F(MultiSurfaceTextureClientTest, DISABLED_MakeCurrentBetweenSurfacesWorks) {
+    for (int iter = 0; iter < 8; iter++) {
+        for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
+            eglMakeCurrent(mEglDisplay, mEglSurfaces[i], mEglSurfaces[i],
+                    mEglContext);
+            glClear(GL_COLOR_BUFFER_BIT);
+            eglSwapBuffers(mEglDisplay, mEglSurfaces[i]);
+        }
+    }
+}
+
 } // namespace android
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index e232ddd..7114b6a 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -33,6 +33,16 @@
 namespace uirenderer {
 
 ///////////////////////////////////////////////////////////////////////////////
+// Macros
+///////////////////////////////////////////////////////////////////////////////
+
+#if DEBUG_CACHE_FLUSH
+    #define FLUSH_LOGD(...) LOGD(__VA_ARGS__)
+#else
+    #define FLUSH_LOGD(...)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
 // Constructors/destructor
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -150,6 +160,30 @@
     mLayerGarbage.push(layer);
 }
 
+void Caches::flush(FlushMode mode) {
+    FLUSH_LOGD("Flushing caches (mode %d)", mode);
+
+    clearGarbage();
+
+    switch (mode) {
+        case kFlushMode_Full:
+            textureCache.clear();
+            patchCache.clear();
+            dropShadowCache.clear();
+            gradientCache.clear();
+            // fall through
+        case kFlushMode_Moderate:
+            layerCache.clear();
+            pathCache.clear();
+            roundRectShapeCache.clear();
+            circleShapeCache.clear();
+            ovalShapeCache.clear();
+            rectShapeCache.clear();
+            arcShapeCache.clear();
+            break;
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // VBO
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index e64d8ac..76dff4b 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -100,6 +100,18 @@
     Vector<Layer*> mLayerGarbage;
 
 public:
+    enum FlushMode {
+        kFlushMode_Moderate = 0,
+        kFlushMode_Full
+    };
+
+    /**
+     * Flush the cache.
+     *
+     * @param mode Indicates how much of the cache should be flushed
+     */
+    void flush(FlushMode mode);
+
     /**
      * Indicates whether the renderer is in debug mode.
      * This debug mode provides limited information to app developers.
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 2cdc8c3..5db73db 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -26,6 +26,9 @@
 // Turn on to enable memory usage summary on each frame
 #define DEBUG_MEMORY_USAGE 0
 
+// Turn on to enable debugging of cache flushes
+#define DEBUG_CACHE_FLUSH 1
+
 // Turn on to enable layers debugging when rendered as regions
 #define DEBUG_LAYERS_AS_REGIONS 0
 
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 9c10c75..794747d 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -303,6 +303,10 @@
         case NATIVE_WINDOW_CONNECT:
         case NATIVE_WINDOW_DISCONNECT:
             break;
+        case NATIVE_WINDOW_LOCK:
+            return INVALID_OPERATION;
+        case NATIVE_WINDOW_UNLOCK_AND_POST:
+            return INVALID_OPERATION;
         default:
             return NAME_NOT_FOUND;
     }
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 7b7ba74..178039c 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -27,6 +27,8 @@
 #include <binder/IServiceManager.h>
 #include <binder/IPCThreadState.h>
 
+#include <gui/SurfaceTextureClient.h>
+
 #include <media/mediaplayer.h>
 #include <media/AudioTrack.h>
 
@@ -38,6 +40,7 @@
 #include <utils/String8.h>
 
 #include <system/audio.h>
+#include <system/window.h>
 
 namespace android {
 
@@ -194,13 +197,62 @@
     return mPlayer->getMetadata(update_only, apply_filter, metadata);
 }
 
+void MediaPlayer::disconnectNativeWindow() {
+    if (mConnectedWindow != NULL) {
+        status_t err = native_window_disconnect(mConnectedWindow.get(),
+                NATIVE_WINDOW_API_MEDIA);
+
+        if (err != OK) {
+            LOGW("native_window_disconnect returned an error: %s (%d)",
+                    strerror(-err), err);
+        }
+    }
+    mConnectedWindow.clear();
+}
+
 status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
 {
     LOGV("setVideoSurface");
     Mutex::Autolock _l(mLock);
     if (mPlayer == 0) return NO_INIT;
 
-    return mPlayer->setVideoSurface(surface);
+    sp<IBinder> binder(surface == NULL ? NULL : surface->asBinder());
+    if (mConnectedWindowBinder == binder) {
+        return OK;
+    }
+
+    if (surface != NULL) {
+        status_t err = native_window_connect(surface.get(),
+                NATIVE_WINDOW_API_MEDIA);
+
+        if (err != OK) {
+            // Note that we must do the reset before disconnecting from the ANW.
+            // Otherwise queue/dequeue calls could be made on the disconnected
+            // ANW, which may result in errors.
+            reset_l();
+
+            disconnectNativeWindow();
+
+            return err;
+        }
+    }
+
+    // Note that we must set the player's new surface before disconnecting the
+    // old one.  Otherwise queue/dequeue calls could be made on the disconnected
+    // ANW, which may result in errors.
+    status_t err = mPlayer->setVideoSurface(surface);
+
+    disconnectNativeWindow();
+
+    mConnectedWindow = surface;
+
+    if (err == OK) {
+        mConnectedWindowBinder = binder;
+    } else {
+        disconnectNativeWindow();
+    }
+
+    return err;
 }
 
 status_t MediaPlayer::setVideoSurfaceTexture(
@@ -210,7 +262,46 @@
     Mutex::Autolock _l(mLock);
     if (mPlayer == 0) return NO_INIT;
 
-    return mPlayer->setVideoSurfaceTexture(surfaceTexture);
+    sp<IBinder> binder(surfaceTexture == NULL ? NULL :
+            surfaceTexture->asBinder());
+    if (mConnectedWindowBinder == binder) {
+        return OK;
+    }
+
+    sp<ANativeWindow> anw;
+    if (surfaceTexture != NULL) {
+        anw = new SurfaceTextureClient(surfaceTexture);
+        status_t err = native_window_connect(anw.get(),
+                NATIVE_WINDOW_API_MEDIA);
+
+        if (err != OK) {
+            // Note that we must do the reset before disconnecting from the ANW.
+            // Otherwise queue/dequeue calls could be made on the disconnected
+            // ANW, which may result in errors.
+            reset_l();
+
+            disconnectNativeWindow();
+
+            return err;
+        }
+    }
+
+    // Note that we must set the player's new SurfaceTexture before
+    // disconnecting the old one.  Otherwise queue/dequeue calls could be made
+    // on the disconnected ANW, which may result in errors.
+    status_t err = mPlayer->setVideoSurfaceTexture(surfaceTexture);
+
+    disconnectNativeWindow();
+
+    mConnectedWindow = anw;
+
+    if (err == OK) {
+        mConnectedWindowBinder = binder;
+    } else {
+        disconnectNativeWindow();
+    }
+
+    return err;
 }
 
 // must call with lock held
@@ -434,10 +525,8 @@
     return result;
 }
 
-status_t MediaPlayer::reset()
+status_t MediaPlayer::reset_l()
 {
-    LOGV("reset");
-    Mutex::Autolock _l(mLock);
     mLoop = false;
     if (mCurrentState == MEDIA_PLAYER_IDLE) return NO_ERROR;
     mPrepareSync = false;
@@ -458,6 +547,13 @@
     return NO_ERROR;
 }
 
+status_t MediaPlayer::reset()
+{
+    LOGV("reset");
+    Mutex::Autolock _l(mLock);
+    return reset_l();
+}
+
 status_t MediaPlayer::setAudioStreamType(int type)
 {
     LOGV("MediaPlayer::setAudioStreamType");
diff --git a/media/libstagefright/codecs/aacenc/src/bit_cnt.c b/media/libstagefright/codecs/aacenc/src/bit_cnt.c
index dd0b9b4..8853efc 100644
--- a/media/libstagefright/codecs/aacenc/src/bit_cnt.c
+++ b/media/libstagefright/codecs/aacenc/src/bit_cnt.c
@@ -496,7 +496,7 @@
 {
 
   Word32 i, t0, t1, t2, t3, t00, t01;
-  Word16 codeWord, codeLength;
+  UWord16 codeWord, codeLength;
   Word16 sign, signLength;
 
    
diff --git a/media/libstagefright/codecs/aacenc/src/memalign.c b/media/libstagefright/codecs/aacenc/src/memalign.c
index 7d203527..44dd4ba 100644
--- a/media/libstagefright/codecs/aacenc/src/memalign.c
+++ b/media/libstagefright/codecs/aacenc/src/memalign.c
@@ -23,6 +23,11 @@
 
 
 #include	"memalign.h"
+#ifdef _MSC_VER
+#include	<stddef.h>
+#else
+#include	<stdint.h>
+#endif
 
 /*****************************************************************************
 *
@@ -66,8 +71,8 @@
 		pMemop->Set(CodecID, tmp, 0, size + alignment);
 
 		mem_ptr =
-			(unsigned char *) ((unsigned int) (tmp + alignment - 1) &
-					(~((unsigned int) (alignment - 1))));
+			(unsigned char *) ((intptr_t) (tmp + alignment - 1) &
+					(~((intptr_t) (alignment - 1))));
 
 		if (mem_ptr == tmp)
 			mem_ptr += alignment;
diff --git a/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c b/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c
deleted file mode 100644
index dd7c26d..0000000
--- a/media/libstagefright/codecs/amrwbenc/src/cmnMemory.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- ** Copyright 2003-2010, VisualOn, Inc.
- **
- ** 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.
- */
-/*******************************************************************************
-	File:		cmnMemory.c
-
-	Content:	sample code for memory operator implementation
-
-*******************************************************************************/
-#include "cmnMemory.h"
-
-#include <malloc.h>
-#if defined LINUX
-#include <string.h>
-#endif
-
-//VO_MEM_OPERATOR		g_memOP;
-
-VO_U32 cmnMemAlloc (VO_S32 uID,  VO_MEM_INFO * pMemInfo)
-{
-	if (!pMemInfo)
-		return VO_ERR_INVALID_ARG;
-
-	pMemInfo->VBuffer = malloc (pMemInfo->Size);
-	return 0;
-}
-
-VO_U32 cmnMemFree (VO_S32 uID, VO_PTR pMem)
-{
-	free (pMem);
-	return 0;
-}
-
-VO_U32	cmnMemSet (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize)
-{
-	memset (pBuff, uValue, uSize);
-	return 0;
-}
-
-VO_U32	cmnMemCopy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
-{
-	memcpy (pDest, pSource, uSize);
-	return 0;
-}
-
-VO_U32	cmnMemCheck (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize)
-{
-	return 0;
-}
-
-VO_S32 cmnMemCompare (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize)
-{
-	return memcmp(pBuffer1, pBuffer2, uSize);
-}
-
-VO_U32	cmnMemMove (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
-{
-	memmove (pDest, pSource, uSize);
-	return 0;
-}
-
diff --git a/media/libstagefright/codecs/common/cmnMemory.c b/media/libstagefright/codecs/common/cmnMemory.c
index dd7c26d..aa52bd9 100644
--- a/media/libstagefright/codecs/common/cmnMemory.c
+++ b/media/libstagefright/codecs/common/cmnMemory.c
@@ -21,10 +21,8 @@
 *******************************************************************************/
 #include "cmnMemory.h"
 
-#include <malloc.h>
-#if defined LINUX
+#include <stdlib.h>
 #include <string.h>
-#endif
 
 //VO_MEM_OPERATOR		g_memOP;
 
diff --git a/media/libstagefright/codecs/common/include/voType.h b/media/libstagefright/codecs/common/include/voType.h
index 70b2e83..5f659ab 100644
--- a/media/libstagefright/codecs/common/include/voType.h
+++ b/media/libstagefright/codecs/common/include/voType.h
@@ -101,7 +101,7 @@
    since the compiler does not support the way the component was written.
 */
 #ifndef VO_SKIP64BIT
-#ifdef _WIN32
+#ifdef _MSC_VER
 /** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
 typedef unsigned __int64  VO_U64;
 /** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */
diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp
index 2c0e88e..5c016c4 100644
--- a/native/android/native_window.cpp
+++ b/native/android/native_window.cpp
@@ -81,39 +81,9 @@
 
 int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
         ARect* inOutDirtyBounds) {
-    int type = -1;
-    if (window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &type) != 0 ||
-            type != NATIVE_WINDOW_SURFACE) {
-        return BAD_VALUE;
-    }
-
-    Region dirtyRegion;
-    Region* dirtyParam = NULL;
-    if (inOutDirtyBounds != NULL) {
-        dirtyRegion.set(*(Rect*)inOutDirtyBounds);
-        dirtyParam = &dirtyRegion;
-    }
-    
-    Surface::SurfaceInfo info;
-    status_t res = static_cast<Surface*>(window)->lock(&info, dirtyParam);
-    if (res != OK) {
-        return -1;
-    }
-    
-    outBuffer->width = (int32_t)info.w;
-    outBuffer->height = (int32_t)info.h;
-    outBuffer->stride = (int32_t)info.s;
-    outBuffer->format = (int32_t)info.format;
-    outBuffer->bits = info.bits;
-    
-    if (inOutDirtyBounds != NULL) {
-        *inOutDirtyBounds = dirtyRegion.getBounds();
-    }
-    
-    return 0;
+    return window->perform(window, NATIVE_WINDOW_LOCK, outBuffer, inOutDirtyBounds);
 }
 
 int32_t ANativeWindow_unlockAndPost(ANativeWindow* window) {
-    status_t res = static_cast<Surface*>(window)->unlockAndPost();
-    return res == android::OK ? 0 : -1;
+    return window->perform(window, NATIVE_WINDOW_UNLOCK_AND_POST);
 }
diff --git a/native/include/android/native_window.h b/native/include/android/native_window.h
index 337fa96..2f4f2d3 100644
--- a/native/include/android/native_window.h
+++ b/native/include/android/native_window.h
@@ -99,10 +99,16 @@
  * width and height must be either both zero or both non-zero.
  *
  */
-int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, int32_t height, int32_t format);
+int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
+        int32_t width, int32_t height, int32_t format);
 
 /**
  * Lock the window's next drawing surface for writing.
+ * inOutDirtyBounds is used as an in/out parameter, upon entering the
+ * function, it contains the dirty region, that is, the region the caller
+ * intends to redraw. When the function returns, inOutDirtyBounds is updated
+ * with the actual area the caller needs to redraw -- this region is often
+ * extended by ANativeWindow_lock.
  */
 int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
         ARect* inOutDirtyBounds);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index dedbe5d..af5c72d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -218,9 +218,165 @@
         R.drawable.stat_sys_roaming_cdma_0,
         R.drawable.stat_sys_roaming_cdma_0,
         R.drawable.stat_sys_roaming_cdma_0,
-        R.drawable.stat_sys_roaming_cdma_0 //83
+        R.drawable.stat_sys_roaming_cdma_0, //83
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0,
+        R.drawable.stat_sys_roaming_cdma_0 //239
 
-        // 128-255 Reserved
+        // 240-255 Reserved
     };
 
     //***** Data connection icons
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 9b09983..0eff776 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -502,77 +502,82 @@
 
 // ----------------------------------------------------------------------------
 
-// set the Surface that the preview will use
-status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
-    LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
+static void disconnectWindow(const sp<ANativeWindow>& window) {
+    if (window != 0) {
+        status_t result = native_window_disconnect(window.get(),
+                NATIVE_WINDOW_API_CAMERA);
+        if (result != NO_ERROR) {
+            LOGW("native_window_disconnect failed: %s (%d)", strerror(-result),
+                    result);
+        }
+    }
+}
+
+status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder,
+        const sp<ANativeWindow>& window) {
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
     if (result != NO_ERROR) return result;
 
-    result = NO_ERROR;
-
     // return if no change in surface.
-    sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0);
     if (binder == mSurface) {
-        return result;
+        return NO_ERROR;
     }
 
-    if (mSurface != 0) {
-        LOG1("clearing old preview surface %p", mSurface.get());
-    }
-    mSurface = binder;
-    mPreviewWindow = surface;
-
-    // If preview has been already started, register preview
-    // buffers now.
-    if (mHardware->previewEnabled()) {
-        if (mPreviewWindow != 0) {
-            native_window_set_buffers_transform(mPreviewWindow.get(),
-                                                mOrientation);
-            result = mHardware->setPreviewWindow(mPreviewWindow);
+    if (window != 0) {
+        result = native_window_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
+        if (result != NO_ERROR) {
+            LOGE("native_window_connect failed: %s (%d)", strerror(-result),
+                    result);
+            return result;
         }
     }
 
+    // If preview has been already started, register preview buffers now.
+    if (mHardware->previewEnabled()) {
+        if (window != 0) {
+            native_window_set_buffers_transform(window.get(), mOrientation);
+            result = mHardware->setPreviewWindow(window);
+        }
+    }
+
+    if (result == NO_ERROR) {
+        // Everything has succeeded.  Disconnect the old window and remember the
+        // new window.
+        disconnectWindow(mPreviewWindow);
+        mSurface = binder;
+        mPreviewWindow = window;
+    } else {
+        // Something went wrong after we connected to the new window, so
+        // disconnect here.
+        disconnectWindow(window);
+    }
+
     return result;
 }
 
+// set the Surface that the preview will use
+status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
+    LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
+
+    sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0);
+    sp<ANativeWindow> window(surface);
+    return setPreviewWindow(binder, window);
+}
+
 // set the SurfaceTexture that the preview will use
 status_t CameraService::Client::setPreviewTexture(
         const sp<ISurfaceTexture>& surfaceTexture) {
     LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(),
             getCallingPid());
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPidAndHardware();
-    if (result != NO_ERROR) return result;
 
-    // return if no change in surface.
-    // asBinder() is safe on NULL (returns NULL)
-    if (surfaceTexture->asBinder() == mSurface) {
-        return result;
-    }
-
-    if (mSurface != 0) {
-        LOG1("clearing old preview surface %p", mSurface.get());
-    }
-    mSurface = surfaceTexture->asBinder();
+    sp<IBinder> binder;
+    sp<ANativeWindow> window;
     if (surfaceTexture != 0) {
-        mPreviewWindow = new SurfaceTextureClient(surfaceTexture);
-    } else {
-        mPreviewWindow = 0;
+        binder = surfaceTexture->asBinder();
+        window = new SurfaceTextureClient(surfaceTexture);
     }
-
-    // If preview has been already started, set overlay or register preview
-    // buffers now.
-    if (mHardware->previewEnabled()) {
-        // XXX: What if the new preview window is 0?
-        if (mPreviewWindow != 0) {
-            native_window_set_buffers_transform(mPreviewWindow.get(),
-                                                mOrientation);
-            result = mHardware->setPreviewWindow(mPreviewWindow);
-        }
-    }
-
-    return result;
+    return setPreviewWindow(binder, window);
 }
 
 // set the preview callback flag to affect how the received frames from
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 5e2d571..c5fefb8 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -161,6 +161,10 @@
 
         int                     getOrientation(int orientation, bool mirror);
 
+        status_t                setPreviewWindow(
+                                    const sp<IBinder>& binder,
+                                    const sp<ANativeWindow>& window);
+
         // these are initialized in the constructor.
         sp<CameraService>               mCameraService;  // immutable after constructor
         sp<ICameraClient>               mCameraClient;
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 18d393f..2597978 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -35,6 +35,7 @@
 
 import android.app.ActivityManagerNative;
 import android.app.AlertDialog;
+import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
@@ -47,6 +48,7 @@
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
@@ -160,6 +162,7 @@
 
     // Ongoing notification
     private final NotificationManager mNotificationManager;
+    private final KeyguardManager mKeyguardManager;
     private final Notification mImeSwitcherNotification;
     private final PendingIntent mImeSwitchPendingIntent;
     private final boolean mShowOngoingImeSwitcherForPhones;
@@ -520,6 +523,8 @@
             }
         });
 
+        mKeyguardManager = (KeyguardManager)
+                mContext.getSystemService(Context.KEYGUARD_SERVICE);
         mNotificationManager = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
         mImeSwitcherNotification = new Notification();
@@ -1632,19 +1637,27 @@
     }
 
     @Override
-    public boolean setAdditionalInputMethodSubtypes(IBinder token, InputMethodSubtype[] subtypes) {
-        if (token == null || mCurToken != token) {
-            return false;
-        }
-        if (subtypes == null || subtypes.length == 0) return false;
+    public boolean setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {
+        // By this IPC call, only a process which shares the same uid with the IME can add
+        // additional input method subtypes to the IME.
+        if (TextUtils.isEmpty(imiId) || subtypes == null || subtypes.length == 0) return false;
         synchronized (mMethodMap) {
-            final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+            final InputMethodInfo imi = mMethodMap.get(imiId);
             if (imi == null) return false;
-            final int N = subtypes.length;
-            mFileManager.addInputMethodSubtypes(imi, subtypes);
-            buildInputMethodListLocked(mMethodList, mMethodMap);
-            return true;
+            final PackageManager pm = mContext.getPackageManager();
+            final String[] packageInfos = pm.getPackagesForUid(Binder.getCallingUid());
+            if (packageInfos != null) {
+                final int packageNum = packageInfos.length;
+                for (int i = 0; i < packageNum; ++i) {
+                    if (packageInfos[i].equals(imi.getPackageName())) {
+                        mFileManager.addInputMethodSubtypes(imi, subtypes);
+                        buildInputMethodListLocked(mMethodList, mMethodMap);
+                        return true;
+                    }
+                }
+            }
         }
+        return false;
     }
 
     private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) {
@@ -2118,7 +2131,8 @@
                         }
                     });
 
-            if (showSubtypes) {
+            if (showSubtypes && !(mKeyguardManager.isKeyguardLocked()
+                    && mKeyguardManager.isKeyguardSecure())) {
                 mDialogBuilder.setPositiveButton(
                         com.android.internal.R.string.configure_input_methods,
                         new DialogInterface.OnClickListener() {
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index 3139798..c80cd0a 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -473,10 +473,7 @@
                 case MSG_SET_CURRENT_FUNCTION:
                     String function = (String)msg.obj;
                     boolean makeDefault = (msg.arg1 == 1);
-                    if (makeDefault) {
-                        if (function == null) {
-                            throw new NullPointerException();
-                        }
+                    if (function != null && makeDefault) {
                         if (mAdbEnabled) {
                             function = addFunction(function, UsbManager.USB_FUNCTION_ADB);
                         }
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index 118cd55..8146fca 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -51,6 +51,8 @@
     float mCurrentX, mCurrentY;
     float mThumbOffsetX, mThumbOffsetY;
     InputChannel mServerChannel, mClientChannel;
+    InputApplicationHandle mDragApplicationHandle;
+    InputWindowHandle mDragWindowHandle;
     WindowState mTargetWindow;
     ArrayList<WindowState> mNotifiedWindows;
     boolean mDragInProgress;
@@ -91,6 +93,38 @@
             mService.mInputManager.registerInputChannel(mServerChannel, null);
             InputQueue.registerInputChannel(mClientChannel, mService.mDragInputHandler,
                     mService.mH.getLooper().getQueue());
+
+            mDragApplicationHandle = new InputApplicationHandle(null);
+            mDragApplicationHandle.name = "drag";
+            mDragApplicationHandle.dispatchingTimeoutNanos =
+                    WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+
+            mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null);
+            mDragWindowHandle.name = "drag";
+            mDragWindowHandle.inputChannel = mServerChannel;
+            mDragWindowHandle.layer = getDragLayerLw();
+            mDragWindowHandle.layoutParamsFlags = 0;
+            mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
+            mDragWindowHandle.dispatchingTimeoutNanos =
+                    WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
+            mDragWindowHandle.visible = true;
+            mDragWindowHandle.canReceiveKeys = false;
+            mDragWindowHandle.hasFocus = true;
+            mDragWindowHandle.hasWallpaper = false;
+            mDragWindowHandle.paused = false;
+            mDragWindowHandle.ownerPid = Process.myPid();
+            mDragWindowHandle.ownerUid = Process.myUid();
+            mDragWindowHandle.inputFeatures = 0;
+            mDragWindowHandle.scaleFactor = 1.0f;
+
+            // The drag window cannot receive new touches.
+            mDragWindowHandle.touchableRegion.setEmpty();
+
+            // The drag window covers the entire display
+            mDragWindowHandle.frameLeft = 0;
+            mDragWindowHandle.frameTop = 0;
+            mDragWindowHandle.frameRight = mService.mDisplay.getRealWidth();
+            mDragWindowHandle.frameBottom = mService.mDisplay.getRealHeight();
         }
     }
 
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 08a3560..12ef238 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -42,10 +42,6 @@
     // When true, need to call updateInputWindowsLw().
     private boolean mUpdateInputWindowsNeeded = true;
 
-    // Fake handles for the drag surface, lazily initialized.
-    private InputApplicationHandle mDragApplicationHandle;
-    private InputWindowHandle mDragWindowHandle;
-
     // Array of window handles to provide to the input dispatcher.
     private InputWindowHandle[] mInputWindowHandles;
     private int mInputWindowHandleCount;
@@ -121,44 +117,6 @@
         return 0; // abort dispatching
     }
 
-    private void addDragInputWindowLw() {
-        if (mDragWindowHandle == null) {
-            mDragApplicationHandle = new InputApplicationHandle(null);
-            mDragApplicationHandle.name = "drag";
-            mDragApplicationHandle.dispatchingTimeoutNanos =
-                    WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
-
-            mDragWindowHandle = new InputWindowHandle(mDragApplicationHandle, null);
-            mDragWindowHandle.name = "drag";
-            mDragWindowHandle.layoutParamsFlags = 0;
-            mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
-            mDragWindowHandle.dispatchingTimeoutNanos =
-                    WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
-            mDragWindowHandle.visible = true;
-            mDragWindowHandle.canReceiveKeys = false;
-            mDragWindowHandle.hasFocus = true;
-            mDragWindowHandle.hasWallpaper = false;
-            mDragWindowHandle.paused = false;
-            mDragWindowHandle.ownerPid = Process.myPid();
-            mDragWindowHandle.ownerUid = Process.myUid();
-            mDragWindowHandle.inputFeatures = 0;
-            mDragWindowHandle.scaleFactor = 1.0f;
-
-            // The drag window cannot receive new touches.
-            mDragWindowHandle.touchableRegion.setEmpty();
-        }
-
-        mDragWindowHandle.layer = mService.mDragState.getDragLayerLw();
-
-        // The drag window covers the entire display
-        mDragWindowHandle.frameLeft = 0;
-        mDragWindowHandle.frameTop = 0;
-        mDragWindowHandle.frameRight = mService.mDisplay.getRealWidth();
-        mDragWindowHandle.frameBottom = mService.mDisplay.getRealHeight();
-
-        addInputWindowHandleLw(mDragWindowHandle);
-    }
-
     private void addInputWindowHandleLw(InputWindowHandle windowHandle) {
         if (mInputWindowHandles == null) {
             mInputWindowHandles = new InputWindowHandle[16];
@@ -202,7 +160,7 @@
             if (WindowManagerService.DEBUG_DRAG) {
                 Log.d(WindowManagerService.TAG, "Inserting drag window");
             }
-            addDragInputWindowLw();
+            addInputWindowHandleLw(mService.mDragState.mDragWindowHandle);
         }
 
         final int N = windows.size();
@@ -429,4 +387,4 @@
     private void updateInputDispatchModeLw() {
         mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
     }
-}
\ No newline at end of file
+}
diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java
index 8427d14..f0d2fba 100644
--- a/telephony/java/com/android/internal/telephony/BaseCommands.java
+++ b/telephony/java/com/android/internal/telephony/BaseCommands.java
@@ -857,22 +857,28 @@
      */
     public static int getLteOnCdmaModeStatic() {
         int retVal;
-        String productType;
+        int curVal;
+        String productType = "";
 
-        Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
-        if (matcher.find()) {
-            productType = matcher.group(1);
-            if (sLteOnCdmaProductType.equals(productType)) {
-                retVal = Phone.LTE_ON_CDMA_TRUE;
+        curVal = SystemProperties.getInt(TelephonyProperties.PROPERTY_LTE_ON_CDMA_DEVICE,
+                    Phone.LTE_ON_CDMA_UNKNOWN);
+        retVal = curVal;
+        if (retVal == Phone.LTE_ON_CDMA_UNKNOWN) {
+            Matcher matcher = sProductTypePattern.matcher(sKernelCmdLine);
+            if (matcher.find()) {
+                productType = matcher.group(1);
+                if (sLteOnCdmaProductType.equals(productType)) {
+                    retVal = Phone.LTE_ON_CDMA_TRUE;
+                } else {
+                    retVal = Phone.LTE_ON_CDMA_FALSE;
+                }
             } else {
                 retVal = Phone.LTE_ON_CDMA_FALSE;
             }
-        } else {
-            retVal = Phone.LTE_ON_CDMA_FALSE;
-            productType = "";
         }
 
-        Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " product_type='" + productType +
+        Log.d(LOG_TAG, "getLteOnCdmaMode=" + retVal + " curVal=" + curVal +
+                " product_type='" + productType +
                 "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'");
         return retVal;
     }
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index 60cf9b7..abb4523 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -79,6 +79,15 @@
      */
     static final String PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE = "telephony.lteOnCdmaProductType";
 
+    /**
+     * The contents of this property is the one of {@link Phone#LTE_ON_CDMA_TRUE} or
+     * {@link Phone#LTE_ON_CDMA_FALSE}. If absent the value will assumed to be false
+     * and the {@see #PROPERTY_LTE_ON_CDMA_PRODUCT_TYPE} will be used to determine its
+     * final value which could also be {@link Phone#LTE_ON_CDMA_FALSE}.
+     * {@see BaseCommands#getLteOnCdmaMode()}
+     */
+    static final String PROPERTY_LTE_ON_CDMA_DEVICE = "telephony.lteOnCdmaDevice";
+
     static final String CURRENT_ACTIVE_PHONE = "gsm.current.phone-type";
 
     //****** SIM Card
diff --git a/tests/BiDiTests/res/layout/canvas2.xml b/tests/BiDiTests/res/layout/canvas2.xml
new file mode 100644
index 0000000..b3e038f
--- /dev/null
+++ b/tests/BiDiTests/res/layout/canvas2.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/canvas2"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent">
+
+    <LinearLayout
+        xmlns:local="http://schemas.android.com/apk/res/com.android.bidi"
+        android:orientation="vertical"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent">
+
+        <TextView
+            android:text="@string/ltr"
+            android:textSize="40dip"
+            android:gravity="center"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content" />
+
+        <com.android.bidi.BiDiTestViewDrawText
+            local:text="@string/ltr"
+            android:layout_width="fill_parent"
+            android:layout_height="64dp" />
+
+        <TextView
+            android:text="@string/rtl"
+            android:textSize="40dip"
+            android:gravity="center"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+
+        <com.android.bidi.BiDiTestViewDrawText
+            local:text="@string/rtl"
+            android:layout_width="fill_parent"
+            android:layout_height="64dp" />
+
+        <TextView
+            android:text="@string/composing"
+            android:textSize="40dip"
+            android:gravity="center"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"/>
+
+        <com.android.bidi.BiDiTestViewDrawText
+            local:text="@string/composing"
+            android:layout_width="fill_parent"
+            android:layout_height="64dp" />
+
+    </LinearLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/BiDiTests/res/values/attrs.xml b/tests/BiDiTests/res/values/attrs.xml
new file mode 100644
index 0000000..7f8a1d8
--- /dev/null
+++ b/tests/BiDiTests/res/values/attrs.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <declare-styleable name="DrawTextTestView">
+        <attr name="size" format="dimension" />
+        <attr name="color" format="color" />
+        <attr name="text" format="string" />
+    </declare-styleable>
+</resources>
\ No newline at end of file
diff --git a/tests/BiDiTests/res/values/strings.xml b/tests/BiDiTests/res/values/strings.xml
index bc99e79..1f6be7f 100644
--- a/tests/BiDiTests/res/values/strings.xml
+++ b/tests/BiDiTests/res/values/strings.xml
@@ -42,5 +42,8 @@
     <string name="textview_hebrew_text">&#x05DD;&#x05DE;ab?!</string>
     <string name="textview_latin_text">ab&#x05DD;&#x05DE;?!</string>
     <string name="textview_multiline_text">&#x05DD;&#x05DE;?!\nab?!\n?!</string>
+    <string name="ltr">Left to right text"</string>
+    <string name="rtl">"والحق أن تترك ونص"</string>
+    <string name="composing">"\u0644\u0627"</string>
 </resources>
 
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
index 7002c41..6b38cc1 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
@@ -102,6 +102,7 @@
         addItem(result, "Basic", BiDiTestBasic.class, R.id.basic);
 
         addItem(result, "Canvas", BiDiTestCanvas.class, R.id.canvas);
+        addItem(result, "Canvas2", BiDiTestCanvas2.class, R.id.canvas2);
 
         addItem(result, "Linear LTR", BiDiTestLinearLayoutLtr.class, R.id.linear_layout_ltr);
         addItem(result, "Linear RTL", BiDiTestLinearLayoutRtl.class, R.id.linear_layout_rtl);
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvas2.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvas2.java
new file mode 100644
index 0000000..b801f0e
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestCanvas2.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 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.bidi;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.SeekBar;
+
+import static com.android.bidi.BiDiTestConstants.FONT_MAX_SIZE;
+import static com.android.bidi.BiDiTestConstants.FONT_MIN_SIZE;
+
+public class BiDiTestCanvas2 extends Fragment {
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.canvas2, container, false);
+    }
+}
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java
index 27e1887..0126dea 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestView.java
@@ -21,7 +21,7 @@
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
-import android.graphics.Typeface;
+import android.text.TextPaint;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.View;
@@ -37,7 +37,6 @@
 
     private static final float DEFAULT_ITALIC_SKEW_X = -0.25f;
 
-    private Paint paint = new Paint();
     private Rect rect = new Rect();
 
     private String NORMAL_TEXT;
@@ -51,8 +50,7 @@
     private String CHINESE_TEXT;
     private String MIXED_TEXT_1;
     private String HEBREW_TEXT;
-
-    private Typeface typeface;
+    private String RTL_TEXT;
 
     private int currentTextSize;
 
@@ -83,9 +81,7 @@
         CHINESE_TEXT = context.getString(R.string.chinese_text);
         MIXED_TEXT_1 = context.getString(R.string.mixed_text_1);
         HEBREW_TEXT = context.getString(R.string.hebrew_text);
-
-        typeface = paint.getTypeface();
-        paint.setAntiAlias(true);
+        RTL_TEXT = context.getString(R.string.rtl);
     }
 
     public void setCurrentTextSize(int size) {
@@ -95,54 +91,56 @@
 
     @Override
     public void onDraw(Canvas canvas) {
-        drawInsideRect(canvas, Color.BLACK);
+        drawInsideRect(canvas, new Paint(), Color.BLACK);
 
         int deltaX = 0;
 
         deltaX  = testString(canvas, NORMAL_TEXT, ORIGIN, ORIGIN,
-                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);
+                false, false,  Paint.DIRECTION_LTR, currentTextSize);
 
         deltaX += testString(canvas, ITALIC_TEXT, ORIGIN + deltaX, ORIGIN,
-                paint, typeface, true, false,  Paint.DIRECTION_LTR, currentTextSize);
+                true, false,  Paint.DIRECTION_LTR, currentTextSize);
 
         deltaX += testString(canvas, BOLD_TEXT, ORIGIN + deltaX, ORIGIN,
-                paint, typeface, false, true,  Paint.DIRECTION_LTR, currentTextSize);
+                false, true,  Paint.DIRECTION_LTR, currentTextSize);
 
         deltaX += testString(canvas, BOLD_ITALIC_TEXT, ORIGIN + deltaX, ORIGIN,
-                paint, typeface, true, true,  Paint.DIRECTION_LTR, currentTextSize);
+                true, true,  Paint.DIRECTION_LTR, currentTextSize);
 
         // Test with a long string
         deltaX = testString(canvas, NORMAL_LONG_TEXT, ORIGIN, ORIGIN + 2 * currentTextSize,
-                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);
+                false, false,  Paint.DIRECTION_LTR, currentTextSize);
 
         // Test with a long string
         deltaX = testString(canvas, NORMAL_LONG_TEXT_2, ORIGIN, ORIGIN + 4 * currentTextSize,
-                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);
+                false, false,  Paint.DIRECTION_LTR, currentTextSize);
 
         // Test with a long string
         deltaX = testString(canvas, NORMAL_LONG_TEXT_3, ORIGIN, ORIGIN + 6 * currentTextSize,
-                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);
+                false, false,  Paint.DIRECTION_LTR, currentTextSize);
 
         // Test Arabic ligature
         deltaX = testString(canvas, ARABIC_TEXT, ORIGIN, ORIGIN + 8 * currentTextSize,
-                paint, typeface, false, false,  Paint.DIRECTION_RTL, currentTextSize);
+                false, false,  Paint.DIRECTION_RTL, currentTextSize);
 
         // Test Chinese
         deltaX = testString(canvas, CHINESE_TEXT, ORIGIN, ORIGIN + 10 * currentTextSize,
-                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);
+                false, false,  Paint.DIRECTION_LTR, currentTextSize);
 
         // Test Mixed (English and Arabic)
         deltaX = testString(canvas, MIXED_TEXT_1, ORIGIN, ORIGIN + 12 * currentTextSize,
-                paint, typeface, false, false,  Paint.DIRECTION_LTR, currentTextSize);
+                false, false,  Paint.DIRECTION_LTR, currentTextSize);
 
         // Test Hebrew
-        deltaX = testString(canvas, HEBREW_TEXT, ORIGIN, ORIGIN + 14 * currentTextSize,
-                paint, typeface, false, false,  Paint.DIRECTION_RTL, currentTextSize);
+        deltaX = testString(canvas, RTL_TEXT, ORIGIN, ORIGIN + 14 * currentTextSize,
+                false, false,  Paint.DIRECTION_RTL, currentTextSize);
     }
 
-    private int testString(Canvas canvas, String text, int x, int y, Paint paint, Typeface typeface,
+    private int testString(Canvas canvas, String text, int x, int y,
             boolean isItalic, boolean isBold, int dir, int textSize) {
-        paint.setTypeface(typeface);
+
+        TextPaint paint = new TextPaint();
+        paint.setAntiAlias(true);
 
         // Set paint properties
         boolean oldFakeBold = paint.isFakeBoldText();
@@ -153,9 +151,9 @@
             paint.setTextSkewX(DEFAULT_ITALIC_SKEW_X);
         }
 
-        Log.v(TAG, "START -- drawTextWithCanvasDrawText");
-        drawTextWithCanvasDrawText(text, canvas, x, y, textSize, Color.WHITE, dir);
-        Log.v(TAG, "END   -- drawTextWithCanvasDrawText");
+        paint.setTextSize(textSize);
+        paint.setColor(Color.WHITE);
+        canvas.drawText(text, x, y, paint);
 
         int length = text.length();
         float[] advances = new float[length];
@@ -167,13 +165,6 @@
         logAdvances(text, textWidthHB, textWidthICU, advances);
         drawMetricsAroundText(canvas, x, y, textWidthHB, textWidthICU, textSize, Color.RED, Color.GREEN);
 
-        paint.setColor(Color.WHITE);
-
-        Log.v(TAG, "START -- drawText");
-        setPaintDir(paint, dir);
-        canvas.drawText(text, x, y + currentTextSize, this.paint);
-        Log.v(TAG, "END   -- drawText");
-
         // Restore old paint properties
         paint.setFakeBoldText(oldFakeBold);
         paint.setTextSkewX(oldTextSkewX);
@@ -186,7 +177,7 @@
         paint.setBidiFlags(dir);
     }
 
-    private void drawInsideRect(Canvas canvas, int color) {
+    private void drawInsideRect(Canvas canvas, Paint paint, int color) {
         paint.setColor(color);
         int width = getWidth();
         int height = getHeight();
@@ -194,16 +185,9 @@
         canvas.drawRect(rect, paint);
     }
 
-    private void drawTextWithCanvasDrawText(String text, Canvas canvas,
-            float x, float y, float textSize, int color, int dir) {
-        setPaintDir(paint, dir);
-        paint.setColor(color);
-        paint.setTextSize(textSize);
-        canvas.drawText(text, x, y, paint);
-    }
-
     private void drawMetricsAroundText(Canvas canvas, int x, int y, float textWidthHB,
             float textWidthICU, int textSize, int color, int colorICU) {
+        Paint paint = new Paint();
         paint.setColor(color);
         canvas.drawLine(x, y - textSize, x, y + 8, paint);
         canvas.drawLine(x, y + 8, x + textWidthHB, y + 8, paint);
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestViewDrawText.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewDrawText.java
new file mode 100644
index 0000000..dfdb807
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewDrawText.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 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.bidi;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint.Align;
+import android.text.TextPaint;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class BiDiTestViewDrawText extends View {
+    private float mSize;
+    private int mColor;
+    private String mText;
+
+    public BiDiTestViewDrawText(Context context) {
+        this(context, null);
+    }
+
+    public BiDiTestViewDrawText(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public BiDiTestViewDrawText(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                R.styleable.DrawTextTestView, defStyle, 0);
+        mSize = a.getDimension(R.styleable.DrawTextTestView_size, 40.0f);
+        mColor = a.getColor(R.styleable.DrawTextTestView_color, Color.YELLOW);
+        final CharSequence text = a.getText(R.styleable.DrawTextTestView_text);
+        mText = (text != null) ? text.toString() : "(empty)";
+        a.recycle();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        final int width = getWidth();
+        final int height = getHeight();
+
+        final TextPaint paint = new TextPaint();
+        paint.setTextSize(mSize);
+        paint.setColor(mColor);
+        paint.setTextAlign(Align.CENTER);
+
+        canvas.drawText(mText, width / 2, height * 2 / 3, paint);
+    }
+}
\ No newline at end of file
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
index af5006f..38a85a3 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
@@ -95,9 +95,7 @@
         }
         {
             Space v = new Space(context);
-            {
-                vg.addView(v, new LayoutParams(row5, col3));
-            }
+            vg.addView(v, new LayoutParams(row5, col3));
         }
         {
             Button v = new Button(context);
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 32a6a65..9fcd05a 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -94,6 +94,15 @@
         </activity>
 
         <activity
+                android:name="CanvasTextureViewActivity"
+                android:label="_CanvasTextureView">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        
+        <activity
                 android:name="GLTextureViewActivity"
                 android:label="_TextureViewGL">
             <intent-filter>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/CanvasTextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/CanvasTextureViewActivity.java
new file mode 100644
index 0000000..81c22b8
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/CanvasTextureViewActivity.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2011 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.test.hwui;
+
+import android.app.Activity;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.SurfaceTexture;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.TextureView;
+import android.widget.FrameLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class CanvasTextureViewActivity extends Activity
+        implements TextureView.SurfaceTextureListener {
+    private TextureView mTextureView;
+    private CanvasTextureViewActivity.RenderingThread mThread;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        FrameLayout content = new FrameLayout(this);
+
+        mTextureView = new TextureView(this);
+        mTextureView.setSurfaceTextureListener(this);
+        mTextureView.setOpaque(false);
+
+        content.addView(mTextureView, new FrameLayout.LayoutParams(500, 500, Gravity.CENTER));
+        setContentView(content);
+    }
+
+    @Override
+    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+        mThread = new RenderingThread(mTextureView);
+        mThread.start();
+    }
+
+    @Override
+    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+        // Ignored
+    }
+
+    @Override
+    public void onSurfaceTextureDestroyed(SurfaceTexture surface) {
+        if (mThread != null) mThread.stopRendering();
+    }
+
+    @Override
+    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+        // Ignored
+    }
+
+    private static class RenderingThread extends Thread {
+        private final TextureView mSurface;
+        private volatile boolean mRunning = true;
+
+        public RenderingThread(TextureView surface) {
+            mSurface = surface;
+        }
+
+        @Override
+        public void run() {
+            float x = 0.0f;
+            float y = 0.0f;
+            float speedX = 5.0f;
+            float speedY = 3.0f;
+            
+            Paint paint = new Paint();
+            paint.setColor(0xff00ff00);
+
+            while (mRunning && !Thread.interrupted()) {
+                final Canvas canvas = mSurface.lockCanvas(null);
+                try {
+                    canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
+                    canvas.drawRect(x, y, x + 20.0f, y + 20.0f, paint);
+                } finally {
+                    mSurface.unlockCanvasAndPost(canvas);
+                }
+
+                if (x + 20.0f + speedX >= mSurface.getWidth() || x + speedX <= 0.0f) {
+                    speedX = -speedX;
+                }
+                if (y + 20.0f + speedY >= mSurface.getHeight() || y + speedY <= 0.0f) {
+                    speedY = -speedY;
+                }
+
+                x += speedX;
+                y += speedY;
+
+                try {
+                    Thread.sleep(15);
+                } catch (InterruptedException e) {
+                    // Interrupted
+                }
+            }
+        }
+        
+        void stopRendering() {
+            interrupt();
+            mRunning = false;
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
index 1394c32..2519ebc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeIInputMethodManager.java
@@ -107,7 +107,7 @@
 
     }
 
-    public boolean setAdditionalInputMethodSubtypes(IBinder arg0, InputMethodSubtype[] arg1)
+    public boolean setAdditionalInputMethodSubtypes(String arg0, InputMethodSubtype[] arg1)
             throws RemoteException {
         // TODO Auto-generated method stub
         return false;