Merge change 6555 into donut

* changes:
  Make it so the notification manager doesn't mysteriously beep during boot.
diff --git a/api/current.xml b/api/current.xml
index 78562f0..d97a0f4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2275,6 +2275,17 @@
  visibility="public"
 >
 </field>
+<field name="autoUrlDetect"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843404"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="background"
  type="int"
  transient="false"
@@ -3386,17 +3397,6 @@
  visibility="public"
 >
 </field>
-<field name="donut_resource_pad20"
- type="int"
- transient="false"
- volatile="false"
- value="16843404"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="donut_resource_pad3"
  type="int"
  transient="false"
diff --git a/awt/Android.mk b/awt/Android.mk
index c7480f5..213c6ce 100644
--- a/awt/Android.mk
+++ b/awt/Android.mk
@@ -28,4 +28,4 @@
 
 LOCAL_DX_FLAGS := --core-library
 
-include $(BUILD_JAVA_LIBRARY)
+#include $(BUILD_JAVA_LIBRARY)
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 022fe5a..e4b6791 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -504,8 +504,7 @@
     }
 
     // start recording mode
-    ret = mHardware->startRecording(recordingCallback,
-                                    mCameraService.get());
+    ret = mHardware->startRecording(recordingCallback, mCameraService.get());
     if (ret != NO_ERROR) {
         LOGE("mHardware->startRecording() failed with status %d", ret);
     }
@@ -798,7 +797,7 @@
 }
 
 // recording callback
-void CameraService::Client::recordingCallback(const sp<IMemory>& mem, void* user)
+void CameraService::Client::recordingCallback(nsecs_t timestamp, const sp<IMemory>& mem, void* user)
 {
     LOGV("recordingCallback");
     sp<Client> client = getClientFromCookie(user);
@@ -806,7 +805,7 @@
         return;
     }
     // The strong pointer guarantees the client will exist, but no lock is held.
-    client->postRecordingFrame(mem);
+    client->postRecordingFrame(timestamp, mem);
 }
 
 // take a picture - image is returned in callback
@@ -1072,14 +1071,14 @@
     mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
 }
 
-void CameraService::Client::postRecordingFrame(const sp<IMemory>& frame)
+void CameraService::Client::postRecordingFrame(nsecs_t timestamp, const sp<IMemory>& frame)
 {
     LOGV("postRecordingFrame");
     if (frame == 0) {
         LOGW("frame is a null pointer");
         return;
     }
-    mCameraClient->dataCallback(CAMERA_MSG_VIDEO_FRAME, frame);
+    mCameraClient->dataCallbackTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, frame);
 }
 
 void CameraService::Client::postPreviewFrame(const sp<IMemory>& mem)
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 0f07673..ea93789 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -132,7 +132,7 @@
 
                     status_t    checkPid();
 
-        static      void        recordingCallback(const sp<IMemory>& mem, void* user);
+        static      void        recordingCallback(nsecs_t timestamp, const sp<IMemory>& mem, void* user);
         static      void        previewCallback(const sp<IMemory>& mem, void* user);
         static      void        shutterCallback(void *user);
         static      void        yuvPictureCallback(const sp<IMemory>& mem, void* user);
@@ -144,7 +144,7 @@
                     void        postRaw(const sp<IMemory>& mem);
                     void        postJpeg(const sp<IMemory>& mem);
                     void        postPreviewFrame(const sp<IMemory>& mem);
-                    void        postRecordingFrame(const sp<IMemory>& frame);
+                    void        postRecordingFrame(nsecs_t timestamp, const sp<IMemory>& frame);
                     void        copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, size_t offset, size_t size);
                     void        postError(status_t error);
                     void        postAutoFocus(bool focused);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index ca9632a..6c2560d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -606,7 +606,6 @@
     private static final String SAVED_DIALOG_IDS_KEY = "android:savedDialogIds";
     private static final String SAVED_DIALOGS_TAG = "android:savedDialogs";
     private static final String SAVED_DIALOG_KEY_PREFIX = "android:dialog_";
-    private static final String SAVED_SEARCH_DIALOG_KEY = "android:search_dialog";
 
     private SparseArray<Dialog> mManagedDialogs;
 
@@ -630,7 +629,6 @@
     /*package*/ int mConfigChangeFlags;
     /*package*/ Configuration mCurrentConfig;
     private SearchManager mSearchManager;
-    private Bundle mSearchDialogState = null;
 
     private Window mWindow;
 
@@ -808,13 +806,6 @@
     final void performRestoreInstanceState(Bundle savedInstanceState) {
         onRestoreInstanceState(savedInstanceState);
         restoreManagedDialogs(savedInstanceState);
-        
-        // Also restore the state of a search dialog (if any)
-        // TODO more generic than just this manager
-        Bundle searchState = savedInstanceState.getBundle(SAVED_SEARCH_DIALOG_KEY);
-        if (searchState != null) {
-            mSearchManager.restoreSearchDialog(searchState);
-        }
     }
 
     /**
@@ -866,7 +857,7 @@
             if (dialogState != null) {
                 // Calling onRestoreInstanceState() below will invoke dispatchOnCreate
                 // so tell createDialog() not to do it, otherwise we get an exception
-                final Dialog dialog = createDialog(dialogId, false);
+                final Dialog dialog = createDialog(dialogId, dialogState);
                 mManagedDialogs.put(dialogId, dialog);
                 onPrepareDialog(dialogId, dialog);
                 dialog.onRestoreInstanceState(dialogState);
@@ -874,13 +865,13 @@
         }
     }
 
-    private Dialog createDialog(Integer dialogId, boolean dispatchOnCreate) {
+    private Dialog createDialog(Integer dialogId, Bundle state) {
         final Dialog dialog = onCreateDialog(dialogId);
         if (dialog == null) {
             throw new IllegalArgumentException("Activity#onCreateDialog did "
                     + "not create a dialog for id " + dialogId);
         }
-        if (dispatchOnCreate) dialog.dispatchOnCreate(null);
+        dialog.dispatchOnCreate(state);
         return dialog;
     }
 
@@ -1030,14 +1021,6 @@
     final void performSaveInstanceState(Bundle outState) {
         onSaveInstanceState(outState);
         saveManagedDialogs(outState);
-
-        // Also save the state of a search dialog (if any)
-        // TODO more generic than just this manager
-        // onPause() should always be called before this method, so mSearchManagerState
-        // should be up to date.
-        if (mSearchDialogState != null) {
-            outState.putBundle(SAVED_SEARCH_DIALOG_KEY, mSearchDialogState);
-        }
     }
 
     /**
@@ -1317,10 +1300,6 @@
                 c.mCursor.close();
             }
         }
-
-        // Clear any search state saved in performPause(). If the state may be needed in the
-        // future, it will have been saved by performSaveInstanceState()
-        mSearchDialogState = null;
     }
 
     /**
@@ -1341,11 +1320,7 @@
      */
     public void onConfigurationChanged(Configuration newConfig) {
         mCalled = true;
-        
-        // also update search dialog if showing
-        // TODO more generic than just this manager
-        mSearchManager.onConfigurationChanged(newConfig);
-        
+
         if (mWindow != null) {
             // Pass the configuration changed event to the window
             mWindow.onConfigurationChanged(newConfig);
@@ -2432,7 +2407,7 @@
         }
         Dialog dialog = mManagedDialogs.get(id);
         if (dialog == null) {
-            dialog = createDialog(id, true);
+            dialog = createDialog(id, null);
             mManagedDialogs.put(id, dialog);
         }
         
@@ -3575,20 +3550,12 @@
                 "Activity " + mComponent.toShortString() +
                 " did not call through to super.onPostResume()");
         }
