Merge "Disable flaky streaming server check"
diff --git a/api/current.xml b/api/current.xml
index 8a5e0d6..e022092 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -8501,6 +8501,17 @@
  visibility="public"
 >
 </field>
+<field name="state_accelerated"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843564"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="state_activated"
  type="int"
  transient="false"
@@ -14645,6 +14656,17 @@
  visibility="public"
 >
 </field>
+<field name="Theme_Holo_Light_DialogWhenLarge"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973955"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="Theme_Holo_Light_Dialog_Alert"
  type="int"
  transient="false"
@@ -222247,6 +222269,101 @@
 </parameter>
 </method>
 </interface>
+<class name="WebResourceResponse"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="WebResourceResponse"
+ type="android.webkit.WebResourceResponse"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mimeType" type="java.lang.String">
+</parameter>
+<parameter name="encoding" type="java.lang.String">
+</parameter>
+<parameter name="data" type="java.io.InputStream">
+</parameter>
+</constructor>
+<method name="getData"
+ return="java.io.InputStream"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEncoding"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMimeType"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setData"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="java.io.InputStream">
+</parameter>
+</method>
+<method name="setEncoding"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="encoding" type="java.lang.String">
+</parameter>
+</method>
+<method name="setMimeType"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mimeType" type="java.lang.String">
+</parameter>
+</method>
+</class>
 <class name="WebSettings"
  extends="java.lang.Object"
  abstract="false"
@@ -225336,6 +225453,21 @@
 <parameter name="event" type="android.view.KeyEvent">
 </parameter>
 </method>
+<method name="shouldInterceptRequest"
+ return="android.webkit.WebResourceResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.webkit.WebView">
+</parameter>
+<parameter name="url" type="java.lang.String">
+</parameter>
+</method>
 <method name="shouldOverrideKeyEvent"
  return="boolean"
  abstract="false"
@@ -246551,7 +246683,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
 </parameter>
 </method>
 </interface>