-
-        // restore search dialog, if any
-        if (mSearchDialogState != null) {
-            mSearchManager.restoreSearchDialog(mSearchDialogState);
-        }
-        mSearchDialogState = null;
     }
 
     final void performPause() {
         onPause();
 
-        // save search dialog state if the search dialog is open,
-        // and then dismiss the search dialog
-        mSearchDialogState = mSearchManager.saveSearchDialog();
+        // dismiss the search dialog if it is open
         mSearchManager.stopSearch();
     }
     
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 222fe75..2b165fc 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -292,8 +292,10 @@
     // internal method to make sure mcreated is set properly without requiring
     // users to call through to super in onCreate
     void dispatchOnCreate(Bundle savedInstanceState) {
-        onCreate(savedInstanceState);
-        mCreated = true;
+        if (!mCreated) {
+            onCreate(savedInstanceState);
+            mCreated = true;
+        }
     }
 
     /**
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl
index e8bd60a..5b62192 100644
--- a/core/java/android/app/ISearchManager.aidl
+++ b/core/java/android/app/ISearchManager.aidl
@@ -36,8 +36,4 @@
             boolean globalSearch,
             ISearchManagerCallback searchManagerCallback);
     void stopSearch();
-    boolean isVisible();
-    Bundle onSaveInstanceState();
-    void onRestoreInstanceState(in Bundle savedInstanceState);
-    void onConfigurationChanged(in Configuration newConfig);
 }
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index fdb619a..022a9d9 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -19,13 +19,11 @@
 import static android.app.SuggestionsAdapter.getColumnString;
 
 import android.content.ActivityNotFoundException;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.ContentResolver;
 import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
@@ -33,8 +31,8 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.Cursor;
-import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.SystemClock;
@@ -95,11 +93,7 @@
 
     private static final int SEARCH_PLATE_LEFT_PADDING_GLOBAL = 12;
     private static final int SEARCH_PLATE_LEFT_PADDING_NON_GLOBAL = 7;
-    
-    // interaction with runtime
-    private IntentFilter mCloseDialogsFilter;
-    private IntentFilter mPackageFilter;
-    
+
     // views & widgets
     private TextView mBadgeLabel;
     private ImageView mAppIcon;
@@ -210,15 +204,7 @@
 
         // Touching outside of the search dialog will dismiss it 
         setCanceledOnTouchOutside(true);
-        
-        // Set up broadcast filters
-        mCloseDialogsFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        mPackageFilter = new IntentFilter();
-        mPackageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
-        mPackageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        mPackageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-        mPackageFilter.addDataScheme("package");
-        
+
         // Save voice intent for later queries/launching
         mVoiceWebSearchIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
         mVoiceWebSearchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -382,15 +368,6 @@
         
         return true;
     }
-    
-    @Override
-    protected void onStart() {
-        super.onStart();
-        
-        // receive broadcasts
-        getContext().registerReceiver(mBroadcastReceiver, mCloseDialogsFilter);
-        getContext().registerReceiver(mBroadcastReceiver, mPackageFilter);
-    }
 
     /**
      * The search dialog is being dismissed, so handle all of the local shutdown operations.
@@ -401,14 +378,7 @@
     @Override
     public void onStop() {
         super.onStop();
-        
-        // stop receiving broadcasts (throws exception if none registered)
-        try {
-            getContext().unregisterReceiver(mBroadcastReceiver);
-        } catch (RuntimeException e) {
-            // This is OK - it just means we didn't have any registered
-        }
-        
+
         closeSuggestionsAdapter();
         
         // dump extra memory we're hanging on to
@@ -455,12 +425,15 @@
     /**
      * Save the minimal set of data necessary to recreate the search
      * 
-     * @return A bundle with the state of the dialog.
+     * @return A bundle with the state of the dialog, or {@code null} if the search
+     *         dialog is not showing.
      */
     @Override
     public Bundle onSaveInstanceState() {
+        if (!isShowing()) return null;
+
         Bundle bundle = new Bundle();
-        
+
         // setup info so I can recreate this particular search       
         bundle.putParcelable(INSTANCE_KEY_COMPONENT, mLaunchComponent);
         bundle.putBundle(INSTANCE_KEY_APPDATA, mAppSearchData);
@@ -483,6 +456,8 @@
      */
     @Override
     public void onRestoreInstanceState(Bundle savedInstanceState) {
+        if (savedInstanceState == null) return;
+
         ComponentName launchComponent = savedInstanceState.getParcelable(INSTANCE_KEY_COMPONENT);
         Bundle appSearchData = savedInstanceState.getBundle(INSTANCE_KEY_APPDATA);
         boolean globalSearch = savedInstanceState.getBoolean(INSTANCE_KEY_GLOBALSEARCH);
@@ -509,7 +484,7 @@
     /**
      * Called after resources have changed, e.g. after screen rotation or locale change.
      */
-    public void onConfigurationChanged(Configuration newConfig) {
+    public void onConfigurationChanged() {
         if (isShowing()) {
             // Redraw (resources may have changed)
             updateSearchButton();
@@ -777,7 +752,7 @@
         }
 
         public void afterTextChanged(Editable s) {
-            if (!mSearchAutoComplete.isPerformingCompletion()) {
+            if (mSearchable.autoUrlDetect() && !mSearchAutoComplete.isPerformingCompletion()) {
                 // The user changed the query, check if it is a URL and if so change the search
                 // button in the soft keyboard to the 'Go' button.
                 int options = (mSearchAutoComplete.getImeOptions() & (~EditorInfo.IME_MASK_ACTION));
@@ -987,17 +962,19 @@
                         && event.getAction() == KeyEvent.ACTION_UP) {
                     v.cancelLongPress();
 
-                    // If this is a url entered by the user and we displayed the 'Go' button which
-                    // the user clicked, launch the url instead of using it as a search query.
-                    if ((mSearchAutoCompleteImeOptions & EditorInfo.IME_MASK_ACTION)
-                            == EditorInfo.IME_ACTION_GO) {
-                        Uri uri = Uri.parse(fixUrl(mSearchAutoComplete.getText().toString()));
-                        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        launchIntent(intent);
-                    } else {
-                        // Launch as a regular search.
-                        launchQuerySearch();
+                    if (mSearchable.autoUrlDetect()) {
+                        // If this is a url entered by the user & we displayed the 'Go' button which
+                        // the user clicked, launch the url instead of using it as a search query.
+                        if ((mSearchAutoCompleteImeOptions & EditorInfo.IME_MASK_ACTION)
+                                == EditorInfo.IME_ACTION_GO) {
+                            Uri uri = Uri.parse(fixUrl(mSearchAutoComplete.getText().toString()));
+                            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                            launchIntent(intent);
+                        } else {
+                            // Launch as a regular search.
+                            launchQuerySearch();
+                        }
                     }
                     return true;
                 }
@@ -1012,35 +989,11 @@
             return false;
         }
     };
-        
-    /**
-     * When the ACTION_CLOSE_SYSTEM_DIALOGS intent is received, we should close ourselves 
-     * immediately, in order to allow a higher-priority UI to take over
-     * (e.g. phone call received).
-     * 
-     * When a package is added, removed or changed, our current context
-     * may no longer be valid.  This would only happen if a package is installed/removed exactly
-     * when the search bar is open.  So for now we're just going to close the search
-     * bar.  
-     * Anything fancier would require some checks to see if the user's context was still valid.
-     * Which would be messier.
-     */
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
-                cancel();
-            } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)
-                    || Intent.ACTION_PACKAGE_REMOVED.equals(action)
-                    || Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
-                cancel();
-            }
-        }
-    };
 
     @Override
     public void cancel() {
+        if (!isShowing()) return;
+
         // We made sure the IME was displayed, so also make sure it is closed
         // when we go away.
         InputMethodManager imm = (InputMethodManager)getContext()
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index e5ba6a4..5d25f10 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -20,7 +20,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.res.Configuration;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
@@ -1730,59 +1729,6 @@
     }
 
     /**
-     * Saves the state of the search UI.
-     *
-     * @return A Bundle containing the state of the search dialog, or {@code null}
-     *         if the search UI is not visible.
-     *
-     * @hide
-     */
-    public Bundle saveSearchDialog() {
-        if (DBG) debug("saveSearchDialog(), mIsShowing=" + mIsShowing);
-        if (!mIsShowing) return null;
-        try {
-            return mService.onSaveInstanceState();
-        } catch (RemoteException ex) {
-            Log.e(TAG, "onSaveInstanceState() failed: " + ex);
-            return null;
-        }
-    }
-
-    /**
-     * Restores the state of the search dialog.
-     *
-     * @param searchDialogState Bundle to read the state from.
-     *
-     * @hide
-     */
-    public void restoreSearchDialog(Bundle searchDialogState) {
-        if (DBG) debug("restoreSearchDialog(" + searchDialogState + ")");
-        if (searchDialogState == null) return;
-        try {
-            mService.onRestoreInstanceState(searchDialogState);
-        } catch (RemoteException ex) {
-            Log.e(TAG, "onRestoreInstanceState() failed: " + ex);
-        }
-    }
-
-    /**
-     * Update the search dialog after a configuration change.
-     *
-     * @param newConfig The new configuration.
-     *
-     * @hide
-     */
-    public void onConfigurationChanged(Configuration newConfig) {
-        if (DBG) debug("onConfigurationChanged(" + newConfig + "), mIsShowing=" + mIsShowing);
-        if (!mIsShowing) return;
-        try {
-            mService.onConfigurationChanged(newConfig);
-        } catch (RemoteException ex) {
-            Log.e(TAG, "onConfigurationChanged() failed:" + ex);
-        }
-    }
-
-    /**
      * Gets information about a searchable activity. This method is static so that it can
      * be used from non-Activity contexts.
      *
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index bcf95b6..0d00f21 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -173,7 +173,7 @@
      * {@hide}
      */
     public static final int ANY_DENSITY = -1;
-    private static final int[] ANY_DENSITIES_ARRAY = { ANY_DENSITY };
+    static final int[] ANY_DENSITIES_ARRAY = { ANY_DENSITY };
 
     /**
      * Flags associated with the application.  Any combination of
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 558b0c3..b293636 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -945,15 +945,25 @@
                         >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
             pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
         }
-        
+        int densities[] = null;
         int size = pkg.supportsDensityList.size();
         if (size > 0) {
-            int densities[] = pkg.supportsDensities = new int[size];
+            densities = pkg.supportsDensities = new int[size];
             List<Integer> densityList = pkg.supportsDensityList;
             for (int i = 0; i < size; i++) {
                 densities[i] = densityList.get(i);
             }
         }
+        /**
+         * TODO: enable this before code freeze. b/1967935
+         * *
+        if ((densities == null || densities.length == 0)
+                && (pkg.applicationInfo.targetSdkVersion
+                        >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
+            pkg.supportsDensities = ApplicationInfo.ANY_DENSITIES_ARRAY;
+        }
+         */
+
         return pkg;
     }
 
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index dfe304d..ebe556e 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -51,18 +51,6 @@
     public static final int DEFAULT_PORTRAIT_HEIGHT = 480;
 
     /**
-     * The x-shift mode that controls the position of the content or the window under
-     * compatibility mode.
-     * {@see getTranslator}
-     * {@see Translator#mShiftMode}
-     */
-    private static final int X_SHIFT_NONE = 0;
-    private static final int X_SHIFT_CONTENT = 1;
-    private static final int X_SHIFT_AND_CLIP_CONTENT = 2;
-    private static final int X_SHIFT_WINDOW = 3;
-
-
-    /**
      *  A compatibility flags
      */
     private int mCompatibilityFlags;
@@ -106,20 +94,6 @@
      */
     public final int appFlags;
     
-    /**
-     * Window size in Compatibility Mode, in real pixels. This is updated by
-     * {@link DisplayMetrics#updateMetrics}.
-     */
-    private int mWidth;
-    private int mHeight;
-    
-    /**
-     * The x offset to center the window content. In X_SHIFT_WINDOW mode, the offset is added
-     * to the window's layout. In X_SHIFT_CONTENT/X_SHIFT_AND_CLIP_CONTENT mode, the offset
-     * is used to translate the Canvas.
-     */
-    private int mXOffset;
-
     public CompatibilityInfo(ApplicationInfo appInfo) {
         appFlags = appInfo.flags;
         
@@ -153,6 +127,7 @@
             applicationScale =
                     DisplayMetrics.DEVICE_DENSITY / (float) DisplayMetrics.DEFAULT_DENSITY;
         }
+
         applicationInvertedScale = 1.0f / applicationScale;
         if (applicationScale != 1.0f) {
             mCompatibilityFlags |= SCALING_REQUIRED;
@@ -181,23 +156,10 @@
     public CompatibilityInfo copy() {
         CompatibilityInfo info = new CompatibilityInfo(appFlags, mCompatibilityFlags,
                 applicationScale, applicationInvertedScale);
-        info.setVisibleRect(mXOffset, mWidth, mHeight);
         return info;
     }
  
     /**
-     * Sets the application's visible rect in compatibility mode.
-     * @param xOffset the application's x offset that is added to center the content.
-     * @param widthPixels the application's width in real pixels on the screen.
-     * @param heightPixels the application's height in real pixels on the screen.
-     */
-    public void setVisibleRect(int xOffset, int widthPixels, int heightPixels) {
-        this.mXOffset = xOffset; 
-        mWidth = widthPixels;
-        mHeight = heightPixels;
-    }
-    
-    /**
      * Sets expandable bit in the compatibility flag.
      */
     public void setExpandable(boolean expandable) {
@@ -222,6 +184,10 @@
         return (mCompatibilityFlags & SCALING_REQUIRED) != 0;
     }
     
+    public boolean supportsScreen() {
+        return (mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) != 0;
+    }
+    
     @Override
     public String toString() {
         return "CompatibilityInfo{scale=" + applicationScale +
@@ -231,21 +197,6 @@
     /**
      * Returns the translator which can translate the coordinates of the window.
      * There are five different types of Translator.
-     * 
-     * 1) {@link CompatibilityInfo#X_SHIFT_AND_CLIP_CONTENT}
-     *   Shift and clip the content of the window at drawing time. Used for activities'
-     *   main window (with no gravity).
-     * 2) {@link CompatibilityInfo#X_SHIFT_CONTENT}
-     *   Shift the content of the window at drawing time. Used for windows that is created by
-     *   an application and expected to be aligned with the application window.
-     * 3) {@link CompatibilityInfo#X_SHIFT_WINDOW}
-     *   Create the window with adjusted x- coordinates. This is typically used 
-     *   in popup window, where it has to be placed relative to main window.
-     * 4) {@link CompatibilityInfo#X_SHIFT_NONE}
-     *   No adjustment required, such as dialog.
-     * 5) Same as X_SHIFT_WINDOW, but no scaling. This is used by {@link SurfaceView}, which
-     *  does not require scaling, but its window's location has to be adjusted.
-     * 
      * @param params the window's parameter
      */
     public Translator getTranslator(WindowManager.LayoutParams params) {
@@ -254,35 +205,11 @@
             if (DBG) Log.d(TAG, "no translation required");
             return null;
         }
-        
-        if ((mCompatibilityFlags & CompatibilityInfo.EXPANDABLE) == 0) {
-            if ((params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) {
-                if (DBG) Log.d(TAG, "translation for surface view selected");
-                return new Translator(X_SHIFT_WINDOW, false, 1.0f, 1.0f);
-            } else {
-                int shiftMode;
-                if (params.gravity == Gravity.NO_GRAVITY) {
-                    // For Regular Application window
-                    shiftMode = X_SHIFT_AND_CLIP_CONTENT;
-                    if (DBG) Log.d(TAG, "shift and clip translator");
-                } else if (params.width == WindowManager.LayoutParams.FILL_PARENT) {
-                    // For Regular Application window
-                    shiftMode = X_SHIFT_CONTENT;
-                    if (DBG) Log.d(TAG, "shift content translator");
-                } else if ((params.gravity & Gravity.LEFT) != 0 && params.x > 0) {
-                    shiftMode = X_SHIFT_WINDOW;
-                    if (DBG) Log.d(TAG, "shift window translator");
-                } else {
-                    shiftMode = X_SHIFT_NONE;
-                    if (DBG) Log.d(TAG, "no content/window translator");
-                }
-                return new Translator(shiftMode);
-            }
-        } else if (isScalingRequired()) {
-            return new Translator();
-        } else {
+        if (!isScalingRequired() ||
+            (params.flags & WindowManager.LayoutParams.FLAG_NO_COMPATIBILITY_SCALING) != 0) {
             return null;
         }
+        return new Translator();
     }
 
     /**
@@ -290,97 +217,48 @@
      * @hide
      */
     public class Translator {
-        final private int mShiftMode;
-        final public boolean scalingRequired;
         final public float applicationScale;
         final public float applicationInvertedScale;
         
         private Rect mContentInsetsBuffer = null;
-        private Rect mVisibleInsets = null;
+        private Rect mVisibleInsetsBuffer = null;
         
-        Translator(int shiftMode, boolean scalingRequired, float applicationScale,
-                float applicationInvertedScale) {
-            mShiftMode = shiftMode;
-            this.scalingRequired = scalingRequired;
+        Translator(float applicationScale, float applicationInvertedScale) {
             this.applicationScale = applicationScale;
             this.applicationInvertedScale = applicationInvertedScale;
         }
 
-        Translator(int shiftMode) {
-            this(shiftMode,
-                    isScalingRequired(),
-                    CompatibilityInfo.this.applicationScale,
-                    CompatibilityInfo.this.applicationInvertedScale);
-        }
-        
         Translator() {
-            this(X_SHIFT_NONE);
+            this(CompatibilityInfo.this.applicationScale,
+                    CompatibilityInfo.this.applicationInvertedScale);
         }
 
         /**
          * Translate the screen rect to the application frame.
          */
         public void translateRectInScreenToAppWinFrame(Rect rect) {
-            if (rect.isEmpty()) return; // skip if the window size is empty.
-            switch (mShiftMode) {
-                case X_SHIFT_AND_CLIP_CONTENT:
-                    rect.intersect(0, 0, mWidth, mHeight);
-                    break;
-                case X_SHIFT_CONTENT:
-                    rect.intersect(0, 0, mWidth + mXOffset, mHeight);
-                    break;
-                case X_SHIFT_WINDOW:
-                case X_SHIFT_NONE:
-                    break;
-            }
-            if (scalingRequired) {
-                rect.scale(applicationInvertedScale);
-            }
+            rect.scale(applicationInvertedScale);
         }
 
         /**
          * Translate the region in window to screen. 
          */
         public void translateRegionInWindowToScreen(Region transparentRegion) {
-            switch (mShiftMode) {
-                case X_SHIFT_AND_CLIP_CONTENT:
-                case X_SHIFT_CONTENT:
-                    transparentRegion.scale(applicationScale);
-                    transparentRegion.translate(mXOffset, 0);
-                    break;
-                case X_SHIFT_WINDOW:
-                case X_SHIFT_NONE:
-                    transparentRegion.scale(applicationScale);
-            }
+            transparentRegion.scale(applicationScale);
         }
 
         /**
          * Apply translation to the canvas that is necessary to draw the content.
          */
         public void translateCanvas(Canvas canvas) {
-            if (mShiftMode == X_SHIFT_CONTENT ||
-                    mShiftMode == X_SHIFT_AND_CLIP_CONTENT) {
-                // TODO: clear outside when rotation is changed.
-
-                // Translate x-offset only when the content is shifted.
-                canvas.translate(mXOffset, 0);
-            }
-            if (scalingRequired) {
-                canvas.scale(applicationScale, applicationScale);
-            }
+            canvas.scale(applicationScale, applicationScale);
         }
 
         /**
          * Translate the motion event captured on screen to the application's window.
          */
         public void translateEventInScreenToAppWindow(MotionEvent event) {
-            if (mShiftMode == X_SHIFT_CONTENT ||
-                    mShiftMode == X_SHIFT_AND_CLIP_CONTENT) {
-                event.translate(-mXOffset, 0);
-            }
-            if (scalingRequired) {
-                event.scale(applicationInvertedScale);
-            }
+            event.scale(applicationInvertedScale);
         }
 
         /**
@@ -388,62 +266,21 @@
          * Screen's view.
          */
         public void translateWindowLayout(WindowManager.LayoutParams params) {
-            switch (mShiftMode) {
-                case X_SHIFT_NONE:
-                case X_SHIFT_AND_CLIP_CONTENT:
-                case X_SHIFT_CONTENT:
-                    params.scale(applicationScale);
-                    break;
-                case X_SHIFT_WINDOW:
-                    params.scale(applicationScale);
-                    params.x += mXOffset;
-                    break;
-            }
+            params.scale(applicationScale);
         }
         
         /**
          * Translate a Rect in application's window to screen.
          */
         public void translateRectInAppWindowToScreen(Rect rect) {
-            // TODO Auto-generated method stub
-            if (scalingRequired) {
-                rect.scale(applicationScale);
-            }
-            switch(mShiftMode) {
-                case X_SHIFT_NONE:
-                case X_SHIFT_WINDOW:
-                    break;
-                case X_SHIFT_CONTENT:
-                case X_SHIFT_AND_CLIP_CONTENT:
-                    rect.offset(mXOffset, 0);
-                    break;
-            }
+            rect.scale(applicationScale);
         }
  
         /**
          * Translate a Rect in screen coordinates into the app window's coordinates.
          */
         public void translateRectInScreenToAppWindow(Rect rect) {
-            switch (mShiftMode) {
-                case X_SHIFT_NONE:
-                case X_SHIFT_WINDOW:
-                    break;
-                case X_SHIFT_CONTENT: {
-                    rect.intersects(mXOffset, 0, rect.right, rect.bottom);
-                    int dx = Math.min(mXOffset, rect.left);
-                    rect.offset(-dx, 0);
-                    break;
-                }
-                case X_SHIFT_AND_CLIP_CONTENT: {
-                    rect.intersects(mXOffset, 0, mWidth + mXOffset, mHeight);
-                    int dx = Math.min(mXOffset, rect.left);
-                    rect.offset(-dx, 0);
-                    break;
-                }
-            }
-            if (scalingRequired) {
-                rect.scale(applicationInvertedScale);
-            }
+            rect.scale(applicationInvertedScale);
         }
 
         /**
@@ -451,19 +288,7 @@
          * @param params
          */
         public void translateLayoutParamsInAppWindowToScreen(LayoutParams params) {
-            if (scalingRequired) {
-                params.scale(applicationScale);
-            }
-            switch (mShiftMode) {
-                // the window location on these mode does not require adjustmenet.
-                case X_SHIFT_NONE:
-                case X_SHIFT_WINDOW:
-                    break;
-                case X_SHIFT_CONTENT:
-                case X_SHIFT_AND_CLIP_CONTENT:
-                    params.x += mXOffset;
-                    break;
-            }
+            params.scale(applicationScale);
         }
 
         /**
@@ -482,10 +307,31 @@
          * the internal buffer for content insets to avoid extra object allocation.
          */
         public Rect getTranslatedVisbileInsets(Rect visibleInsets) {
-            if (mVisibleInsets == null) mVisibleInsets = new Rect();
-            mVisibleInsets.set(visibleInsets);
-            translateRectInAppWindowToScreen(mVisibleInsets);
-            return mVisibleInsets;
+            if (mVisibleInsetsBuffer == null) mVisibleInsetsBuffer = new Rect();
+            mVisibleInsetsBuffer.set(visibleInsets);
+            translateRectInAppWindowToScreen(mVisibleInsetsBuffer);
+            return mVisibleInsetsBuffer;
+        }
+    }
+
+    /**
+     * Returns the frame Rect for applications runs under compatibility mode.
+     *
+     * @param dm the display metrics used to compute the frame size.
+     * @param orientation the orientation of the screen.
+     * @param outRect the output parameter which will contain the result.
+     */
+    public static void updateCompatibleScreenFrame(DisplayMetrics dm, int orientation,
+            Rect outRect) {
+        int width = dm.widthPixels;
+        int portraitHeight = (int) (DEFAULT_PORTRAIT_HEIGHT * dm.density);
+        int portraitWidth = (int) (DEFAULT_PORTRAIT_WIDTH * dm.density);
+        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+            int xOffset = (width - portraitHeight) / 2 ;
+            outRect.set(xOffset, 0, xOffset + portraitHeight, portraitWidth);
+        } else {
+            int xOffset = (width - portraitWidth) / 2 ;
+            outRect.set(xOffset, 0, xOffset + portraitWidth, portraitHeight);
         }
     }
 }
diff --git a/core/java/android/server/search/SearchDialogWrapper.java b/core/java/android/server/search/SearchDialogWrapper.java
new file mode 100644
index 0000000..dbc1e7f
--- /dev/null
+++ b/core/java/android/server/search/SearchDialogWrapper.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.server.search;
+
+import android.app.ISearchManagerCallback;
+import android.app.SearchDialog;
+import android.app.SearchManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.DeadObjectException;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * Runs an instance of {@link SearchDialog} on its own thread.
+ */
+class SearchDialogWrapper
+implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
+
+    private static final String TAG = "SearchManagerService";
+    private static final boolean DBG = false;
+
+    private static final String DISABLE_SEARCH_PROPERTY = "dev.disablesearchdialog";
+
+    private static final String SEARCH_UI_THREAD_NAME = "SearchDialog";
+    private static final int SEARCH_UI_THREAD_PRIORITY =
+        android.os.Process.THREAD_PRIORITY_FOREGROUND;
+
+    // Takes no arguments
+    private static final int MSG_INIT = 0;
+    // Takes these arguments:
+    // arg1: selectInitialQuery, 0 = false, 1 = true
+    // arg2: globalSearch, 0 = false, 1 = true
+    // obj: searchManagerCallback
+    // data[KEY_INITIAL_QUERY]: initial query
+    // data[KEY_LAUNCH_ACTIVITY]: launch activity
+    // data[KEY_APP_SEARCH_DATA]: app search data
+    private static final int MSG_START_SEARCH = 1;
+    // Takes no arguments
+    private static final int MSG_STOP_SEARCH = 2;
+    // Takes no arguments
+    private static final int MSG_ON_CONFIGURATION_CHANGED = 3;
+
+    private static final String KEY_INITIAL_QUERY = "q";
+    private static final String KEY_LAUNCH_ACTIVITY = "a";
+    private static final String KEY_APP_SEARCH_DATA = "d";
+
+    // Context used for getting search UI resources
+    private final Context mContext;
+
+    // Handles messages on the search UI thread.
+    private final SearchDialogHandler mSearchUiThread;
+
+    // The search UI
+    SearchDialog mSearchDialog;
+
+    // If the search UI is visible, this is the callback for the client that showed it.
+    ISearchManagerCallback mCallback = null;
+
+    // Allows disabling of search dialog for stress testing runs
+    private final boolean mDisabledOnBoot;
+
+    /**
+     * Creates a new search dialog wrapper and a search UI thread. The search dialog itself will
+     * be created some asynchronously on the search UI thread.
+     *
+     * @param context Context used for getting search UI resources.
+     */
+    public SearchDialogWrapper(Context context) {
+        mContext = context;
+
+        mDisabledOnBoot = !TextUtils.isEmpty(SystemProperties.get(DISABLE_SEARCH_PROPERTY));
+
+        // Create the search UI thread
+        HandlerThread t = new HandlerThread(SEARCH_UI_THREAD_NAME, SEARCH_UI_THREAD_PRIORITY);
+        t.start();
+        mSearchUiThread = new SearchDialogHandler(t.getLooper());
+
+        // Create search UI on the search UI thread
+        mSearchUiThread.sendEmptyMessage(MSG_INIT);
+    }
+
+    /**
+     * Initializes the search UI.
+     * Must be called from the search UI thread.
+     */
+    private void init() {
+        mSearchDialog = new SearchDialog(mContext);
+        mSearchDialog.setOnCancelListener(this);
+        mSearchDialog.setOnDismissListener(this);
+    }
+
+    private void registerBroadcastReceiver() {
+        IntentFilter closeDialogsFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        mContext.registerReceiver(mBroadcastReceiver, closeDialogsFilter);
+        IntentFilter configurationChangedFilter =
+                new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
+        mContext.registerReceiver(mBroadcastReceiver, configurationChangedFilter);
+    }
+
+    private void unregisterBroadcastReceiver() {
+        mContext.unregisterReceiver(mBroadcastReceiver);
+    }
+
+    /**
+     * Closes the search dialog when requested by the system (e.g. when a phone call comes in).
+     */
+    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
+                if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+                stopSearch();
+            } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
+                if (DBG) debug(Intent.ACTION_CONFIGURATION_CHANGED);
+                onConfigurationChanged();
+            }
+        }
+    };
+
+    //
+    // External API
+    //
+
+    /**
+     * Launches the search UI.
+     * Can be called from any thread.
+     *
+     * @see SearchManager#startSearch(String, boolean, ComponentName, Bundle, boolean)
+     */
+    public void startSearch(final String initialQuery,
+            final boolean selectInitialQuery,
+            final ComponentName launchActivity,
+            final Bundle appSearchData,
+            final boolean globalSearch,
+            final ISearchManagerCallback searchManagerCallback) {
+        if (DBG) debug("startSearch()");
+        Message msg = Message.obtain();
+        msg.what = MSG_START_SEARCH;
+        msg.arg1 = selectInitialQuery ? 1 : 0;
+        msg.arg2 = globalSearch ? 1 : 0;
+        msg.obj = searchManagerCallback;
+        Bundle msgData = msg.getData();
+        msgData.putString(KEY_INITIAL_QUERY, initialQuery);
+        msgData.putParcelable(KEY_LAUNCH_ACTIVITY, launchActivity);
+        msgData.putBundle(KEY_APP_SEARCH_DATA, appSearchData);
+        mSearchUiThread.sendMessage(msg);
+    }
+
+    /**
+     * Cancels the search dialog.
+     * Can be called from any thread.
+     */
+    public void stopSearch() {
+        if (DBG) debug("stopSearch()");
+        mSearchUiThread.sendEmptyMessage(MSG_STOP_SEARCH);
+    }
+
+    /**
+     * Updates the search UI in response to a configuration change.
+     * Can be called from any thread.
+     */
+    void onConfigurationChanged() {
+        if (DBG) debug("onConfigurationChanged()");
+        mSearchUiThread.sendEmptyMessage(MSG_ON_CONFIGURATION_CHANGED);
+    }
+
+    //
+    // Implementation methods that run on the search UI thread
+    //
+
+    private class SearchDialogHandler extends Handler {
+
+        public SearchDialogHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_INIT:
+                    init();
+                    break;
+                case MSG_START_SEARCH:
+                    handleStartSearchMessage(msg);
+                    break;
+                case MSG_STOP_SEARCH:
+                    performStopSearch();
+                    break;
+                case MSG_ON_CONFIGURATION_CHANGED:
+                    performOnConfigurationChanged();
+                    break;
+            }
+        }
+
+        private void handleStartSearchMessage(Message msg) {
+            Bundle msgData = msg.getData();
+            String initialQuery = msgData.getString(KEY_INITIAL_QUERY);
+            boolean selectInitialQuery = msg.arg1 != 0;
+            ComponentName launchActivity =
+                    (ComponentName) msgData.getParcelable(KEY_LAUNCH_ACTIVITY);
+            Bundle appSearchData = msgData.getBundle(KEY_APP_SEARCH_DATA);
+            boolean globalSearch = msg.arg2 != 0;
+            ISearchManagerCallback searchManagerCallback = (ISearchManagerCallback) msg.obj;
+            performStartSearch(initialQuery, selectInitialQuery, launchActivity,
+                    appSearchData, globalSearch, searchManagerCallback);
+        }
+
+    }
+
+    /**
+     * Actually launches the search UI.
+     * This must be called on the search UI thread.
+     */
+    void performStartSearch(String initialQuery,
+            boolean selectInitialQuery,
+            ComponentName launchActivity,
+            Bundle appSearchData,
+            boolean globalSearch,
+            ISearchManagerCallback searchManagerCallback) {
+        if (DBG) debug("performStartSearch()");
+
+        if (mDisabledOnBoot) {
+            Log.d(TAG, "ignoring start search request because " + DISABLE_SEARCH_PROPERTY
+                    + " system property is set.");
+            return;
+        }
+
+        registerBroadcastReceiver();
+        mCallback = searchManagerCallback;
+        mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData,
+                globalSearch);
+    }
+
+    /**
+     * Actually cancels the search UI.
+     * This must be called on the search UI thread.
+     */
+    void performStopSearch() {
+        if (DBG) debug("performStopSearch()");
+        mSearchDialog.cancel();
+    }
+
+    /**
+     * Must be called from the search UI thread.
+     */
+    void performOnConfigurationChanged() {
+        if (DBG) debug("performOnConfigurationChanged()");
+        mSearchDialog.onConfigurationChanged();
+    }
+
+    /**
+     * Called by {@link SearchDialog} when it goes away.
+     */
+    public void onDismiss(DialogInterface dialog) {
+        if (DBG) debug("onDismiss()");
+        if (mCallback != null) {
+            try {
+                // should be safe to do on the search UI thread, since it's a oneway interface
+                mCallback.onDismiss();
+            } catch (DeadObjectException ex) {
+                // The process that hosted the callback has died, do nothing
+            } catch (RemoteException ex) {
+                Log.e(TAG, "onDismiss() failed: " + ex);
+            }
+            // we don't need the callback anymore, release it
+            mCallback = null;
+        }
+        unregisterBroadcastReceiver();
+    }
+
+    /**
+     * Called by {@link SearchDialog} when the user or activity cancels search.
+     * Whenever this method is called, {@link #onDismiss} is always called afterwards.
+     */
+    public void onCancel(DialogInterface dialog) {
+        if (DBG) debug("onCancel()");
+        if (mCallback != null) {
+            try {
+                // should be safe to do on the search UI thread, since it's a oneway interface
+                mCallback.onCancel();
+            } catch (DeadObjectException ex) {
+                // The process that hosted the callback has died, do nothing
+            } catch (RemoteException ex) {
+                Log.e(TAG, "onCancel() failed: " + ex);
+            }
+        }
+    }
+
+    private static void debug(String msg) {
+        Thread thread = Thread.currentThread();
+        Log.d(TAG, msg + " (" + thread.getName() + "-" + thread.getId() + ")");
+    }
+}
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index 373e61f..87adfb3 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -18,52 +18,38 @@
 
 import android.app.ISearchManager;
 import android.app.ISearchManagerCallback;