diff --git a/core/java/android/net/http/Connection.java b/core/java/android/net/http/Connection.java
index 43fb5f1..95cecd2 100644
--- a/core/java/android/net/http/Connection.java
+++ b/core/java/android/net/http/Connection.java
@@ -437,8 +437,7 @@
             ret = false;
             String error;
             if (errorId < 0) {
-                error = mContext.getText(
-                        EventHandler.errorStringResources[-errorId]).toString();
+                error = ErrorStrings.getString(errorId, mContext);
             } else {
                 Throwable cause = e.getCause();
                 error = cause != null ? cause.toString() : e.getMessage();
diff --git a/core/java/android/net/http/ErrorStrings.java b/core/java/android/net/http/ErrorStrings.java
new file mode 100644
index 0000000..8383681
--- /dev/null
+++ b/core/java/android/net/http/ErrorStrings.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.net.http;
+
+import android.content.Context;
+import android.util.Log;
+
+/**
+ * Localized strings for the error codes defined in EventHandler.
+ *
+ * {@hide}
+ */
+public class ErrorStrings {
+    private ErrorStrings() { /* Utility class, don't instantiate. */ }
+
+    private static final String LOGTAG = "Http";
+
+    /**
+     * Get the localized error message resource for the given error code.
+     * If the code is unknown, we'll return a generic error message.
+     */
+    public static String getString(int errorCode, Context context) {
+        return context.getText(getResource(errorCode)).toString();
+    }
+
+    /**
+     * Get the localized error message resource for the given error code.
+     * If the code is unknown, we'll return a generic error message.
+     */
+    public static int getResource(int errorCode) {
+        switch(errorCode) {
+            case EventHandler.OK:
+                return com.android.internal.R.string.httpErrorOk;
+
+            case EventHandler.ERROR:
+                return com.android.internal.R.string.httpError;
+
+            case EventHandler.ERROR_LOOKUP:
+                return com.android.internal.R.string.httpErrorLookup;
+
+            case EventHandler.ERROR_UNSUPPORTED_AUTH_SCHEME:
+                return com.android.internal.R.string.httpErrorUnsupportedAuthScheme;
+
+            case EventHandler.ERROR_AUTH:
+                return com.android.internal.R.string.httpErrorAuth;
+
+            case EventHandler.ERROR_PROXYAUTH:
+                return com.android.internal.R.string.httpErrorProxyAuth;
+
+            case EventHandler.ERROR_CONNECT:
+                return com.android.internal.R.string.httpErrorConnect;
+
+            case EventHandler.ERROR_IO:
+                return com.android.internal.R.string.httpErrorIO;
+
+            case EventHandler.ERROR_TIMEOUT:
+                return com.android.internal.R.string.httpErrorTimeout;
+
+            case EventHandler.ERROR_REDIRECT_LOOP:
+                return com.android.internal.R.string.httpErrorRedirectLoop;
+
+            case EventHandler.ERROR_UNSUPPORTED_SCHEME:
+                return com.android.internal.R.string.httpErrorUnsupportedScheme;
+
+            case EventHandler.ERROR_FAILED_SSL_HANDSHAKE:
+                return com.android.internal.R.string.httpErrorFailedSslHandshake;
+
+            case EventHandler.ERROR_BAD_URL:
+                return com.android.internal.R.string.httpErrorBadUrl;
+
+            case EventHandler.FILE_ERROR:
+                return com.android.internal.R.string.httpErrorFile;
+
+            case EventHandler.FILE_NOT_FOUND_ERROR:
+                return com.android.internal.R.string.httpErrorFileNotFound;
+
+            case EventHandler.TOO_MANY_REQUESTS_ERROR:
+                return com.android.internal.R.string.httpErrorTooManyRequests;
+
+            default:
+                Log.w(LOGTAG, "Using generic message for unknown error code: " + errorCode);
+                return com.android.internal.R.string.httpError;
+        }
+    }
+}
diff --git a/core/java/android/net/http/EventHandler.java b/core/java/android/net/http/EventHandler.java
index 2aa05eb..3fd471d 100644
--- a/core/java/android/net/http/EventHandler.java
+++ b/core/java/android/net/http/EventHandler.java
@@ -68,25 +68,6 @@
     /** Too many requests queued */
     public static final int TOO_MANY_REQUESTS_ERROR = -15;
 
-    final static int[] errorStringResources = {
-        com.android.internal.R.string.httpErrorOk,
-        com.android.internal.R.string.httpError,
-        com.android.internal.R.string.httpErrorLookup,
-        com.android.internal.R.string.httpErrorUnsupportedAuthScheme,
-        com.android.internal.R.string.httpErrorAuth,
-        com.android.internal.R.string.httpErrorProxyAuth,
-        com.android.internal.R.string.httpErrorConnect,
-        com.android.internal.R.string.httpErrorIO,
-        com.android.internal.R.string.httpErrorTimeout,
-        com.android.internal.R.string.httpErrorRedirectLoop,
-        com.android.internal.R.string.httpErrorUnsupportedScheme,
-        com.android.internal.R.string.httpErrorFailedSslHandshake,
-        com.android.internal.R.string.httpErrorBadUrl,
-        com.android.internal.R.string.httpErrorFile,
-        com.android.internal.R.string.httpErrorFileNotFound,
-        com.android.internal.R.string.httpErrorTooManyRequests
-    };
-
     /**
      * Called after status line has been sucessfully processed.
      * @param major_version HTTP version advertised by server.  major
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 22876c0..8762512 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -605,7 +605,7 @@
 
     // Sets up CloseGuard in Dalvik/libcore
     private static void setCloseGuardEnabled(boolean enabled) {
-        if (!(CloseGuard.getReporter() instanceof AndroidBlockGuardPolicy)) {
+        if (!(CloseGuard.getReporter() instanceof AndroidCloseGuardReporter)) {
             CloseGuard.setReporter(new AndroidCloseGuardReporter());
         }
         CloseGuard.setEnabled(enabled);
@@ -694,6 +694,7 @@
         // For debug builds, log event loop stalls to dropbox for analysis.
         // Similar logic also appears in ActivityThread.java for system apps.
         if ("user".equals(Build.TYPE)) {
+            setCloseGuardEnabled(false);
             return false;
         }
         StrictMode.setThreadPolicyMask(
@@ -705,6 +706,7 @@
                 StrictMode.DETECT_VM_CLOSABLE_LEAKS |
                 StrictMode.PENALTY_DROPBOX |
                 StrictMode.PENALTY_LOG;
+        setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
         return true;
     }
 
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index a54f342..dd0f477 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -79,7 +79,7 @@
     void executeAppTransition();
     void setAppStartingWindow(IBinder token, String pkg, int theme,
             CharSequence nonLocalizedLabel, int labelRes,
-            int icon, IBinder transferFrom, boolean createIfNeeded);
+            int icon, int windowFlags, IBinder transferFrom, boolean createIfNeeded);
     void setAppWillBeHidden(IBinder token);
     void setAppVisibility(IBinder token, boolean visible);
     void startAppFreezingScreen(IBinder token, int configChanges);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 026f1a0..be49255 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1258,6 +1258,7 @@
     static final int VIEW_STATE_ENABLED = 1 << 3;
     static final int VIEW_STATE_PRESSED = 1 << 4;
     static final int VIEW_STATE_ACTIVATED = 1 << 5;
+    static final int VIEW_STATE_ACCELERATED = 1 << 6;
 
     static final int[] VIEW_STATE_IDS = new int[] {
         R.attr.state_window_focused,    VIEW_STATE_WINDOW_FOCUSED,
@@ -1266,9 +1267,14 @@
         R.attr.state_enabled,           VIEW_STATE_ENABLED,
         R.attr.state_pressed,           VIEW_STATE_PRESSED,
         R.attr.state_activated,         VIEW_STATE_ACTIVATED,
+        R.attr.state_accelerated,       VIEW_STATE_ACCELERATED,
     };
 
     static {
+        if ((VIEW_STATE_IDS.length/2) != R.styleable.ViewDrawableStates.length) {
+            throw new IllegalStateException(
+                    "VIEW_STATE_IDs array length does not match ViewDrawableStates style array");
+        }
         int[] orderedIds = new int[VIEW_STATE_IDS.length];
         for (int i = 0; i < R.styleable.ViewDrawableStates.length; i++) {
             int viewState = R.styleable.ViewDrawableStates[i];
@@ -7176,6 +7182,8 @@
         //System.out.println("Attached! " + this);
         mAttachInfo = info;
         mWindowAttachCount++;
+        // We will need to evaluate the drawable state at least once.
+        mPrivateFlags |= DRAWABLE_STATE_DIRTY;
         if (mFloatingTreeObserver != null) {
             info.mTreeObserver.merge(mFloatingTreeObserver);
             mFloatingTreeObserver = null;
@@ -7190,6 +7198,10 @@
         if (vis != GONE) {
             onWindowVisibilityChanged(vis);
         }
+        if ((mPrivateFlags&DRAWABLE_STATE_DIRTY) != 0) {
+            // If nobody has evaluated the drawable state yet, then do it now.
+            refreshDrawableState();
+        }
     }
 
     void dispatchDetachedFromWindow() {
@@ -8562,6 +8574,12 @@
         if ((privateFlags & SELECTED) != 0) viewStateIndex |= VIEW_STATE_SELECTED;
         if (hasWindowFocus()) viewStateIndex |= VIEW_STATE_WINDOW_FOCUSED;
         if ((privateFlags & ACTIVATED) != 0) viewStateIndex |= VIEW_STATE_ACTIVATED;
+        if (mAttachInfo != null && mAttachInfo.mHardwareAccelerationRequested) {
+            // This is set if HW acceleration is requested, even if the current
+            // process doesn't allow it.  This is just to allow app preview
+            // windows to better match their app.
+            viewStateIndex |= VIEW_STATE_ACCELERATED;
+        }
 
         drawableState = VIEW_STATE_SETS[viewStateIndex];
 
@@ -10503,6 +10521,7 @@
         Surface mSurface;
 
         boolean mHardwareAccelerated;
+        boolean mHardwareAccelerationRequested;
         HardwareRenderer mHardwareRenderer;
         
         /**
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index e04916f..1972692 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -467,19 +467,25 @@
     }
 
     private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
-        // Only enable hardware acceleration if we are not in the system process
-        // The window manager creates ViewRoots to display animated preview windows
-        // of launching apps and we don't want those to be hardware accelerated
-        if (!HardwareRenderer.sRendererDisabled) {
-            // Try to enable hardware acceleration if requested
-            if (attrs != null &&
-                    (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) {
+        mAttachInfo.mHardwareAccelerated = false;
+        mAttachInfo.mHardwareAccelerationRequested = false;
+        
+        // Try to enable hardware acceleration if requested
+        if (attrs != null &&
+                (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) {
+            // Only enable hardware acceleration if we are not in the system process
+            // The window manager creates ViewRoots to display animated preview windows
+            // of launching apps and we don't want those to be hardware accelerated
+            if (!HardwareRenderer.sRendererDisabled) {
                 final boolean translucent = attrs.format != PixelFormat.OPAQUE;
                 if (mAttachInfo.mHardwareRenderer != null) {
                     mAttachInfo.mHardwareRenderer.destroy(true);
                 }                
                 mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);
-                mAttachInfo.mHardwareAccelerated = mAttachInfo.mHardwareRenderer != null;
+                mAttachInfo.mHardwareAccelerated = mAttachInfo.mHardwareAccelerationRequested
+                        = mAttachInfo.mHardwareRenderer != null;
+            } else if (HardwareRenderer.isAvailable()) {
+                mAttachInfo.mHardwareAccelerationRequested = true;
             }
         }
     }
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 9fadc58..d5d9a2e 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -428,6 +428,10 @@
             mHardwareAccelerated = hardwareAccelerated;
         }
 
+        public boolean isHardwareAccelerated() {
+            return mHardwareAccelerated;
+        }
+        
         public final void addView(View view, ViewGroup.LayoutParams params) {
             // Let this throw an exception on a bad params.
             WindowManager.LayoutParams wp = (WindowManager.LayoutParams)params;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c657a1c..f9e7d18 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -65,6 +65,14 @@
      */
     public void removeViewImmediate(View view);
     
+    /**
+     * Return true if this window manager is configured to request hardware
+     * accelerated windows.  This does <em>not</em> guarantee that they will
+     * actually be accelerated, since that depends on the device supporting them.
+     * @hide
+     */
+    public boolean isHardwareAccelerated();
+    
     public static class LayoutParams extends ViewGroup.LayoutParams
             implements Parcelable {
         /**
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 0973599..07953d6 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -80,6 +80,10 @@
         return mWindowManager;
     }
     
+    public boolean isHardwareAccelerated() {
+        return false;
+    }
+    
     public void addView(View view)
     {
         addView(view, new WindowManager.LayoutParams(
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 4deff5e..5a9cd97 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -473,6 +473,7 @@
      *        no data is found in the resource.
      * @param labelRes The resource ID the application would like to use as its name.
      * @param icon The resource ID the application would like to use as its icon.
+     * @param windowFlags Window layout flags.
      * 
      * @return Optionally you can return the View that was used to create the
      *         window, for easy removal in removeStartingWindow.
@@ -481,7 +482,7 @@
      */
     public View addStartingWindow(IBinder appToken, String packageName,
             int theme, CharSequence nonLocalizedLabel,
-            int labelRes, int icon);
+            int labelRes, int icon, int windowFlags);
 
     /**
      * Called when the first window of an application has been displayed, while
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index cce7914..d3c0ffd 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -26,6 +26,7 @@
 import android.net.ParseException;
 import android.net.Uri;
 import android.net.WebAddress;
+import android.net.http.ErrorStrings;
 import android.net.http.SslCertificate;
 import android.os.Handler;
 import android.os.Message;
@@ -323,16 +324,20 @@
      * native callback
      * Report an error to an activity.
      * @param errorCode The HTTP error code.
-     * @param description A String description.
+     * @param description Optional human-readable description. If no description
+     *     is given, we'll use a standard localized error message.
+     * @param failingUrl The URL that was being loaded when the error occurred.
      * TODO: Report all errors including resource errors but include some kind
      * of domain identifier. Change errorCode to an enum for a cleaner
      * interface.
      */
-    private void reportError(final int errorCode, final String description,
-            final String failingUrl) {
+    private void reportError(int errorCode, String description, String failingUrl) {
         // As this is called for the main resource and loading will be stopped
         // after, reset the state variables.
         resetLoadingStates();
+        if (description == null || description.isEmpty()) {
+            description = ErrorStrings.getString(errorCode, mContext);
+        }
         mCallbackProxy.onReceivedError(errorCode, description, failingUrl);
     }
 
@@ -649,23 +654,6 @@
     }
 
     /**
-     * Called by JNI.
-     * Read from an InputStream into a supplied byte[]
-     * This method catches any exceptions so they don't crash the JVM.
-     * @param inputStream InputStream to read from.
-     * @param output Bytearray that gets the output.
-     * @return the number of bytes read, or -i if then end of stream has been reached
-     */
-    private static int readFromStream(InputStream inputStream, byte[] output) {
-        try {
-            return inputStream.read(output);
-        } catch(java.io.IOException e) {
-            // If we get an exception, return end of stream
-            return -1;
-        }
-    }
-
-    /**
      * Get the InputStream for an Android resource
      * There are three different kinds of android resources:
      * - file:///android_res
@@ -854,8 +842,6 @@
                 this, url, loaderHandle, synchronous, isMainFramePage,
                 mainResource, userGesture, postDataIdentifier, username, password);
 
-        mCallbackProxy.onLoadResource(url);
-
         if (LoadListener.getNativeLoaderCount() > MAX_OUTSTANDING_REQUESTS) {
             // send an error message, so that loadListener can be deleted
             // after this is returned. This is important as LoadListener's 
@@ -867,7 +853,11 @@
             return loadListener;
         }
 
-        FrameLoader loader = new FrameLoader(loadListener, mSettings, method);
+        // Note that we are intentionally skipping
+        // inputStreamForAndroidResource.  This is so that FrameLoader will use
+        // the various StreamLoader classes to handle assets.
+        FrameLoader loader = new FrameLoader(loadListener, mSettings, method,
+                mCallbackProxy.shouldInterceptRequest(url));
         loader.setHeaders(headers);
         loader.setPostData(postData);
         // Set the load mode to the mode used for the current page.
@@ -884,6 +874,15 @@
         return !synchronous ? loadListener : null;
     }
 
+    // Called by jni from the chrome network stack.
+    private WebResourceResponse shouldInterceptRequest(String url) {
+        InputStream androidResource = inputStreamForAndroidResource(url);
+        if (androidResource != null) {
+            return new WebResourceResponse(null, null, androidResource);
+        }
+        return mCallbackProxy.shouldInterceptRequest(url);
+    }
+
     /**
      * Set the progress for the browser activity.  Called by native code.
      * Uses a delay so it does not happen too often.
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 0078e7a..160fc2e 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -1008,13 +1008,17 @@
         sendMessage(obtainMessage(UPDATE_VISITED, isReload ? 1 : 0, 0, url));
     }
 
-    public void onLoadResource(String url) {
-        // Do an unsynchronized quick check to avoid posting if no callback has
-        // been set.
+    WebResourceResponse shouldInterceptRequest(String url) {
         if (mWebViewClient == null) {
-            return;
+            return null;
         }
-        sendMessage(obtainMessage(LOAD_RESOURCE, url));
+        // Note: This method does _not_ send a message.
+        WebResourceResponse r =
+                mWebViewClient.shouldInterceptRequest(mWebView, url);
+        if (r == null) {
+            sendMessage(obtainMessage(LOAD_RESOURCE, url));
+        }
+        return r;
     }
 
     public void onUnhandledKeyEvent(KeyEvent event) {
diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java
index 021b53c..951dab3 100644
--- a/core/java/android/webkit/FrameLoader.java
+++ b/core/java/android/webkit/FrameLoader.java
@@ -16,6 +16,7 @@
 
 package android.webkit;
 
+import android.net.http.ErrorStrings;
 import android.net.http.EventHandler;
 import android.net.http.RequestHandle;
 import android.os.Build;
@@ -37,6 +38,7 @@
     private String mReferrer;
     private String mContentType;
     private final String mUaprofHeader;
+    private final WebResourceResponse mInterceptResponse;
 
     private static final int URI_PROTOCOL = 0x100;
 
@@ -53,12 +55,13 @@
     private static final String LOGTAG = "webkit";
     
     FrameLoader(LoadListener listener, WebSettings settings,
-            String method) {
+            String method, WebResourceResponse interceptResponse) {
         mListener = listener;
         mHeaders = null;
         mMethod = method;
         mCacheMode = WebSettings.LOAD_NORMAL;
         mSettings = settings;
+        mInterceptResponse = interceptResponse;
         mUaprofHeader = mListener.getContext().getResources().getString(
                 com.android.internal.R.string.config_useragentprofile_url, Build.MODEL);
     }
@@ -99,7 +102,17 @@
     public boolean executeLoad() {
         String url = mListener.url();
 
-        if (URLUtil.isNetworkUrl(url)){
+        // Process intercepted requests first as they could be any url.
+        if (mInterceptResponse != null) {
+            if (mListener.isSynchronous()) {
+                mInterceptResponse.loader(mListener).load();
+            } else {
+                WebViewWorker.getHandler().obtainMessage(
+                        WebViewWorker.MSG_ADD_STREAMLOADER,
+                        mInterceptResponse.loader(mListener)).sendToTarget();
+            }
+            return true;
+        } else if (URLUtil.isNetworkUrl(url)){
             if (mSettings.getBlockNetworkLoads()) {
                 mListener.error(EventHandler.ERROR_BAD_URL,
                         mListener.getContext().getString(
@@ -247,8 +260,7 @@
             error = EventHandler.ERROR_BAD_URL;
         }
         if (!ret) {
-            mListener.error(error, mListener.getContext().getText(
-                    EventHandler.errorStringResources[Math.abs(error)]).toString());
+            mListener.error(error, ErrorStrings.getString(error, mListener.getContext()));
             return false;
         }
         return true;
@@ -303,9 +315,8 @@
                     // it has gone.
                     // Generate a file not found error
                     int err = EventHandler.FILE_NOT_FOUND_ERROR;
-                    mListener.error(err, mListener.getContext().getText(
-                            EventHandler.errorStringResources[Math.abs(err)])
-                            .toString());
+                    mListener.error(err,
+                            ErrorStrings.getString(err, mListener.getContext()));
                 }
                 return true;
             }
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 33f5655..a29299d 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -836,8 +836,7 @@
             mRequestHandle.handleSslErrorResponse(proceed);
         }
         if (!proceed) {
-            // Commit whatever data we have and tear down the loader.
-            commitLoad();
+            mBrowserFrame.stopLoading();
             tearDown();
         }
     }
diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java
new file mode 100644
index 0000000..e786838
--- /dev/null
+++ b/core/java/android/webkit/WebResourceResponse.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.webkit;
+
+import android.net.http.Headers;
+
+import java.io.InputStream;
+
+/**
+ * A WebResourceResponse is return by
+ * {@link WebViewClient#shouldInterceptRequest} and
+ * contains the response information for a particular resource.
+ */
+public class WebResourceResponse {
+
+    private class Loader extends StreamLoader {
+        Loader(LoadListener loadListener) {
+            super(loadListener);
+            mDataStream = mInputStream;
+        }
+        @Override
+        protected boolean setupStreamAndSendStatus() {
+            mLoadListener.status(1, 1, mDataStream != null ? 200 : 404, "");
+            return true;
+        }
+        @Override
+        protected void buildHeaders(Headers headers) {
+            headers.setContentType(mMimeType);
+            headers.setContentEncoding(mEncoding);
+        }
+    }
+
+    // Accessed by jni, do not rename without modifying the jni code.
+    private String mMimeType;
+    private String mEncoding;
+    private InputStream mInputStream;
+
+    /**
+     * Construct a response with the given mime type, encoding, and data.
+     * @param mimeType The mime type of the data (i.e. text/html).
+     * @param encoding The encoding of the bytes read from data.
+     * @param data An InputStream for reading custom data.  The implementation
+     *             must implement {@link InputStream#read(byte[])}.
+     */
+    public WebResourceResponse(String mimeType, String encoding,
+            InputStream data) {
+        mMimeType = mimeType;
+        mEncoding = encoding;
+        mInputStream = data;
+    }
+
+    /**
+     * Set the mime type of the response data (i.e. text/html).
+     * @param mimeType
+     */
+    public void setMimeType(String mimeType) {
+        mMimeType = mimeType;
+    }
+
+    /**
+     * @see #setMimeType
+     */
+    public String getMimeType() {
+        return mMimeType;
+    }
+
+    /**
+     * Set the encoding of the response data (i.e. utf-8).  This will be used to
+     * decode the raw bytes from the input stream.
+     * @param encoding
+     */
+    public void setEncoding(String encoding) {
+        mEncoding = encoding;
+    }
+
+    /**
+     * @see #setEncoding
+     */
+    public String getEncoding() {
+        return mEncoding;
+    }
+
+    /**
+     * Set the input stream containing the data for this resource.
+     * @param data An InputStream for reading custom data.  The implementation
+     *             must implement {@link InputStream#read(byte[])}.
+     */
+    public void setData(InputStream data) {
+        mInputStream = data;
+    }
+
+    /**
+     * @see #setData
+     */
+    public InputStream getData() {
+        return mInputStream;
+    }
+
+    StreamLoader loader(LoadListener listener) {
+        return new Loader(listener);
+    }
+}
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 1f8eeba..db605de 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -78,6 +78,26 @@
     }
 
     /**
+     * Notify the host application of a resource request and allow the
+     * application to return the data.  If the return value is null, the WebView
+     * will continue to load the resource as usual.  Otherwise, the return
+     * response and data will be used.  NOTE: This method is called by the
+     * network thread so clients should exercise caution when accessing private
+     * data.
+     *
+     * @param view The {@link android.webkit.WebView} that is requesting the
+     *             resource.
+     * @param url The raw url of the resource.
+     * @return A {@link android.webkit.WebResourceResponse} containing the
+     *         response information or null if the WebView should load the
+     *         resource itself.
+     */
+    public WebResourceResponse shouldInterceptRequest(WebView view,
+            String url) {
+        return null;
+    }
+
+    /**
      * Notify the host application that there have been an excessive number of
      * HTTP redirects. As the host application if it would like to continue
      * trying to load the resource. The default behavior is to send the cancel
diff --git a/core/res/res/drawable/screen_background_selector_dark.xml b/core/res/res/drawable/screen_background_selector_dark.xml
new file mode 100644
index 0000000..2a81669
--- /dev/null
+++ b/core/res/res/drawable/screen_background_selector_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_accelerated="false"
+            android:drawable="@android:drawable/screen_background_dark" />
+    <item android:drawable="@android:drawable/background_holo_dark" />
+</selector>
diff --git a/core/res/res/drawable/screen_background_selector_light.xml b/core/res/res/drawable/screen_background_selector_light.xml
new file mode 100644
index 0000000..6992cad
--- /dev/null
+++ b/core/res/res/drawable/screen_background_selector_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_accelerated="false"
+            android:drawable="@android:drawable/screen_background_light" />
+    <item android:drawable="@android:drawable/background_holo_light" />
+</selector>
diff --git a/core/res/res/values-large/themes.xml b/core/res/res/values-large/themes.xml
index cdf58fe..8f9b03d 100644
--- a/core/res/res/values-large/themes.xml
+++ b/core/res/res/values-large/themes.xml
@@ -19,4 +19,6 @@
 <resources>
     <style name="Theme.Holo.DialogWhenLarge" parent="@android:style/Theme.Holo.Dialog">
     </style>
+    <style name="Theme.Holo.Light.DialogWhenLarge" parent="@android:style/Theme.Holo.Light.Dialog">
+    </style>
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 65a580b..9348822 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -34,9 +34,11 @@
         <!-- Color that matches (as closely as possible) the window background. -->
         <attr name="colorBackground" format="color" />
         <!-- This is a hint for a solid color that can be used for caching
-             rendered views.  This will be the color of the background when
-             there is a solid background color; it will be null when the
-             background is a texture or translucent. -->
+             rendered views.  This should be the color of the background when
+             there is a solid background color; it should be null when the
+             background is a texture or translucent.  When a device is able
+             to use accelerated drawing (thus setting state_accelerated), the
+             cache hint is ignored and always assumed to be transparent. -->
         <attr name="colorBackgroundCacheHint" format="color" />
         <!-- Default disabled alpha for widgets that set enabled/disabled alpha programmatically. -->
         <attr name="disabledAlpha" format="float" />
@@ -227,8 +229,13 @@
         <!-- ============= -->
         <eat-comment />
 
-        <!-- Drawable to use as the overall window background.  There are a
-             few special considerations you should use when settings this
+        <!-- Drawable to use as the overall window background.  As of
+             {@link android.os.Build.VERSION_CODES#HONEYCOMB}, this may
+             be a selector that uses state_accelerated to pick a non-solid
+             color when running on devices that can draw such a bitmap
+             with complex compositing on top at 60fps.
+             
+             <p>There are a few special considerations to use when setting this
              drawable:
              <ul>
              <li> This information will be used to infer the pixel format
@@ -3396,16 +3403,24 @@
              marked it as being of interest.  This is an alternative representation of
              state_checked for when the state should be propagated down the view hierarchy. -->
         <attr name="state_activated" format="boolean" />
-        <!--  State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
+        <!-- State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
         <attr name="state_active" format="boolean" />
-        <!--  State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
+        <!-- State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
         <attr name="state_single" format="boolean" />
-        <!--  State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
+        <!-- State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
         <attr name="state_first" format="boolean" />
-        <!--  State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
+        <!-- State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
         <attr name="state_middle" format="boolean" />
-        <!--  State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
+        <!-- State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable}.-->
         <attr name="state_last" format="boolean" />
+        <!-- State value for {@link android.graphics.drawable.StateListDrawable StateListDrawable},
+             indicating that the Drawable is in a view that is hardware accelerated.
+             This means that the device can at least render a full-screen scaled
+             bitmap with one layer of text and bitmaps composited on top of it
+             at 60fps.  When this is set, the colorBackgroundCacheHint will be
+             ignored even if it specifies a solid color, since that optimization
+             is not needed. -->
+        <attr name="state_accelerated" format="boolean" />
     </declare-styleable>
     <declare-styleable name="ViewDrawableStates">
         <attr name="state_pressed" />
@@ -3414,6 +3429,7 @@
         <attr name="state_window_focused" />
         <attr name="state_enabled" />
         <attr name="state_activated" />
+        <attr name="state_accelerated" />
     </declare-styleable>
     <!-- State array representing a menu item that is currently checked. -->
     <declare-styleable name="MenuItemCheckedState">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 3eb980f..6e14527 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1375,6 +1375,7 @@
   <public type="attr" name="indeterminateProgressStyle" />
   <public type="attr" name="progressBarPadding" />
   <public type="attr" name="animationResolution" />
+  <public type="attr" name="state_accelerated" />
 
   <public type="anim" name="animator_fade_in" />
   <public type="anim" name="animator_fade_out" />
@@ -1442,6 +1443,7 @@
   <public type="style" name="Widget.FragmentBreadCrumbs" />
 
   <public type="style" name="Theme.Holo.DialogWhenLarge" />
+  <public type="style" name="Theme.Holo.Light.DialogWhenLarge" />
   
   <public type="string" name="selectTextMode" />
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 8082f6b..88e755f 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -123,7 +123,7 @@
         <item name="galleryItemBackground">@android:drawable/gallery_item_background</item>
         
         <!-- Window attributes -->
-        <item name="windowBackground">@android:drawable/screen_background_dark</item>
+        <item name="windowBackground">@android:drawable/screen_background_selector_dark</item>
         <item name="windowFrame">@null</item>
         <item name="windowNoTitle">false</item>
         <item name="windowFullscreen">false</item>
@@ -279,7 +279,7 @@
          default theme, you should try to assume little more than that the
          background will be a light color. -->
     <style name="Theme.Light">
-        <item name="windowBackground">@drawable/screen_background_light</item>
+        <item name="windowBackground">@android:drawable/screen_background_selector_light</item>
         <item name="colorBackground">@android:color/background_light</item>
         <item name="colorForeground">@color/bright_foreground_light</item>
         <item name="colorForegroundInverse">@android:color/bright_foreground_light_inverse</item>
@@ -736,7 +736,6 @@
         <item name="galleryItemBackground">@android:drawable/gallery_item_background</item>
         
         <!-- Window attributes -->
-        <item name="windowBackground">?android:attr/colorBackground</item>
         <item name="windowFrame">@null</item>
         <item name="windowNoTitle">false</item>
         <item name="windowFullscreen">false</item>
@@ -972,7 +971,6 @@
         <item name="galleryItemBackground">@android:drawable/gallery_item_background</item>
         
         <!-- Window attributes -->
-        <item name="windowBackground">?android:attr/colorBackground</item>
         <item name="windowFrame">@null</item>
         <item name="windowNoTitle">false</item>
         <item name="windowFullscreen">false</item>
@@ -1220,6 +1218,12 @@
         <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item>
     </style>
 
+    <!-- Theme for a window that will be displayed either full-screen on
+         smaller screens (small, normal) or as a dialog on larger screens
+         (large, xlarge) -->
+    <style name="Theme.Holo.Light.DialogWhenLarge" parent="@android:style/Theme.Holo.Light">
+    </style>
+
     <!-- Holo light theme for alert dialog windows, which is used by the
          {@link android.app.AlertDialog} class.  This is basically a dialog
          but sets the background to empty so it can do two-tone backgrounds.
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStateUnitTestTemplate.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStateUnitTestTemplate.java
index 6abfbb2..f8e8f98 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStateUnitTestTemplate.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerStateUnitTestTemplate.java
@@ -39,7 +39,7 @@
  */
 class MediaPlayerStateUnitTestTemplate extends AndroidTestCase {
     private static final String TEST_PATH = MediaNames.TEST_PATH_1;
-    private static final String TAG = "MediaPlayerSeekToStateUnitTest";
+    private static final String TAG = "MediaPlayerStateUnitTestTemplate";
     private static final int SEEK_TO_END  = 135110;  // Milliseconds.
     private static int WAIT_FOR_COMMAND_TO_COMPLETE = 1000;  // Milliseconds.
     
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 1090c71..e99b74f 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -37,9 +37,7 @@
 import com.android.internal.widget.ActionBarView;
 
 import android.app.KeyguardManager;
-import android.content.ActivityNotFoundException;
 import android.content.Context;
-import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -51,7 +49,6 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemClock;
 import android.util.AndroidRuntimeException;
 import android.util.Config;
 import android.util.EventLog;
@@ -60,6 +57,7 @@
 import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.Gravity;
+import android.view.HardwareRenderer;
 import android.view.InputQueue;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
@@ -72,14 +70,12 @@
 import android.view.ViewGroup;
 import android.view.ViewManager;
 import android.view.ViewStub;
-import android.view.VolumePanel;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
-import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.PopupWindow;
@@ -166,7 +162,6 @@
     private MenuDialogHelper mContextMenuHelper;
 
     private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
-    private long mVolumeKeyUpTime;
 
     private AudioManager mAudioManager;
     private KeyguardManager mKeyguardManager;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 4bc7433..7d58e41 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -962,7 +962,7 @@
     /** {@inheritDoc} */
     public View addStartingWindow(IBinder appToken, String packageName,
                                   int theme, CharSequence nonLocalizedLabel,
-                                  int labelRes, int icon) {
+                                  int labelRes, int icon, int windowFlags) {
         if (!SHOW_STARTING_ANIMATIONS) {
             return null;
         }
@@ -1006,9 +1006,11 @@
             // flag because we do know that the next window will take input
             // focus, so we want to get the IME window up on top of us right away.
             win.setFlags(
+                windowFlags|
                 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
                 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                windowFlags|
                 WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
                 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|
                 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index fb87d69..5038770 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -3729,7 +3729,7 @@
 
     public void setAppStartingWindow(IBinder token, String pkg,
             int theme, CharSequence nonLocalizedLabel, int labelRes, int icon,
-            IBinder transferFrom, boolean createIfNeeded) {
+            int windowFlags, IBinder transferFrom, boolean createIfNeeded) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
                 "setAppStartingIcon()")) {
             throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3877,7 +3877,7 @@
             mStartingIconInTransition = true;
             wtoken.startingData = new StartingData(
                     pkg, theme, nonLocalizedLabel,
-                    labelRes, icon);
+                    labelRes, icon, windowFlags);
             Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
             // Note: we really want to do sendMessageAtFrontOfQueue() because we
             // want to process the message ASAP, before any other queued
@@ -8440,14 +8440,16 @@
         final CharSequence nonLocalizedLabel;
         final int labelRes;
         final int icon;
+        final int windowFlags;
 
         StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
-                int _labelRes, int _icon) {
+                int _labelRes, int _icon, int _windowFlags) {
             pkg = _pkg;
             theme = _theme;
             nonLocalizedLabel = _nonLocalizedLabel;
             labelRes = _labelRes;
             icon = _icon;
+            windowFlags = _windowFlags;
         }
     }
 