-import android.app.SearchDialog;
 import android.app.SearchManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.text.TextUtils;
 import android.util.Log;
 
 import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
 
 /**
- * This is a simplified version of the Search Manager service.  It no longer handles
- * presentation (UI).  Its function is to maintain the map & list of "searchable"
- * items, which provides a mapping from individual activities (where a user might have
- * invoked search) to specific searchable activities (where the search will be dispatched).
+ * The search manager service handles the search UI, and maintains a registry of searchable
+ * activities.
  */
-public class SearchManagerService extends ISearchManager.Stub
-        implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener
-{
-        // general debugging support
+public class SearchManagerService extends ISearchManager.Stub {
+
+    // general debugging support
     private static final String TAG = "SearchManagerService";
     private static final boolean DBG = false;
 
-        // class maintenance and general shared data
+    // Context that the service is running in.
     private final Context mContext;
-    private final Handler mHandler;
-    private boolean mSearchablesDirty;
-    private final Searchables mSearchables;
 
-    final SearchDialog mSearchDialog;
-    ISearchManagerCallback mCallback = null;
+    // This field is initialized in initialize(), and then never modified.
+    // It is volatile since it can be accessed by multiple threads.
+    private volatile Searchables mSearchables;
 
-    private final boolean mDisabledOnBoot;
-
-    private static final String DISABLE_SEARCH_PROPERTY = "dev.disablesearchdialog";
+    // This field is initialized in initialize(), and then never modified.
+    // It is volatile since it can be accessed by multiple threads.
+    private volatile SearchDialogWrapper mSearchDialog;
 
     /**
      * Initializes the Search Manager service in the provided system context.
@@ -73,82 +59,71 @@
      */
     public SearchManagerService(Context context)  {
         mContext = context;
-        mHandler = new Handler();
-        mSearchablesDirty = true;
-        mSearchables = new Searchables(context);
-        mSearchDialog = new SearchDialog(context);
-        mSearchDialog.setOnCancelListener(this);
-        mSearchDialog.setOnDismissListener(this);
-
-        // Setup the infrastructure for updating and maintaining the list
-        // of searchable activities.
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
-        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-        filter.addDataScheme("package");
-        mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
-
-        // After startup settles down, preload the searchables list,
-        // which will reduce the delay when the search UI is invoked.
-        mHandler.post(mRunUpdateSearchable);
-
-        // allows disabling of search dialog for stress testing runs
-        mDisabledOnBoot = !TextUtils.isEmpty(SystemProperties.get(DISABLE_SEARCH_PROPERTY));
+        // call initialize() after all pending actions on the main system thread have finished
+        new Handler().post(new Runnable() {
+            public void run() {
+                initialize();
+            }
+        });
     }
 
     /**
-     * Listens for intent broadcasts.
-     *
-     * The primary purpose here is to refresh the "searchables" list
-     * if packages are added/removed.
+     * Initializes the search UI and the list of searchable activities.
      */
-    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+    void initialize() {
+        mSearchables = createSearchables();
+        mSearchDialog = new SearchDialogWrapper(mContext);
+    }
+
+    private Searchables createSearchables() {
+        Searchables searchables = new Searchables(mContext);
+        searchables.buildSearchableList();
+
+        IntentFilter packageFilter = new IntentFilter();
+        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        packageFilter.addDataScheme("package");
+        mContext.registerReceiver(mPackageChangedReceiver, packageFilter);
+
+        return searchables;
+    }
+
+    /**
+     * Refreshes the "searchables" list when packages are added/removed.
+     */
+    private BroadcastReceiver mPackageChangedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
 
-            // First, test for intents that matter at any time
-            if (action.equals(Intent.ACTION_PACKAGE_ADDED) ||
-                action.equals(Intent.ACTION_PACKAGE_REMOVED) ||
-                action.equals(Intent.ACTION_PACKAGE_CHANGED)) {
-                mSearchablesDirty = true;
-                mHandler.post(mRunUpdateSearchable);
-                return;
+            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
+                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
+                    Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
+                if (DBG) Log.d(TAG, "Got " + action);
+                // Dismiss search dialog, since the search context may no longer be valid
+                mSearchDialog.stopSearch();
+                // Update list of searchable activities
+                mSearchables.buildSearchableList();
+                broadcastSearchablesChanged();
             }
         }
     };
 
     /**
-     * This runnable (for the main handler / UI thread) will update the searchables list.
+     * Informs all listeners that the list of searchables has been updated.
      */
-    private Runnable mRunUpdateSearchable = new Runnable() {
-        public void run() {
-            updateSearchablesIfDirty();
-        }
-    };
-
-    /**
-     * Updates the list of searchables, either at startup or in response to
-     * a package add/remove broadcast message.
-     */
-    private void updateSearchables() {
-        if (DBG) debug("updateSearchables()");
-        mSearchables.buildSearchableList();
-        mSearchablesDirty = false;
+    void broadcastSearchablesChanged() {
+        mContext.sendBroadcast(
+                new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED));
     }
 
-    /**
-     * Updates the list of searchables if needed.
-     */
-    private void updateSearchablesIfDirty() {
-        if (mSearchablesDirty) {
-            updateSearchables();
-        }
-    }
+    //
+    // Searchable activities API
+    //
 
     /**
-     * Returns the SearchableInfo for a given activity
+     * Returns the SearchableInfo for a given activity.
      *
      * @param launchActivity The activity from which we're launching this search.
      * @param globalSearch If false, this will only launch the search that has been specifically
@@ -158,226 +133,84 @@
      * @return Returns a SearchableInfo record describing the parameters of the search,
      * or null if no searchable metadata was available.
      */
-    public SearchableInfo getSearchableInfo(ComponentName launchActivity, boolean globalSearch) {
-        updateSearchablesIfDirty();
-        SearchableInfo si = null;
+    public SearchableInfo getSearchableInfo(final ComponentName launchActivity,
+            final boolean globalSearch) {
+        if (mSearchables == null) return null;
         if (globalSearch) {
-            si = mSearchables.getDefaultSearchable();
+            return mSearchables.getDefaultSearchable();
         } else {
             if (launchActivity == null) {
                 Log.e(TAG, "getSearchableInfo(), activity == null");
                 return null;
             }
-            si = mSearchables.getSearchableInfo(launchActivity);
+            return mSearchables.getSearchableInfo(launchActivity);
         }
-
-        return si;
     }
 
     /**
      * Returns a list of the searchable activities that can be included in global search.
      */
     public List<SearchableInfo> getSearchablesInGlobalSearch() {
-        updateSearchablesIfDirty();
+        if (mSearchables == null) return null;
         return mSearchables.getSearchablesInGlobalSearchList();
     }
-    /**
-     * Launches the search UI on the main thread of the service.
-     *
-     * @see SearchManager#startSearch(String, boolean, ComponentName, Bundle, boolean)
-     */
-    public void startSearch(final String initialQuery,
-            final boolean selectInitialQuery,
-            final ComponentName launchActivity,
-            final Bundle appSearchData,
-            final boolean globalSearch,
-            final ISearchManagerCallback searchManagerCallback) {
-        if (DBG) debug("startSearch()");
-        Runnable task = new Runnable() {
-            public void run() {
-                performStartSearch(initialQuery,
-                        selectInitialQuery,
-                        launchActivity,
-                        appSearchData,
-                        globalSearch,
-                        searchManagerCallback);
-            }
-        };
-        mHandler.post(task);
-    }
 
     /**
-     * Actually launches the search. This must be called on the service UI thread.
+     * Returns a list of the searchable activities that handle web searches.
+     * Can be called from any thread.
      */
-    /*package*/ void performStartSearch(String initialQuery,
+    public List<SearchableInfo> getSearchablesForWebSearch() {
+        if (mSearchables == null) return null;
+        return mSearchables.getSearchablesForWebSearchList();
+    }
+
+    /**
+     * Returns the default searchable activity for web searches.
+     * Can be called from any thread.
+     */
+    public SearchableInfo getDefaultSearchableForWebSearch() {
+        if (mSearchables == null) return null;
+        return mSearchables.getDefaultSearchableForWebSearch();
+    }
+
+    /**
+     * Sets the default searchable activity for web searches.
+     * Can be called from any thread.
+     */
+    public void setDefaultWebSearch(final ComponentName component) {
+        if (mSearchables == null) return;
+        mSearchables.setDefaultWebSearch(component);
+        broadcastSearchablesChanged();
+    }
+
+    // Search UI API
+
+    /**
+     * Launches the search UI. Can be called from any thread.
+     *
+     * @see SearchManager#startSearch(String, boolean, ComponentName, Bundle, boolean)
+     */
+    public void startSearch(String initialQuery,
             boolean selectInitialQuery,
             ComponentName launchActivity,
             Bundle appSearchData,
             boolean globalSearch,
             ISearchManagerCallback searchManagerCallback) {
-        if (DBG) debug("performStartSearch()");
-
-        if (mDisabledOnBoot) {
-            Log.d(TAG, "ignoring start search request because " + DISABLE_SEARCH_PROPERTY
-                    + " system property is set.");
-            return;
-        }
-
-        mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData,
-                globalSearch);
-        if (searchManagerCallback != null) {
-            mCallback = searchManagerCallback;
-        }
+        if (mSearchDialog == null) return;
+        mSearchDialog.startSearch(initialQuery,
+                selectInitialQuery,
+                launchActivity,
+                appSearchData,
+                globalSearch,
+                searchManagerCallback);
     }
 
     /**
      * Cancels the search dialog. Can be called from any thread.
      */
     public void stopSearch() {
-        if (DBG) debug("stopSearch()");
-        mHandler.post(new Runnable() {
-            public void run() {
-                performStopSearch();
-            }
-        });
-    }
-
-    /**
-     * Cancels the search dialog. Must be called from the service UI thread.
-     */
-    /*package*/ void performStopSearch() {
-        if (DBG) debug("performStopSearch()");
-        mSearchDialog.cancel();
-    }
-
-    /**
-     * Determines if the Search UI is currently displayed.
-     *
-     * @see SearchManager#isVisible()
-     */
-    public boolean isVisible() {
-        return postAndWait(mIsShowing, false, "isShowing()");
-    }
-
-    private final Callable<Boolean> mIsShowing = new Callable<Boolean>() {
-        public Boolean call() {
-            return mSearchDialog.isShowing();
-        }
-    };
-
-    public Bundle onSaveInstanceState() {
-        return postAndWait(mOnSaveInstanceState, null, "onSaveInstanceState()");
-    }
-
-    private final Callable<Bundle> mOnSaveInstanceState = new Callable<Bundle>() {
-        public Bundle call() {
-            if (mSearchDialog.isShowing()) {
-                return mSearchDialog.onSaveInstanceState();
-            } else {
-                return null;
-            }
-        }
-    };
-
-    public void onRestoreInstanceState(final Bundle searchDialogState) {
-        if (searchDialogState != null) {
-            mHandler.post(new Runnable() {
-                public void run() {
-                    mSearchDialog.onRestoreInstanceState(searchDialogState);
-                }
-            });
-        }
-    }
-
-    public void onConfigurationChanged(final Configuration newConfig) {
-        mHandler.post(new Runnable() {
-            public void run() {
-                if (mSearchDialog.isShowing()) {
-                    mSearchDialog.onConfigurationChanged(newConfig);
-                }
-            }
-        });
-    }
-
-    /**
-     * Called by {@link SearchDialog} when it goes away.
-     */
-    public void onDismiss(DialogInterface dialog) {
-        if (DBG) debug("onDismiss()");
-        if (mCallback != null) {
-            try {
-                mCallback.onDismiss();
-            } catch (RemoteException ex) {
-                Log.e(TAG, "onDismiss() failed: " + ex);
-            }
-        }
-    }
-
-    /**
-     * Called by {@link SearchDialog} when the user or activity cancels search.
-     * When this is called, {@link #onDismiss} is called too.
-     */
-    public void onCancel(DialogInterface dialog) {
-        if (DBG) debug("onCancel()");
-        if (mCallback != null) {
-            try {
-                mCallback.onCancel();
-            } catch (RemoteException ex) {
-                Log.e(TAG, "onCancel() failed: " + ex);
-            }
-        }
-    }
-
-    /**
-     * Returns a list of the searchable activities that handle web searches.
-     */
-    public List<SearchableInfo> getSearchablesForWebSearch() {
-        updateSearchablesIfDirty();
-        return mSearchables.getSearchablesForWebSearchList();
-    }
-
-    /**
-     * Returns the default searchable activity for web searches.
-     */
-    public SearchableInfo getDefaultSearchableForWebSearch() {
-        updateSearchablesIfDirty();
-        return mSearchables.getDefaultSearchableForWebSearch();
-    }
-
-    /**
-     * Sets the default searchable activity for web searches.
-     */
-    public void setDefaultWebSearch(ComponentName component) {
-        mSearchables.setDefaultWebSearch(component);
-    }
-
-    /**
-     * Runs an operation on the handler for the service, blocks until it returns,
-     * and returns the value returned by the operation.
-     *
-     * @param <V> Return value type.
-     * @param callable Operation to run.
-     * @param errorResult Value to return if the operations throws an exception.
-     * @param name Operation name to include in error log messages.
-     * @return The value returned by the operation.
-     */
-    private <V> V postAndWait(Callable<V> callable, V errorResult, String name) {
-        FutureTask<V> task = new FutureTask<V>(callable);
-        mHandler.post(task);
-        try {
-            return task.get();
-        } catch (InterruptedException ex) {
-            Log.e(TAG, "Error calling " + name + ": " + ex);
-            return errorResult;
-        } catch (ExecutionException ex) {
-            Log.e(TAG, "Error calling " + name + ": " + ex);
-            return errorResult;
-        }
-    }
-
-    private static void debug(String msg) {
-        Thread thread = Thread.currentThread();
-        Log.d(TAG, msg + " (" + thread.getName() + "-" + thread.getId() + ")");
+        if (mSearchDialog == null) return;
+        mSearchDialog.stopSearch();
     }
 
 }
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index 8ef1f15..283555a 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -67,6 +67,7 @@
     private final int mSearchImeOptions;
     private final boolean mIncludeInGlobalSearch;
     private final boolean mQueryAfterZeroResults;
+    private final boolean mAutoUrlDetect;
     private final String mSettingsDescription;
     private final String mSuggestAuthority;
     private final String mSuggestPath;
@@ -288,6 +289,8 @@
                 com.android.internal.R.styleable.Searchable_includeInGlobalSearch, false);
         mQueryAfterZeroResults = a.getBoolean(
                 com.android.internal.R.styleable.Searchable_queryAfterZeroResults, false);
+        mAutoUrlDetect = a.getBoolean(
+                com.android.internal.R.styleable.Searchable_autoUrlDetect, false);
 
         mSettingsDescription = a.getString(
                 com.android.internal.R.styleable.Searchable_searchSettingsDescription);