@@ -8568,7 +8570,7 @@
                         view = mPolicy.addStartingWindow(
                             wtoken.token, sd.pkg,
                             sd.theme, sd.nonLocalizedLabel, sd.labelRes,
-                            sd.icon);
+                            sd.icon, sd.windowFlags);
                     } catch (Exception e) {
                         Slog.w(TAG, "Exception when adding starting window", e);
                     }
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 47be6a2..c2f8d67 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -36,6 +36,7 @@
 import android.util.Slog;
 import android.util.TimeUtils;
 import android.view.IApplicationToken;
+import android.view.WindowManager;
 
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
@@ -68,6 +69,7 @@
     int labelRes;           // the label information from the package mgr.
     int icon;               // resource identifier of activity's icon.
     int theme;              // resource identifier of activity's theme.
+    int windowFlags;        // custom window flags for preview window.
     TaskRecord task;        // the task this is in.
     long launchTime;        // when we starting launching this activity
     long startTime;         // last time this activity was started
@@ -244,6 +246,9 @@
             }
             icon = aInfo.getIconResource();
             theme = aInfo.getThemeResource();
+            if ((aInfo.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
+                windowFlags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+            }
             if ((aInfo.flags&ActivityInfo.FLAG_MULTIPROCESS) != 0
                     && _caller != null
                     && (aInfo.applicationInfo.uid == Process.SYSTEM_UID
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 463493b..51dc84e 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1301,7 +1301,8 @@
                         mService.mWindowManager.setAppStartingWindow(
                                 next, next.packageName, next.theme,
                                 next.nonLocalizedLabel,
-                                next.labelRes, next.icon, null, true);
+                                next.labelRes, next.icon, next.windowFlags,
+                                null, true);
                     }
                 }
                 startSpecificActivityLocked(next, true, false);
@@ -1336,7 +1337,8 @@
                     mService.mWindowManager.setAppStartingWindow(
                             next, next.packageName, next.theme,
                             next.nonLocalizedLabel,
-                            next.labelRes, next.icon, null, true);
+                            next.labelRes, next.icon, next.windowFlags,
+                            null, true);
                 }
                 if (DEBUG_SWITCH) Slog.v(TAG, "Restarting: " + next);
             }
@@ -1460,7 +1462,7 @@
                 }
                 mService.mWindowManager.setAppStartingWindow(
                         r, r.packageName, r.theme, r.nonLocalizedLabel,
-                        r.labelRes, r.icon, prev, showStartingIcon);
+                        r.labelRes, r.icon, r.windowFlags, prev, showStartingIcon);
             }
         } else {
             // If this is the first activity, don't do any fancy animations,
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 4464236..710ff30 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -164,7 +164,7 @@
         }
         
         try {
-            mWm.setAppStartingWindow(null, "foo", 0, null, 0, 0, null, false);
+            mWm.setAppStartingWindow(null, "foo", 0, null, 0, 0, 0, null, false);
             fail("IWindowManager.setAppStartingWindow did not throw SecurityException as"
                     + " expected");
         } catch (SecurityException e) {