@@ -667,6 +670,16 @@
     }
 
     /**
+     * Checks whether this searchable activity has auto URL detect turned on.
+     *
+     * @return The value of the <code>autoUrlDetect</code> attribute,
+     *         or <code>false</code> if the attribute is not set.
+     */
+    public boolean autoUrlDetect() {
+        return mAutoUrlDetect;
+    }
+
+    /**
      * Support for parcelable and aidl operations.
      */
     public static final Parcelable.Creator<SearchableInfo> CREATOR
@@ -698,6 +711,7 @@
         mSearchImeOptions = in.readInt();
         mIncludeInGlobalSearch = in.readInt() != 0;
         mQueryAfterZeroResults = in.readInt() != 0;
+        mAutoUrlDetect = in.readInt() != 0;
         
         mSettingsDescription = in.readString();
         mSuggestAuthority = in.readString();
@@ -735,6 +749,7 @@
         dest.writeInt(mSearchImeOptions);
         dest.writeInt(mIncludeInGlobalSearch ? 1 : 0);
         dest.writeInt(mQueryAfterZeroResults ? 1 : 0);
+        dest.writeInt(mAutoUrlDetect ? 1 : 0);
         
         dest.writeString(mSettingsDescription);
         dest.writeString(mSuggestAuthority);
diff --git a/core/java/android/server/search/Searchables.java b/core/java/android/server/search/Searchables.java
index c7cc8ed..b959907 100644
--- a/core/java/android/server/search/Searchables.java
+++ b/core/java/android/server/search/Searchables.java
@@ -17,7 +17,6 @@
 package android.server.search;
 
 import com.android.internal.app.ResolverActivity;
-import com.android.internal.R;
 
 import android.app.SearchManager;
 import android.content.ComponentName;
@@ -27,7 +26,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
 import android.os.Bundle;
 import android.util.Log;
 
@@ -264,7 +262,7 @@
         }
 
         // Find the default web search provider.
-        ComponentName webSearchActivity = getPreferredWebSearchActivity();
+        ComponentName webSearchActivity = getPreferredWebSearchActivity(mContext);
         SearchableInfo newDefaultSearchableForWebSearch = null;
         if (webSearchActivity != null) {
             newDefaultSearchableForWebSearch = newSearchablesMap.get(webSearchActivity);
@@ -283,9 +281,6 @@
             mDefaultSearchable = newDefaultSearchable;
             mDefaultSearchableForWebSearch = newDefaultSearchableForWebSearch;
         }
-
-        // Inform all listeners that the list of searchables has been updated.
-        mContext.sendBroadcast(new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED));
     }
 
     /**
@@ -295,9 +290,10 @@
      * @param action Intent action for which this activity is to be set as preferred.
      * @return true if component was detected and set as preferred activity, false if not.
      */
-    private boolean setPreferredActivity(ComponentName component, String action) {
+    private static boolean setPreferredActivity(Context context,
+            ComponentName component, String action) {
         Log.d(LOG_TAG, "Checking component " + component);
-        PackageManager pm = mContext.getPackageManager();
+        PackageManager pm = context.getPackageManager();
         ActivityInfo ai;
         try {
             ai = pm.getActivityInfo(component, 0);
@@ -326,10 +322,10 @@
         return true;
     }
 
-    public ComponentName getPreferredWebSearchActivity() {
+    private static ComponentName getPreferredWebSearchActivity(Context context) {
         // Check if we have a preferred web search activity.
         Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
-        PackageManager pm = mContext.getPackageManager();
+        PackageManager pm = context.getPackageManager();
         ResolveInfo ri = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
 
         if (ri == null || ri.activityInfo.name.equals(ResolverActivity.class.getName())) {
@@ -338,11 +334,11 @@
             // The components in the providers array are checked in the order of declaration so the
             // first one has the highest priority. If the component exists in the system it is set
             // as the preferred activity to handle intent action web search.
-            String[] preferredActivities = mContext.getResources().getStringArray(
+            String[] preferredActivities = context.getResources().getStringArray(
                     com.android.internal.R.array.default_web_search_providers);
             for (String componentName : preferredActivities) {
                 ComponentName component = ComponentName.unflattenFromString(componentName);
-                if (setPreferredActivity(component, Intent.ACTION_WEB_SEARCH)) {
+                if (setPreferredActivity(context, component, Intent.ACTION_WEB_SEARCH)) {
                     return component;
                 }
             }
@@ -354,7 +350,8 @@
             if (cn.flattenToShortString().equals(GOOGLE_SEARCH_COMPONENT_NAME)) {
                 ComponentName enhancedGoogleSearch = ComponentName.unflattenFromString(
                         ENHANCED_GOOGLE_SEARCH_COMPONENT_NAME);
-                if (setPreferredActivity(enhancedGoogleSearch, Intent.ACTION_WEB_SEARCH)) {
+                if (setPreferredActivity(context, enhancedGoogleSearch,
+                        Intent.ACTION_WEB_SEARCH)) {
                     return enhancedGoogleSearch;
                 }
             }
@@ -397,7 +394,7 @@
      * Sets the default searchable activity for web searches.
      */
     public synchronized void setDefaultWebSearch(ComponentName component) {
-        setPreferredActivity(component, Intent.ACTION_WEB_SEARCH);
+        setPreferredActivity(mContext, component, Intent.ACTION_WEB_SEARCH);
         buildSearchableList();
     }
 }
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 616b3f1..ed1e4ff 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -107,9 +107,7 @@
         public static final int FALLBACK_TTS_DEFAULT_RATE = 100; // 1x
         public static final int FALLBACK_TTS_DEFAULT_PITCH = 100;// 1x
         public static final int FALLBACK_TTS_USE_DEFAULTS = 0; // false
-        public static final String FALLBACK_TTS_DEFAULT_LANG = "eng";
-        public static final String FALLBACK_TTS_DEFAULT_COUNTRY = "";
-        public static final String FALLBACK_TTS_DEFAULT_VARIANT = "";
+        public static final String FALLBACK_TTS_DEFAULT_SYNTH = "com.svox.pico";
 
         // return codes for a TTS engine's check data activity
         public static final int CHECK_VOICE_DATA_PASS = 1;
@@ -608,6 +606,7 @@
                 result = mITts.setLanguage(mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1],
                         mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1],
                         mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] );
+            } catch (RemoteException e) {
                 // TTS died; restart it.
                 mStarted = false;
                 initTts();
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 4179edb..9071bf0 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -109,7 +109,6 @@
      */
     public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation,
             int screenLayout) {
-        int xOffset = 0;
         if (!compatibilityInfo.isConfiguredExpandable()) {
             // Note: this assume that configuration is updated before calling
             // updateMetrics method.
@@ -142,7 +141,6 @@
                 
                 if (defaultWidth < widthPixels) {
                     // content/window's x offset in original pixels
-                    xOffset = ((widthPixels - defaultWidth) / 2);
                     widthPixels = defaultWidth;
                 }
                 if (defaultHeight < heightPixels) {
@@ -154,7 +152,6 @@
                 compatibilityInfo.setExpandable(true);
             }
         }
-        compatibilityInfo.setVisibleRect(xOffset, widthPixels, heightPixels);
         if (compatibilityInfo.isScalingRequired()) {
             float invertedRatio = compatibilityInfo.applicationInvertedScale;
             density *= invertedRatio;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 45b0f0a..ff1eb53 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -306,7 +306,7 @@
 
         // Use original size if the app specified the size of the view,
         // and let the flinger to scale up.
-        if (mRequestedWidth <= 0 && mTranslator != null && mTranslator.scalingRequired) {
+        if (mRequestedWidth <= 0 && mTranslator != null) {
             myWidth *= appScale;
             myHeight *= appScale;
         }
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 6f6e224..6bcb135 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -385,6 +385,7 @@
             if (mView == null) {
                 mView = view;
                 mWindowAttributes.copyFrom(attrs);
+                attrs = mWindowAttributes;
 
                 CompatibilityInfo compatibilityInfo =
                         mView.getContext().getResources().getCompatibilityInfo();
@@ -397,11 +398,14 @@
                 }
                 if (DEBUG_LAYOUT) Log.d(TAG, "WindowLayout in setView:" + attrs);
 
+                if (!compatibilityInfo.supportsScreen()) {
+                    attrs.flags |= WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
+                }
+
                 mSoftInputMode = attrs.softInputMode;
                 mWindowAttributesChanged = true;
                 mAttachInfo.mRootView = view;
-                mAttachInfo.mScalingRequired =
-                        mTranslator == null ? false : mTranslator.scalingRequired;
+                mAttachInfo.mScalingRequired = mTranslator == null ? false : true;
                 mAttachInfo.mApplicationScale =
                         mTranslator == null ? 1.0f : mTranslator.applicationScale;
                 if (panelParentView != null) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index bdb86d7..e96a15b 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -484,11 +484,19 @@
         public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;
 
         /** Window flag: special flag to let a window ignore the compatibility scaling.
-         * This is used by SurfaceView to create a window that does not scale the content.
+         * This is used by SurfaceView to pass this info into ViewRoot, and not used
+         * by WindowManager.
          *
          * {@hide} */
         public static final int FLAG_NO_COMPATIBILITY_SCALING = 0x00100000;
 
+        /** Window flag: special flag to limit the size of the window to be
+         * original size ([320x480] x density). Used to create window for applications
+         * running under compatibility mode.
+         *
+         * {@hide} */
+        public static final int FLAG_COMPATIBLE_WINDOW = 0x00200000;
+
         /** Window flag: a special option intended for system dialogs.  When
          * this flag is set, the window will demand focus unconditionally when
          * it is created.
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 670692f..df957ac 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -65,6 +65,7 @@
      */
     public static final int LENGTH_LONG = 1;
 
+    final Handler mHandler = new Handler();    
     final Context mContext;
     final TN mTN;
     int mDuration;
@@ -84,7 +85,7 @@
      */
     public Toast(Context context) {
         mContext = context;
-        mTN = new TN(context);
+        mTN = new TN();
         mY = context.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.toast_y_offset);
     }
@@ -229,7 +230,8 @@
     public static Toast makeText(Context context, CharSequence text, int duration) {
         Toast result = new Toast(context);
 
-        LayoutInflater inflate = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        LayoutInflater inflate = (LayoutInflater)
+                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
         TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
         tv.setText(text);
@@ -286,8 +288,7 @@
 
     private static INotificationManager sService;
 
-    static private INotificationManager getService()
-    {
+    static private INotificationManager getService() {
         if (sService != null) {
             return sService;
         }
@@ -295,28 +296,42 @@
         return sService;
     }
 
-    private class TN extends ITransientNotification.Stub
-    {
-        TN(Context context)
-        {
+    private class TN extends ITransientNotification.Stub {
+        final Runnable mShow = new Runnable() {
+            public void run() {
+                handleShow();
+            }
+        };
+
+        final Runnable mHide = new Runnable() {
+            public void run() {
+                handleHide();
+            }
+        };
+
+        private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
+        
+        WindowManagerImpl mWM;
+
+        TN() {
             // XXX This should be changed to use a Dialog, with a Theme.Toast
             // defined that sets up the layout params appropriately.
-            mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
-            mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
-            mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+            final WindowManager.LayoutParams params = mParams;
+            params.height = WindowManager.LayoutParams.WRAP_CONTENT;
+            params.width = WindowManager.LayoutParams.WRAP_CONTENT;
+            params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                     | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
-            mParams.format = PixelFormat.TRANSLUCENT;
-            mParams.windowAnimations = com.android.internal.R.style.Animation_Toast;
-            mParams.type = WindowManager.LayoutParams.TYPE_TOAST;
-            mParams.setTitle("Toast");
+            params.format = PixelFormat.TRANSLUCENT;
+            params.windowAnimations = com.android.internal.R.style.Animation_Toast;
+            params.type = WindowManager.LayoutParams.TYPE_TOAST;
+            params.setTitle("Toast");
         }
 
         /**
          * schedule handleShow into the right thread
          */
-        public void show()
-        {
+        public void show() {
             if (localLOGV) Log.v(TAG, "SHOW: " + this);
             mHandler.post(mShow);
         }
@@ -324,14 +339,12 @@
         /**
          * schedule handleHide into the right thread
          */
-        public void hide()
-        {
+        public void hide() {
             if (localLOGV) Log.v(TAG, "HIDE: " + this);
             mHandler.post(mHide);
         }
 
-        public void handleShow()
-        {
+        public void handleShow() {
             if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView
                     + " mNextView=" + mNextView);
             if (mView != mNextView) {
@@ -361,8 +374,7 @@
             }
         }
 
-        public void handleHide()
-        {
+        public void handleHide() {
             if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView);
             if (mView != null) {
                 // note: checking parent() just to make sure the view has
@@ -377,24 +389,5 @@
                 mView = null;
             }
         }
-
-        Runnable mShow = new Runnable() {
-            public void run() {
-                handleShow();
-            }
-        };
-
-        Runnable mHide = new Runnable() {
-            public void run() {
-                handleHide();
-            }
-        };
-
-        private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
-        
-        WindowManagerImpl mWM;
     }
-
-    final Handler mHandler = new Handler();
 }
-
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 77a8a72..57b5aa6 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -55,6 +55,7 @@
     ~JNICameraContext() { release(); }
     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2);
     virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr);
+    virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
     sp<Camera> getCamera() { Mutex::Autolock _l(mLock); return mCamera; }
     void release();
 
@@ -188,6 +189,12 @@
     }
 }
 
+void JNICameraContext::postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
+{
+    // TODO: plumb up to Java. For now, just drop the timestamp
+    postData(msgType, dataPtr);
+}
+
 // connect to camera service
 static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)
 {
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 6f2a5d3..fd78f83 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2888,6 +2888,14 @@
              attribute.</i> -->
         <attr name="searchSettingsDescription" format="string" />
 
+        <!-- If provided and <code>true</code>, URLs entered in the search dialog while searching
+             within this activity would be detected and treated as URLs (show a 'go' button in the
+             keyboard and invoke the browser directly when user launches the URL instead of passing
+             the URL to the activity). If set to <code>false</code> any URLs entered are treated as
+             normal query text.
+             The default value is <code>false</code>. <i>Optional attribute.</i>. -->
+        <attr name="autoUrlDetect" format="boolean" />
+
     </declare-styleable>
 
     <!-- In order to process special action keys during search, you must define them using
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 32c6937..871c651 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1125,6 +1125,7 @@
   <public type="attr" name="progressBarStyleLargeInverse" /> 
   <public type="attr" name="searchSettingsDescription" />
   <public type="attr" name="textColorPrimaryInverseDisableOnly" />
+  <public type="attr" name="autoUrlDetect" />
 
   <public-padding type="attr" name="donut_resource_pad" end="0x0101029f" />
 
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 0bd3276..a3579c7 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -143,8 +143,6 @@
     <!-- This is a list of all the libraries available for application
          code to link against. -->
 
-    <library name="android.awt"
-            file="/system/framework/android.awt.jar" />
     <library name="android.test.runner"
             file="/system/framework/android.test.runner.jar" />
     <library name="com.android.im.plugin"
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index d24194f..6677a35 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -278,10 +278,15 @@
         if (name.equals("padding")) {
             TypedArray a = r.obtainAttributes(attrs,
                     com.android.internal.R.styleable.ShapeDrawablePadding);
-            setPadding(a.getInt(com.android.internal.R.styleable.ShapeDrawablePadding_left, 0),
-                       a.getInt(com.android.internal.R.styleable.ShapeDrawablePadding_top, 0),
-                       a.getInt(com.android.internal.R.styleable.ShapeDrawablePadding_right, 0),
-                       a.getInt(com.android.internal.R.styleable.ShapeDrawablePadding_bottom, 0));
+            setPadding(
+                    a.getDimensionPixelOffset(
+                            com.android.internal.R.styleable.ShapeDrawablePadding_left, 0),
+                    a.getDimensionPixelOffset(
+                            com.android.internal.R.styleable.ShapeDrawablePadding_top, 0),
+                    a.getDimensionPixelOffset(
+                            com.android.internal.R.styleable.ShapeDrawablePadding_right, 0),
+                    a.getDimensionPixelOffset(
+                            com.android.internal.R.styleable.ShapeDrawablePadding_bottom, 0));
             a.recycle();
             return true;
         }
diff --git a/include/ui/Camera.h b/include/ui/Camera.h
index e3544ab..afb07b5 100644
--- a/include/ui/Camera.h
+++ b/include/ui/Camera.h
@@ -18,6 +18,7 @@
 #ifndef ANDROID_HARDWARE_CAMERA_H
 #define ANDROID_HARDWARE_CAMERA_H
 
+#include <utils/Timers.h>
 #include <ui/ICameraClient.h>
 
 namespace android {
@@ -94,6 +95,7 @@
 public:
     virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
     virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr) = 0;
+    virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
 };
 
 class Camera : public BnCameraClient, public IBinder::DeathRecipient
@@ -155,6 +157,7 @@
     // ICameraClient interface
     virtual void        notifyCallback(int32_t msgType, int32_t ext, int32_t ext2);
     virtual void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr);
+    virtual void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
 
     sp<ICamera>         remote();
 
diff --git a/include/ui/CameraHardwareInterface.h b/include/ui/CameraHardwareInterface.h
index 73036f0..822b4a8 100644
--- a/include/ui/CameraHardwareInterface.h
+++ b/include/ui/CameraHardwareInterface.h
@@ -28,7 +28,7 @@
 typedef void (*preview_callback)(const sp<IMemory>& mem, void* user);
 
 /** Callback for startRecord() */
-typedef void (*recording_callback)(const sp<IMemory>& mem, void* user);
+typedef void (*recording_callback)(nsecs_t timestamp, const sp<IMemory>& mem, void* user);
 
 /** Callback for takePicture() */
 typedef void (*shutter_callback)(void* user);
diff --git a/include/ui/ICameraClient.h b/include/ui/ICameraClient.h
index c4bdd07..1001c71 100644
--- a/include/ui/ICameraClient.h
+++ b/include/ui/ICameraClient.h
@@ -21,6 +21,7 @@
 #include <utils/IInterface.h>
 #include <utils/Parcel.h>
 #include <utils/IMemory.h>
+#include <utils/Timers.h>
 
 namespace android {
 
@@ -31,7 +32,7 @@
 
     virtual void            notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) = 0;
     virtual void            dataCallback(int32_t msgType, const sp<IMemory>& data) = 0;
-
+    virtual void            dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& data) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index 975594f..5015379 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -310,6 +310,19 @@
     }
 }
 
+// callback from camera service when timestamped frame is ready
+void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
+{
+    sp<CameraListener> listener;
+    {
+        Mutex::Autolock _l(mLock);
+        listener = mListener;
+    }
+    if (listener != NULL) {
+        listener->postDataTimestamp(timestamp, msgType, dataPtr);
+    }
+}
+
 void Camera::binderDied(const wp<IBinder>& who) {
     LOGW("ICamera died");
     notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp
index c6cf75c..59a6cf2 100644
--- a/libs/ui/ICameraClient.cpp
+++ b/libs/ui/ICameraClient.cpp
@@ -27,6 +27,7 @@
 enum {
     NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
     DATA_CALLBACK,
+    DATA_CALLBACK_TIMESTAMP,
 };
 
 class BpCameraClient: public BpInterface<ICameraClient>
@@ -60,6 +61,17 @@
         remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY);
     }
 
+    // generic data callback from camera service to app with image data
+    void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
+    {
+        LOGV("dataCallback");
+        Parcel data, reply;
+        data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
+        data.writeInt64(timestamp);
+        data.writeInt32(msgType);
+        data.writeStrongBinder(imageData->asBinder());
+        remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient");
@@ -86,13 +98,22 @@
             return NO_ERROR;
         } break;
         case DATA_CALLBACK: {
-            LOGV("RAW_CALLBACK");
+            LOGV("DATA_CALLBACK");
             CHECK_INTERFACE(ICameraClient, data, reply);
             int32_t msgType = data.readInt32();
             sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
             dataCallback(msgType, imageData);
             return NO_ERROR;
         } break;
+        case DATA_CALLBACK_TIMESTAMP: {
+            LOGV("DATA_CALLBACK_TIMESTAMP");
+            CHECK_INTERFACE(ICameraClient, data, reply);
+            nsecs_t timestamp = data.readInt64();
+            int32_t msgType = data.readInt32();
+            sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
+            dataCallbackTimestamp(timestamp, msgType, imageData);
+            return NO_ERROR;
+        } break;
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index cfdf5e3..a65a417 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1063,6 +1063,21 @@
         }
     }
 
+    /**
+     *  @hide
+     *  Reload audio settings. This method is called by Settings backup
+     *  agent when audio settings are restored and causes the AudioService
+     *  to read and apply restored settings.
+     */
+    public void reloadAudioSettings() {
+        IAudioService service = getService();
+        try {
+            service.reloadAudioSettings();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Dead object in reloadAudioSettings"+e);
+        }
+    }
+
      /**
       * {@hide}
       */
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 937baad..ee41021 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -508,14 +508,14 @@
     /** @see AudioManager#setRingerMode(int) */
     public void setRingerMode(int ringerMode) {
         if (ringerMode != mRingerMode) {
-            setRingerModeInt(ringerMode);
+            setRingerModeInt(ringerMode, true);
 
             // Send sticky broadcast
             broadcastRingerMode();
         }
     }
 
-    private void setRingerModeInt(int ringerMode) {
+    private void setRingerModeInt(int ringerMode, boolean persist) {
         mRingerMode = ringerMode;
 
         // Adjust volumes via posting message
@@ -543,8 +543,10 @@
         }
         
         // Post a persist ringer mode msg
-        sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, SHARED_MSG,
-                SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
+        if (persist) {
+            sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, SHARED_MSG,
+                    SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
+        }
     }
 
     /** @see AudioManager#shouldVibrate(int) */
@@ -914,6 +916,46 @@
         }
     }
 
+    /** @see AudioManager#reloadAudioSettings() */
+    public void reloadAudioSettings() {
+        // restore ringer mode, ringer mode affected streams, mute affected streams and vibrate settings
+        readPersistedSettings();
+
+        // restore volume settings
+        int numStreamTypes = AudioSystem.getNumStreamTypes();
+        for (int streamType = 0; streamType < numStreamTypes; streamType++) {
+            VolumeStreamState streamState = mStreamStates[streamType];
+
+            // there is no volume setting for STREAM_BLUETOOTH_SCO
+            if (streamType != AudioSystem.STREAM_BLUETOOTH_SCO) {
+                String settingName = System.VOLUME_SETTINGS[streamType];
+                String lastAudibleSettingName = settingName + System.APPEND_FOR_LAST_AUDIBLE;
+
+                streamState.mIndex = streamState.getValidIndex(Settings.System.getInt(mContentResolver,
+                        settingName,
+                        AudioManager.DEFAULT_STREAM_VOLUME[streamType]));
+                streamState.mLastAudibleIndex = streamState.getValidIndex(Settings.System.getInt(mContentResolver,
+                        lastAudibleSettingName,
+                        streamState.mIndex > 0 ? streamState.mIndex : AudioManager.DEFAULT_STREAM_VOLUME[streamType]));
+            }
+            // unmute stream that whas muted but is not affect by mute anymore
+            if (streamState.muteCount() != 0 && !isStreamAffectedByMute(streamType)) {
+                int size = streamState.mDeathHandlers.size();
+                for (int i = 0; i < size; i++) {
+                    streamState.mDeathHandlers.get(i).mMuteCount = 1;
+                    streamState.mDeathHandlers.get(i).mute(false);
+                }
+            }
+            // apply stream volume
+            if (streamState.muteCount() == 0) {
+                AudioSystem.setVolume(streamType, streamState.mVolumes[streamState.mIndex]);
+            }
+        }
+
+        // apply new ringer mode
+        setRingerModeInt(getRingerMode(), false);
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // Internal methods
     ///////////////////////////////////////////////////////////////////////////
@@ -1426,7 +1468,7 @@
              * Ensure all stream types that should be affected by ringer mode
              * are in the proper state.
              */
-            setRingerModeInt(getRingerMode());
+            setRingerModeInt(getRingerMode(), false);
         }
         
     }
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index f5e242d..9a8264f 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -71,4 +71,5 @@
   
     oneway void unloadSoundEffects();
 
+    oneway void reloadAudioSettings();
 }
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 3b82284..6e28515 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -810,17 +810,25 @@
 
                 // Now propagate the newly-backed-up data to the transport
                 if (success) {
-                    if (DEBUG) Log.v(TAG, "doBackup() success; calling transport");
-                    backupData =
-                        ParcelFileDescriptor.open(backupDataName, ParcelFileDescriptor.MODE_READ_ONLY);
-                    if (!transport.performBackup(packInfo, backupData)) {
-                        // STOPSHIP TODO: handle errors
-                        Log.e(TAG, "Backup failure in performBackup()");
+                    if (DEBUG) Log.v(TAG, "doBackup() success");
+                    if (backupDataName.length() > 0) {
+                        backupData =
+                            ParcelFileDescriptor.open(backupDataName,
+                                    ParcelFileDescriptor.MODE_READ_ONLY);
+                        if (!transport.performBackup(packInfo, backupData)) {
+                            // STOPSHIP TODO: handle errors
+                            Log.e(TAG, "Backup failure in performBackup()");
+                        }
+                    } else {
+                        if (DEBUG) {
+                            Log.i(TAG, "no backup data written; not calling transport");
+                        }
                     }
 
-                    // !!! TODO: After successful transport, delete the now-stale data
-                    // and juggle the files so that next time the new state is passed
-                    //backupDataName.delete();
+                    // After successful transport, delete the now-stale data
+                    // and juggle the files so that next time we supply the agent
+                    // with the new state file it just created.
+                    backupDataName.delete();
                     newStateName.renameTo(savedStateName);
                 }
             } catch (Exception e) {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 2dd70ef..ad882a9 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -53,6 +53,7 @@
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
+import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Matrix;
 import android.graphics.PixelFormat;
@@ -417,7 +418,13 @@
 
     final Configuration mTempConfiguration = new Configuration();
     int screenLayout = Configuration.SCREENLAYOUT_UNDEFINED;
-    
+
+    // The frame use to limit the size of the app running in compatibility mode.
+    Rect mCompatibleScreenFrame = new Rect();
+    // The surface used to fill the outer rim of the app running in compatibility mode.
+    Surface mBackgroundFillerSurface = null;
+    boolean mBackgroundFillerShown = false;
+
     public static WindowManagerService main(Context context,
             PowerManagerService pm, boolean haveInputMethods) {
         WMThread thr = new WMThread(context, pm, haveInputMethods);
@@ -3738,12 +3745,14 @@
         }
         config.orientation = orientation;
         
+        DisplayMetrics dm = new DisplayMetrics();
+        mDisplay.getMetrics(dm);
+        CompatibilityInfo.updateCompatibleScreenFrame(dm, orientation, mCompatibleScreenFrame);
+
         if (screenLayout == Configuration.SCREENLAYOUT_UNDEFINED) {
             // Note we only do this once because at this point we don't
             // expect the screen to change in this way at runtime, and want
             // to avoid all of this computation for every config change.
-            DisplayMetrics dm = new DisplayMetrics();
-            mDisplay.getMetrics(dm);
             int longSize = dw;
             int shortSize = dh;
             if (longSize < shortSize) {
@@ -3753,7 +3762,7 @@
             }
             longSize = (int)(longSize/dm.density);
             shortSize = (int)(shortSize/dm.density);
-            
+
             // These semi-magic numbers define our compatibility modes for
             // applications with different screens.  Don't change unless you
             // make sure to test lots and lots of apps!
@@ -5845,8 +5854,19 @@
         public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
             mHaveFrame = true;
 
-            final int pw = pf.right-pf.left;
-            final int ph = pf.bottom-pf.top;
+            final Rect container = mContainingFrame;
+            container.set(pf);
+
+            final Rect display = mDisplayFrame;
+            display.set(df);
+
+            if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW) != 0) {
+                container.intersect(mCompatibleScreenFrame);
+                display.intersect(mCompatibleScreenFrame);
+            }
+
+            final int pw = container.right - container.left;
+            final int ph = container.bottom - container.top;
 
             int w,h;
             if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
@@ -5857,12 +5877,6 @@
                 h = mAttrs.height== mAttrs.FILL_PARENT ? ph : mRequestedHeight;
             }
 
-            final Rect container = mContainingFrame;
-            container.set(pf);
-
-            final Rect display = mDisplayFrame;
-            display.set(df);
-
             final Rect content = mContentFrame;
             content.set(cf);
 
@@ -5882,7 +5896,7 @@
 
             // Now make sure the window fits in the overall display.
             Gravity.applyDisplay(mAttrs.gravity, df, frame);
-
+            
             // Make sure the content and visible frames are inside of the
             // final window frame.
             if (content.left < frame.left) content.left = frame.left;
@@ -6573,16 +6587,29 @@
             return false;
         }
 
-        boolean isFullscreenOpaque(int screenWidth, int screenHeight) {
-            if (mAttrs.format != PixelFormat.OPAQUE || mSurface == null
-                    || mAnimation != null || mDrawPending || mCommitDrawPending) {
-                return false;
-            }
-            if (mFrame.left <= 0 && mFrame.top <= 0 &&
-                mFrame.right >= screenWidth && mFrame.bottom >= screenHeight) {
-                return true;
-            }
-            return false;
+        /**
+         * Return true if the window is opaque and fully drawn.
+         */
+        boolean isOpaqueDrawn() {
+            return mAttrs.format == PixelFormat.OPAQUE && mSurface != null
+                    && mAnimation == null && !mDrawPending && !mCommitDrawPending;
+        }
+
+        boolean needsBackgroundFiller(int screenWidth, int screenHeight) {
+            return
+                 // only if the application is requesting compatible window
+                 (mAttrs.flags & mAttrs.FLAG_COMPATIBLE_WINDOW) != 0 &&
+                 // and only if the application wanted to fill the screen
+                 mAttrs.width == mAttrs.FILL_PARENT &&
+                 mAttrs.height == mAttrs.FILL_PARENT &&
+                 // and only if the screen is bigger
+                 ((mFrame.right - mFrame.right) < screenWidth ||
+                         (mFrame.bottom - mFrame.top) < screenHeight);
+        }
+
+        boolean isFullscreen(int screenWidth, int screenHeight) {
+            return mFrame.left <= 0 && mFrame.top <= 0 &&
+                mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
         }
 
         void removeLocked() {
@@ -8102,6 +8129,7 @@
             boolean dimming = false;
             boolean covered = false;
             boolean syswin = false;
+            boolean backgroundFillerShown = false;
 
             for (i=N-1; i>=0; i--) {
                 WindowState w = (WindowState)mWindows.get(i);
@@ -8371,11 +8399,39 @@
                             syswin = true;
                         }
                     }
-                    if (w.isFullscreenOpaque(dw, dh)) {
+
+                    boolean opaqueDrawn = w.isOpaqueDrawn();
+                    if (opaqueDrawn && w.isFullscreen(dw, dh)) {
                         // This window completely covers everything behind it,
                         // so we want to leave all of them as unblurred (for
                         // performance reasons).
                         obscured = true;
+                    } else if (opaqueDrawn && w.needsBackgroundFiller(dw, dh)) {
+                        if (SHOW_TRANSACTIONS) Log.d(TAG, "showing background filler");
+                                                // This window is in compatibility mode, and needs background filler. 
+                        obscured = true;
+                        if (mBackgroundFillerSurface == null) {
+                            try {
+                                mBackgroundFillerSurface = new Surface(mFxSession, 0,
+                                        0, dw, dh,
+                                        PixelFormat.OPAQUE,
+                                        Surface.FX_SURFACE_NORMAL);
+                            } catch (Exception e) {
+                                Log.e(TAG, "Exception creating filler surface", e);
+                            }
+                        }
+                        try {
+                            mBackgroundFillerSurface.setPosition(0, 0);
+                            mBackgroundFillerSurface.setSize(dw, dh);
+                            // Using the same layer as Dim because they will never be shown at the
+                            // same time.
+                            mBackgroundFillerSurface.setLayer(w.mAnimLayer - 1);
+                            mBackgroundFillerSurface.show();
+                        } catch (RuntimeException e) {
+                            Log.e(TAG, "Exception showing filler surface");
+                        }
+                        backgroundFillerShown = true;
+                        mBackgroundFillerShown = true;
                     } else if (canBeSeen && !obscured &&
                             (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
                         if (localLOGV) Log.v(TAG, "Win " + w
@@ -8472,6 +8528,16 @@
                     }
                 }
             }
+            
+            if (backgroundFillerShown == false && mBackgroundFillerShown) {
+                mBackgroundFillerShown = false;
+                if (SHOW_TRANSACTIONS) Log.d(TAG, "hiding background filler");
+                try {
+                    mBackgroundFillerSurface.hide();
+                } catch (RuntimeException e) {
+                    Log.e(TAG, "Exception hiding filler surface", e);
+                }
+            }
 
             if (!dimming && mDimShown) {
                 // Time to hide the dim surface...  start fading.
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java
index c4f1ab6..4c5fefc 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java
@@ -107,8 +107,6 @@
     }
 
     // Checks that the search UI is not visible.
-    // This checks both the SearchManager and the SearchManagerService,
-    // since SearchManager keeps a local variable for the visibility.
     private void assertSearchNotVisible() {
         SearchManager searchManager = (SearchManager)
                 mContext.getSystemService(Context.SEARCH_SERVICE);
@@ -245,22 +243,4 @@
         assertSearchNotVisible();
     }
 
-    @MediumTest
-    public void testSearchDialogState() throws Exception {
-        SearchManager searchManager = (SearchManager)
-                mContext.getSystemService(Context.SEARCH_SERVICE);
-        assertNotNull(searchManager);
-
-        Bundle searchState;
-
-        // search dialog not visible, so no state should be stored
-        searchState = searchManager.saveSearchDialog();
-        assertNull(searchState);
-
-        searchManager.startSearch("test search string", true, SEARCHABLE_ACTIVITY, null, false);
-        searchState = searchManager.saveSearchDialog();
-        assertNotNull(searchState);
-        searchManager.stopSearch();
-    }
-
 }