Merge "Remove a dependency of Region (libui) on Parcel (libbinder)."
diff --git a/api/current.xml b/api/current.xml
index eb1c6d6..444b002 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -78725,6 +78725,17 @@
  visibility="public"
 >
 </field>
+<field name="PASSIVE_PROVIDER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;passive&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="LocationProvider"
  extends="java.lang.Object"
@@ -84485,6 +84496,28 @@
 <parameter name="srcQuality" type="int">
 </parameter>
 </constructor>
+<method name="autoPause"
+ return="void"
+ abstract="false"
+ native="true"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="autoResume"
+ return="void"
+ abstract="false"
+ native="true"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="load"
  return="int"
  abstract="false"
@@ -84626,6 +84659,19 @@
 <parameter name="loop" type="int">
 </parameter>
 </method>
+<method name="setOnLoadCompleteListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.media.SoundPool.OnLoadCompleteListener">
+</parameter>
+</method>
 <method name="setPriority"
  return="void"
  abstract="false"
@@ -84700,6 +84746,31 @@
 </parameter>
 </method>
 </class>
+<interface name="SoundPool.OnLoadCompleteListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onLoadComplete"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="soundPool" type="android.media.SoundPool">
+</parameter>
+<parameter name="sampleId" type="int">
+</parameter>
+<parameter name="status" type="int">
+</parameter>
+</method>
+</interface>
 <class name="ThumbnailUtils"
  extends="java.lang.Object"
  abstract="false"
@@ -201436,6 +201507,19 @@
  native="false"
  synchronized="false"
  static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="color" type="int">
+</parameter>
+</method>
+<method name="setColorFilter"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
  final="false"
  deprecated="not deprecated"
  visibility="public"
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 39e14e4..6a79c6d 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -268,7 +268,10 @@
     char anr_traces_path[PATH_MAX];
     strlcpy(anr_traces_path, traces_path, sizeof(anr_traces_path));
     strlcat(anr_traces_path, ".anr", sizeof(anr_traces_path));
-    rename(traces_path, anr_traces_path);
+    if (rename(traces_path, anr_traces_path) && errno != ENOENT) {
+        fprintf(stderr, "rename(%s, %s): %s\n", traces_path, anr_traces_path, strerror(errno));
+        return NULL;  // Can't rename old traces.txt -- no permission? -- leave it alone instead
+    }
 
     /* create a new, empty traces.txt file to receive stack dumps */
     int fd = open(traces_path, O_CREAT | O_WRONLY | O_TRUNC, 0666);  /* -rw-rw-rw- */
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index f7cb2273..942a303 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -157,13 +157,18 @@
     long numIterationsLeft = gNumRepetitions;
     MediaSource::ReadOptions options;
 
+    int64_t sumDecodeUs = 0;
+
     while (numIterationsLeft-- > 0) {
         long numFrames = 0;
 
         MediaBuffer *buffer;
 
         for (;;) {
+            int64_t startDecodeUs = getNowUs();
             status_t err = rawSource->read(&buffer, &options);
+            int64_t delayDecodeUs = getNowUs() - startDecodeUs;
+
             options.clearSeekTo();
 
             if (err != OK) {
@@ -182,6 +187,8 @@
                 fflush(stdout);
             }
 
+            sumDecodeUs += delayDecodeUs;
+
             buffer->release();
             buffer = NULL;
 
@@ -210,6 +217,8 @@
 
     int64_t delay = getNowUs() - startTime;
     printf("avg. %.2f fps\n", n * 1E6 / delay);
+    printf("avg. time to decode one buffer %.2f usecs\n",
+           (double)sumDecodeUs / n);
 
     printf("decoded a total of %d frame(s).\n", n);
 }
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index ed38240..4598bb5 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -822,11 +822,6 @@
         final SearchManager searchManager = (SearchManager) mContext
                 .getSystemService(Context.SEARCH_SERVICE);
 
-        // can't start search without an associated activity (e.g a system dialog)
-        if (!searchManager.hasIdent()) {
-            return false;
-        }
-
         // associate search with owner activity if possible (otherwise it will default to
         // global search).
         final ComponentName appName = getAssociatedActivity();
diff --git a/core/java/android/app/FullBackupAgent.java b/core/java/android/app/FullBackupAgent.java
index d89db96..db198ad 100644
--- a/core/java/android/app/FullBackupAgent.java
+++ b/core/java/android/app/FullBackupAgent.java
@@ -48,7 +48,8 @@
         }
 
         // That's the file set; now back it all up
-        FileBackupHelper helper = new FileBackupHelper(this, (String[])allFiles.toArray());
+        FileBackupHelper helper = new FileBackupHelper(this,
+                allFiles.toArray(new String[allFiles.size()]));
         helper.performBackup(oldState, data, newState);
     }
 
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index e4c1ba6..581b436 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -16,6 +16,9 @@
 
 package android.app;
 
+import com.android.common.Patterns;
+import com.android.common.speech.Recognition;
+
 import static android.app.SuggestionsAdapter.getColumnString;
 
 import android.content.ActivityNotFoundException;
@@ -67,9 +70,6 @@
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.AdapterView.OnItemSelectedListener;
 
-import com.android.common.Patterns;
-import com.android.common.speech.Recognition;
-
 import java.util.ArrayList;
 import java.util.WeakHashMap;
 import java.util.concurrent.atomic.AtomicLong;
@@ -89,10 +89,7 @@
 
     private static final String INSTANCE_KEY_COMPONENT = "comp";
     private static final String INSTANCE_KEY_APPDATA = "data";
-    private static final String INSTANCE_KEY_GLOBALSEARCH = "glob";
-    private static final String INSTANCE_KEY_STORED_COMPONENT = "sComp";
     private static final String INSTANCE_KEY_STORED_APPDATA = "sData";
-    private static final String INSTANCE_KEY_PREVIOUS_COMPONENTS = "sPrev";
     private static final String INSTANCE_KEY_USER_QUERY = "uQry";
     
     // The string used for privateImeOptions to identify to the IME that it should not show
@@ -115,19 +112,8 @@
     private SearchableInfo mSearchable;
     private ComponentName mLaunchComponent;
     private Bundle mAppSearchData;
-    private boolean mGlobalSearchMode;
     private Context mActivityContext;
     private SearchManager mSearchManager;
-    
-    // Values we store to allow user to toggle between in-app search and global search.
-    private ComponentName mStoredComponentName;
-    private Bundle mStoredAppSearchData;
-    
-    // stack of previous searchables, to support the BACK key after
-    // SearchManager.INTENT_ACTION_CHANGE_SEARCH_SOURCE.
-    // The top of the stack (= previous searchable) is the last element of the list,
-    // since adding and removing is efficient at the end of an ArrayList.
-    private ArrayList<ComponentName> mPreviousComponents;
 
     // For voice searching
     private final Intent mVoiceWebSearchIntent;
@@ -158,7 +144,7 @@
      * @param context Application Context we can use for system acess
      */
     public SearchDialog(Context context, SearchManager searchManager) {
-        super(context, com.android.internal.R.style.Theme_GlobalSearchBar);
+        super(context, com.android.internal.R.style.Theme_SearchBar);
 
         // Save voice intent for later queries/launching
         mVoiceWebSearchIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
@@ -241,14 +227,8 @@
      * @return true if search dialog launched, false if not
      */
     public boolean show(String initialQuery, boolean selectInitialQuery,
-            ComponentName componentName, Bundle appSearchData, boolean globalSearch) {
-
-        // Reset any stored values from last time dialog was shown.
-        mStoredComponentName = null;
-        mStoredAppSearchData = null;
-
-        boolean success = doShow(initialQuery, selectInitialQuery, componentName, appSearchData,
-                globalSearch);
+            ComponentName componentName, Bundle appSearchData) {
+        boolean success = doShow(initialQuery, selectInitialQuery, componentName, appSearchData);
         if (success) {
             // Display the drop down as soon as possible instead of waiting for the rest of the
             // pending UI stuff to get done, so that things appear faster to the user.
@@ -257,67 +237,16 @@
         return success;
     }
 
-    private boolean isInRealAppSearch() {
-        return !mGlobalSearchMode
-                && (mPreviousComponents == null || mPreviousComponents.isEmpty());
-    }
-
     /**
-     * Called in response to a press of the hard search button in
-     * {@link #onKeyDown(int, KeyEvent)}, this method toggles between in-app
-     * search and global search when relevant.
-     * 
-     * If pressed within an in-app search context, this switches the search dialog out to
-     * global search. If pressed within a global search context that was originally an in-app
-     * search context, this switches back to the in-app search context. If pressed within a
-     * global search context that has no original in-app search context (e.g., global search
-     * from Home), this does nothing.
-     * 
-     * @return false if we wanted to toggle context but could not do so successfully, true
-     * in all other cases
-     */
-    private boolean toggleGlobalSearch() {
-        String currentSearchText = mSearchAutoComplete.getText().toString();
-        if (!mGlobalSearchMode) {
-            mStoredComponentName = mLaunchComponent;
-            mStoredAppSearchData = mAppSearchData;
-            
-            // If this is the browser, we have a special case to not show the icon to the left
-            // of the text field, for extra space for url entry (this should be reconciled in
-            // Eclair). So special case a second tap of the search button to remove any
-            // already-entered text so that we can be sure to show the "Quick Search Box" hint
-            // text to still make it clear to the user that we've jumped out to global search.
-            //
-            // TODO: When the browser icon issue is reconciled in Eclair, remove this special case.
-            if (isBrowserSearch()) currentSearchText = "";
-
-            cancel();
-            mSearchManager.startGlobalSearch(currentSearchText, false, mStoredAppSearchData);
-            return true;
-        } else {
-            if (mStoredComponentName != null) {
-                // This means we should toggle *back* to an in-app search context from
-                // global search.
-                return doShow(currentSearchText, false, mStoredComponentName,
-                        mStoredAppSearchData, false);
-            } else {
-                return true;
-            }
-        }
-    }
-    
-    /**
-     * Does the rest of the work required to show the search dialog. Called by both
-     * {@link #show(String, boolean, ComponentName, Bundle, boolean)} and
-     * {@link #toggleGlobalSearch()}.
-     * 
+     * Does the rest of the work required to show the search dialog. Called by
+     * {@link #show(String, boolean, ComponentName, Bundle)} and
+     *
      * @return true if search dialog showed, false if not
      */
     private boolean doShow(String initialQuery, boolean selectInitialQuery,
-            ComponentName componentName, Bundle appSearchData,
-            boolean globalSearch) {
+            ComponentName componentName, Bundle appSearchData) {
         // set up the searchable and show the dialog
-        if (!show(componentName, appSearchData, globalSearch)) {
+        if (!show(componentName, appSearchData)) {
             return false;
         }
 
@@ -335,38 +264,24 @@
      * 
      * @return <code>true</code> if search dialog launched
      */
-    private boolean show(ComponentName componentName, Bundle appSearchData, 
-            boolean globalSearch) {
+    private boolean show(ComponentName componentName, Bundle appSearchData) {
         
         if (DBG) { 
             Log.d(LOG_TAG, "show(" + componentName + ", " 
-                    + appSearchData + ", " + globalSearch + ")");
+                    + appSearchData + ")");
         }
         
         SearchManager searchManager = (SearchManager)
                 mContext.getSystemService(Context.SEARCH_SERVICE);
-        // Try to get the searchable info for the provided component (or for global search,
-        // if globalSearch == true).
-        mSearchable = searchManager.getSearchableInfo(componentName, globalSearch);
-        
-        // If we got back nothing, and it wasn't a request for global search, then try again
-        // for global search, as we'll try to launch that in lieu of any component-specific search.
-        if (!globalSearch && mSearchable == null) {
-            globalSearch = true;
-            mSearchable = searchManager.getSearchableInfo(componentName, globalSearch);
-        }
+        // Try to get the searchable info for the provided component.
+        mSearchable = searchManager.getSearchableInfo(componentName, false);
 
-        // If there's not even a searchable info available for global search, then really give up.
         if (mSearchable == null) {
-            Log.w(LOG_TAG, "No global search provider.");
             return false;
         }
 
         mLaunchComponent = componentName;
         mAppSearchData = appSearchData;
-        // Using globalSearch here is just an optimization, just calling
-        // isDefaultSearchable() should always give the same result.
-        mGlobalSearchMode = globalSearch || searchManager.isDefaultSearchable(mSearchable);
         mActivityContext = mSearchable.getActivityContext(getContext());
 
         // show the dialog. this will call onStart().
@@ -375,20 +290,6 @@
             // of any bad state in the AutoCompleteTextView etc
             createContentView();
 
-            // The Dialog uses a ContextThemeWrapper for the context; use this to change the
-            // theme out from underneath us, between the global search theme and the in-app
-            // search theme. They are identical except that the global search theme does not
-            // dim the background of the window (because global search is full screen so it's
-            // not needed and this should save a little bit of time on global search invocation).
-            Object context = getContext();
-            if (context instanceof ContextThemeWrapper) {
-                ContextThemeWrapper wrapper = (ContextThemeWrapper) context;
-                if (globalSearch) {
-                    wrapper.setTheme(com.android.internal.R.style.Theme_GlobalSearchBar);
-                } else {
-                    wrapper.setTheme(com.android.internal.R.style.Theme_SearchBar);
-                }
-            }
             show();
         }
         updateUI();
@@ -414,7 +315,6 @@
         mSearchable = null;
         mActivityContext = null;
         mUserQuery = null;
-        mPreviousComponents = null;
     }
 
     /**
@@ -428,7 +328,7 @@
         mWorkingSpinner.setVisible(working, false);
         mWorkingSpinner.invalidateSelf();
     }
-    
+
     /**
      * Closes and gets rid of the suggestions adapter.
      */
@@ -442,7 +342,7 @@
         }
         mSuggestionsAdapter = null;
     }
-    
+
     /**
      * Save the minimal set of data necessary to recreate the search
      * 
@@ -458,10 +358,6 @@
         // setup info so I can recreate this particular search       
         bundle.putParcelable(INSTANCE_KEY_COMPONENT, mLaunchComponent);
         bundle.putBundle(INSTANCE_KEY_APPDATA, mAppSearchData);
-        bundle.putBoolean(INSTANCE_KEY_GLOBALSEARCH, mGlobalSearchMode);
-        bundle.putParcelable(INSTANCE_KEY_STORED_COMPONENT, mStoredComponentName);
-        bundle.putBundle(INSTANCE_KEY_STORED_APPDATA, mStoredAppSearchData);
-        bundle.putParcelableArrayList(INSTANCE_KEY_PREVIOUS_COMPONENTS, mPreviousComponents);
         bundle.putString(INSTANCE_KEY_USER_QUERY, mUserQuery);
 
         return bundle;
@@ -481,22 +377,10 @@
 
         ComponentName launchComponent = savedInstanceState.getParcelable(INSTANCE_KEY_COMPONENT);
         Bundle appSearchData = savedInstanceState.getBundle(INSTANCE_KEY_APPDATA);
-        boolean globalSearch = savedInstanceState.getBoolean(INSTANCE_KEY_GLOBALSEARCH);
-        ComponentName storedComponentName =
-                savedInstanceState.getParcelable(INSTANCE_KEY_STORED_COMPONENT);
-        Bundle storedAppSearchData =
-                savedInstanceState.getBundle(INSTANCE_KEY_STORED_APPDATA);
-        ArrayList<ComponentName> previousComponents =
-                savedInstanceState.getParcelableArrayList(INSTANCE_KEY_PREVIOUS_COMPONENTS);
         String userQuery = savedInstanceState.getString(INSTANCE_KEY_USER_QUERY);
 
-        // Set stored state
-        mStoredComponentName = storedComponentName;
-        mStoredAppSearchData = storedAppSearchData;
-        mPreviousComponents = previousComponents;
-
         // show the dialog.
-        if (!doShow(userQuery, false, launchComponent, appSearchData, globalSearch)) {
+        if (!doShow(userQuery, false, launchComponent, appSearchData)) {
             // for some reason, we couldn't re-instantiate
             return;
         }
@@ -506,7 +390,7 @@
      * Called after resources have changed, e.g. after screen rotation or locale change.
      */
     public void onConfigurationChanged() {
-        if (isShowing()) {
+        if (mSearchable != null && isShowing()) {
             // Redraw (resources may have changed)
             updateSearchButton();
             updateSearchAppIcon();
@@ -571,19 +455,13 @@
         // we dismiss the entire dialog instead
         mSearchAutoComplete.setDropDownDismissedOnCompletion(false);
 
-        if (!isInRealAppSearch()) {
-            mSearchAutoComplete.setDropDownAlwaysVisible(true);  // fill space until results come in
-        } else {
-            mSearchAutoComplete.setDropDownAlwaysVisible(false);
-        }
-
         mSearchAutoComplete.setForceIgnoreOutsideTouch(true);
 
         // attach the suggestions adapter, if suggestions are available
         // The existence of a suggestions authority is the proxy for "suggestions available here"
         if (mSearchable.getSuggestAuthority() != null) {
             mSuggestionsAdapter = new SuggestionsAdapter(getContext(), this, mSearchable, 
-                    mOutsideDrawablesCache, mGlobalSearchMode);
+                    mOutsideDrawablesCache);
             mSearchAutoComplete.setAdapter(mSuggestionsAdapter);
         }
     }
@@ -611,7 +489,7 @@
         // global search, for extra space for url entry.
         //
         // TODO: Remove this special case once the issue has been reconciled in Eclair. 
-        if (mGlobalSearchMode || isBrowserSearch()) {
+        if (isBrowserSearch()) {
             mAppIcon.setImageResource(0);
             mAppIcon.setVisibility(View.GONE);
             mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_GLOBAL,
@@ -705,15 +583,13 @@
     
     /**
      * Hack to determine whether this is the browser, so we can remove the browser icon
-     * to the left of the search field, as a special requirement for Donut.
-     * 
-     * TODO: For Eclair, reconcile this with the rest of the global search UI.
+     * to the left of the search field.
      */
     private boolean isBrowserSearch() {
         return mLaunchComponent.flattenToShortString().startsWith("com.android.browser/");
     }
 
-    /**
+    /*
      * Listeners of various types
      */
 
@@ -769,7 +645,7 @@
 
         return super.onKeyDown(keyCode, event);
     }
-    
+
     /**
      * Callback to watch the textedit field for empty/non-empty
      */
@@ -799,12 +675,8 @@
             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));
-                if (Patterns.WEB_URL.matcher(mUserQuery).matches()) {
-                    options = options | EditorInfo.IME_ACTION_GO;
-                } else {
-                    options = options | EditorInfo.IME_ACTION_SEARCH;
-                }
+                int options = (mSearchAutoComplete.getImeOptions() & (~EditorInfo.IME_MASK_ACTION))
+                        | EditorInfo.IME_ACTION_GO;
                 if (options != mSearchAutoCompleteImeOptions) {
                     mSearchAutoCompleteImeOptions = options;
                     mSearchAutoComplete.setImeOptions(options);
@@ -881,7 +753,8 @@
                 if (searchable.getVoiceSearchLaunchWebSearch()) {
                     getContext().startActivity(mVoiceWebSearchIntent);
                 } else if (searchable.getVoiceSearchLaunchRecognizer()) {
-                    Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent);                    
+                    Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent,
+                            searchable);
                     getContext().startActivity(appSearchIntent);
                 }
             } catch (ActivityNotFoundException e) {
@@ -899,8 +772,8 @@
      * @param baseIntent The voice app search intent to start from
      * @return A completely-configured intent ready to send to the voice search activity
      */
-    private Intent createVoiceAppSearchIntent(Intent baseIntent) {
-        ComponentName searchActivity = mSearchable.getSearchActivity();
+    private Intent createVoiceAppSearchIntent(Intent baseIntent, SearchableInfo searchable) {
+        ComponentName searchActivity = searchable.getSearchActivity();
         
         // create the necessary intent to set up a search-and-forward operation
         // in the voice search system.   We have to keep the bundle separate,
@@ -930,17 +803,17 @@
         String language = null;
         int maxResults = 1;
         Resources resources = mActivityContext.getResources();
-        if (mSearchable.getVoiceLanguageModeId() != 0) {
-            languageModel = resources.getString(mSearchable.getVoiceLanguageModeId());
+        if (searchable.getVoiceLanguageModeId() != 0) {
+            languageModel = resources.getString(searchable.getVoiceLanguageModeId());
         }
-        if (mSearchable.getVoicePromptTextId() != 0) {
-            prompt = resources.getString(mSearchable.getVoicePromptTextId());
+        if (searchable.getVoicePromptTextId() != 0) {
+            prompt = resources.getString(searchable.getVoicePromptTextId());
         }
-        if (mSearchable.getVoiceLanguageId() != 0) {
-            language = resources.getString(mSearchable.getVoiceLanguageId());
+        if (searchable.getVoiceLanguageId() != 0) {
+            language = resources.getString(searchable.getVoiceLanguageId());
         }
-        if (mSearchable.getVoiceMaxResults() != 0) {
-            maxResults = mSearchable.getVoiceMaxResults();
+        if (searchable.getVoiceMaxResults() != 0) {
+            maxResults = searchable.getVoiceMaxResults();
         }
         voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, languageModel);
         voiceIntent.putExtra(RecognizerIntent.EXTRA_PROMPT, prompt);
@@ -1140,14 +1013,9 @@
      */
     protected void launchQuerySearch(int actionKey, String actionMsg)  {
         String query = mSearchAutoComplete.getText().toString();
-        String action = mGlobalSearchMode ? Intent.ACTION_WEB_SEARCH : Intent.ACTION_SEARCH;
+        String action = Intent.ACTION_SEARCH;
         Intent intent = createIntent(action, null, null, query, null,
-                actionKey, actionMsg, null);
-        // Allow GlobalSearch to log and create shortcut for searches launched by
-        // the search button, enter key or an action key.
-        if (mGlobalSearchMode) {
-            mSuggestionsAdapter.reportSearch(query);
-        }
+                actionKey, actionMsg);
         launchIntent(intent);
     }
     
@@ -1160,7 +1028,7 @@
     protected boolean launchSuggestion(int position) {
         return launchSuggestion(position, KeyEvent.KEYCODE_UNKNOWN, null);
     }
-    
+
     /**
      * Launches an intent based on a suggestion.
      * 
@@ -1177,20 +1045,7 @@
 
             Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg);
 
-            // report back about the click
-            if (mGlobalSearchMode) {
-                // in global search mode, do it via cursor
-                mSuggestionsAdapter.callCursorOnClick(c, position, actionKey, actionMsg);
-            } else if (intent != null
-                    && mPreviousComponents != null
-                    && !mPreviousComponents.isEmpty()) {
-                // in-app search (and we have pivoted in as told by mPreviousComponents,
-                // which is used for keeping track of what we pop back to when we are pivoting into
-                // in app search.)
-                reportInAppClickToGlobalSearch(c, intent);
-            }
-
-            // launch the intent
+           // launch the intent
             launchIntent(intent);
 
             return true;
@@ -1199,163 +1054,28 @@
     }
 
     /**
-     * Report a click from an in app search result back to global search for shortcutting porpoises.
-     *
-     * @param c The cursor that is pointing to the clicked position.
-     * @param intent The intent that will be launched for the click.
-     */
-    private void reportInAppClickToGlobalSearch(Cursor c, Intent intent) {
-        // for in app search, still tell global search via content provider
-        Uri uri = getClickReportingUri();
-        final ContentValues cv = new ContentValues();
-        cv.put(SearchManager.SEARCH_CLICK_REPORT_COLUMN_QUERY, mUserQuery);
-        final ComponentName source = mSearchable.getSearchActivity();
-        cv.put(SearchManager.SEARCH_CLICK_REPORT_COLUMN_COMPONENT, source.flattenToShortString());
-
-        // grab the intent columns from the intent we created since it has additional
-        // logic for falling back on the searchable default
-        cv.put(SearchManager.SUGGEST_COLUMN_INTENT_ACTION, intent.getAction());
-        cv.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA, intent.getDataString());
-        cv.put(SearchManager.SUGGEST_COLUMN_INTENT_COMPONENT_NAME,
-                intent.getComponent().flattenToShortString());
-
-        // ensure the icons will work for global search
-        cv.put(SearchManager.SUGGEST_COLUMN_ICON_1,
-                        wrapIconForPackage(
-                                mSearchable.getSuggestPackage(),
-                                getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_1)));
-        cv.put(SearchManager.SUGGEST_COLUMN_ICON_2,
-                        wrapIconForPackage(
-                                mSearchable.getSuggestPackage(),
-                                getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_2)));
-
-        // the rest can be passed through directly
-        cv.put(SearchManager.SUGGEST_COLUMN_FORMAT,
-                getColumnString(c, SearchManager.SUGGEST_COLUMN_FORMAT));
-        cv.put(SearchManager.SUGGEST_COLUMN_TEXT_1,
-                getColumnString(c, SearchManager.SUGGEST_COLUMN_TEXT_1));
-        cv.put(SearchManager.SUGGEST_COLUMN_TEXT_2,
-                getColumnString(c, SearchManager.SUGGEST_COLUMN_TEXT_2));
-        cv.put(SearchManager.SUGGEST_COLUMN_QUERY,
-                getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY));
-        cv.put(SearchManager.SUGGEST_COLUMN_SHORTCUT_ID,
-                getColumnString(c, SearchManager.SUGGEST_COLUMN_SHORTCUT_ID));
-        // note: deliberately omitting background color since it is only for global search
-        // "more results" entries
-        mContext.getContentResolver().insert(uri, cv);
-    }
-
-    /**
-     * @return A URI appropriate for reporting a click.
-     */
-    private Uri getClickReportingUri() {
-        Uri.Builder uriBuilder = new Uri.Builder()
-                .scheme(ContentResolver.SCHEME_CONTENT)
-                .authority(SearchManager.SEARCH_CLICK_REPORT_AUTHORITY);
-
-        uriBuilder.appendPath(SearchManager.SEARCH_CLICK_REPORT_URI_PATH);
-
-        return uriBuilder
-                .query("")     // TODO: Remove, workaround for a bug in Uri.writeToParcel()
-                .fragment("")  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
-                .build();
-    }
-
-    /**
-     * Wraps an icon for a particular package.  If the icon is a resource id, it is converted into
-     * an android.resource:// URI.
-     *
-     * @param packageName The source of the icon
-     * @param icon The icon retrieved from a suggestion column
-     * @return An icon string appropriate for the package.
-     */
-    private String wrapIconForPackage(String packageName, String icon) {
-        if (icon == null || icon.length() == 0 || "0".equals(icon)) {
-            // SearchManager specifies that null or zero can be returned to indicate
-            // no icon. We also allow empty string.
-            return null;
-        } else if (!Character.isDigit(icon.charAt(0))){
-            return icon;
-        } else {
-            return new Uri.Builder()
-                    .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
-                    .authority(packageName)
-                    .encodedPath(icon)
-                    .toString();
-        }
-    }
-
-    /**
      * Launches an intent, including any special intent handling.
      */
     private void launchIntent(Intent intent) {
         if (intent == null) {
             return;
         }
-        if (handleSpecialIntent(intent)){
-            return;
-        }
         Log.d(LOG_TAG, "launching " + intent);
         try {
-            // in global search mode, we send the activity straight to the original suggestion
-            // source. this is because GlobalSearch may not have permission to launch the
-            // intent, and to avoid the extra step of going through GlobalSearch.
-            if (mGlobalSearchMode) {
-                launchGlobalSearchIntent(intent);
-                if (mStoredComponentName != null) {
-                    // If we're embedded in an application, dismiss the dialog.
-                    // This ensures that if the intent is handled by the current
-                    // activity, it's not obscured by the dialog.
-                    dismiss();
-                }
-            } else {
-                // If the intent was created from a suggestion, it will always have an explicit
-                // component here.
-                Log.i(LOG_TAG, "Starting (as ourselves) " + intent.toURI());
-                getContext().startActivity(intent);
-                // If the search switches to a different activity,
-                // SearchDialogWrapper#performActivityResuming
-                // will handle hiding the dialog when the next activity starts, but for
-                // real in-app search, we still need to dismiss the dialog.
-                if (isInRealAppSearch()) {
-                    dismiss();
-                }
-            }
+            // If the intent was created from a suggestion, it will always have an explicit
+            // component here.
+            Log.i(LOG_TAG, "Starting (as ourselves) " + intent.toURI());
+            getContext().startActivity(intent);
+            // If the search switches to a different activity,
+            // SearchDialogWrapper#performActivityResuming
+            // will handle hiding the dialog when the next activity starts, but for
+            // real in-app search, we still need to dismiss the dialog.
+            dismiss();
         } catch (RuntimeException ex) {
             Log.e(LOG_TAG, "Failed launch activity: " + intent, ex);
         }
     }
 
-    private void launchGlobalSearchIntent(Intent intent) {
-        final String packageName;
-        // GlobalSearch puts the original source of the suggestion in the
-        // 'component name' column. If set, we send the intent to that activity.
-        // We trust GlobalSearch to always set this to the suggestion source.
-        String intentComponent = intent.getStringExtra(SearchManager.COMPONENT_NAME_KEY);
-        if (intentComponent != null) {
-            ComponentName componentName = ComponentName.unflattenFromString(intentComponent);
-            intent.setComponent(componentName);
-            intent.removeExtra(SearchManager.COMPONENT_NAME_KEY);
-            // Launch the intent as the suggestion source.
-            // This prevents sources from using the search dialog to launch
-            // intents that they don't have permission for themselves.
-            packageName = componentName.getPackageName();
-        } else {
-            // If there is no component in the suggestion, it must be a built-in suggestion
-            // from GlobalSearch (e.g. "Search the web for") or the intent
-            // launched when pressing the search/go button in the search dialog.
-            // Launch the intent with the permissions of GlobalSearch.
-            packageName = mSearchable.getSearchActivity().getPackageName();
-        }
-
-        // Launch all global search suggestions as new tasks, since they don't relate
-        // to the current task.
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        setBrowserApplicationId(intent);
-
-        startActivityInPackage(intent, packageName);
-    }
-
     /**
      * If the intent is to open an HTTP or HTTPS URL, we set
      * {@link Browser#EXTRA_APPLICATION_ID} so that any existing browser window that
@@ -1372,106 +1092,6 @@
     }
 
     /**
-     * Starts an activity as if it had been started by the given package.
-     *
-     * @param intent The description of the activity to start.
-     * @param packageName
-     * @throws ActivityNotFoundException If the intent could not be resolved to
-     *         and existing activity.
-     * @throws SecurityException If the package does not have permission to start
-     *         start the activity.
-     * @throws AndroidRuntimeException If some other error occurs.
-     */
-    private void startActivityInPackage(Intent intent, String packageName) {
-        try {
-            int uid = ActivityThread.getPackageManager().getPackageUid(packageName);
-            if (uid < 0) {
-                throw new AndroidRuntimeException("Package UID not found " + packageName);
-            }
-            String resolvedType = intent.resolveTypeIfNeeded(getContext().getContentResolver());
-            IBinder resultTo = null;
-            String resultWho = null;
-            int requestCode = -1;
-            boolean onlyIfNeeded = false;
-            Log.i(LOG_TAG, "Starting (uid " + uid + ", " + packageName + ") " + intent.toURI());
-            int result = ActivityManagerNative.getDefault().startActivityInPackage(
-                    uid, intent, resolvedType, resultTo, resultWho, requestCode, onlyIfNeeded);
-            checkStartActivityResult(result, intent);
-        } catch (RemoteException ex) {
-            throw new AndroidRuntimeException(ex);
-        }
-    }
-
-    // Stolen from Instrumentation.checkStartActivityResult()
-    private static void checkStartActivityResult(int res, Intent intent) {
-        if (res >= IActivityManager.START_SUCCESS) {
-            return;
-        }
-        switch (res) {
-            case IActivityManager.START_INTENT_NOT_RESOLVED:
-            case IActivityManager.START_CLASS_NOT_FOUND:
-                if (intent.getComponent() != null)
-                    throw new ActivityNotFoundException(
-                            "Unable to find explicit activity class "
-                            + intent.getComponent().toShortString()
-                            + "; have you declared this activity in your AndroidManifest.xml?");
-                throw new ActivityNotFoundException(
-                        "No Activity found to handle " + intent);
-            case IActivityManager.START_PERMISSION_DENIED:
-                throw new SecurityException("Not allowed to start activity "
-                        + intent);
-            case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
-                throw new AndroidRuntimeException(
-                        "FORWARD_RESULT_FLAG used while also requesting a result");
-            default:
-                throw new AndroidRuntimeException("Unknown error code "
-                        + res + " when starting " + intent);
-        }
-    }
-
-    /**
-     * Handles the special intent actions declared in {@link SearchManager}.
-     * 
-     * @return <code>true</code> if the intent was handled.
-     */
-    private boolean handleSpecialIntent(Intent intent) {
-        String action = intent.getAction();
-        if (SearchManager.INTENT_ACTION_CHANGE_SEARCH_SOURCE.equals(action)) {
-            handleChangeSourceIntent(intent);
-            return true;
-        }
-        return false;
-    }
-    
-    /**
-     * Handles {@link SearchManager#INTENT_ACTION_CHANGE_SEARCH_SOURCE}.
-     */
-    private void handleChangeSourceIntent(Intent intent) {
-        Uri dataUri = intent.getData();
-        if (dataUri == null) {
-            Log.w(LOG_TAG, "SearchManager.INTENT_ACTION_CHANGE_SOURCE without intent data.");
-            return;
-        }
-        ComponentName componentName = ComponentName.unflattenFromString(dataUri.toString());
-        if (componentName == null) {
-            Log.w(LOG_TAG, "Invalid ComponentName: " + dataUri);
-            return;
-        }
-        if (DBG) Log.d(LOG_TAG, "Switching to " + componentName);
-
-        pushPreviousComponent(mLaunchComponent);
-        if (!show(componentName, mAppSearchData, false)) {
-            Log.w(LOG_TAG, "Failed to switch to source " + componentName);
-            popPreviousComponent();
-            return;
-        }
-
-        String query = intent.getStringExtra(SearchManager.QUERY);
-        setUserQuery(query);
-        mSearchAutoComplete.showDropDown();
-    }
-
-    /**
      * Sets the list item selection in the AutoCompleteTextView's ListView.
      */
     public void setListSelection(int index) {
@@ -1479,61 +1099,6 @@
     }
 
     /**
-     * Checks if there are any previous searchable components in the history stack.
-     */
-    private boolean hasPreviousComponent() {
-        return mPreviousComponents != null && !mPreviousComponents.isEmpty();
-    }
-
-    /**
-     * Saves the previous component that was searched, so that we can go
-     * back to it.
-     */
-    private void pushPreviousComponent(ComponentName componentName) {
-        if (mPreviousComponents == null) {
-            mPreviousComponents = new ArrayList<ComponentName>();
-        }
-        mPreviousComponents.add(componentName);
-    }
-    
-    /**
-     * Pops the previous component off the stack and returns it.
-     * 
-     * @return The component name, or <code>null</code> if there was
-     *         no previous component.
-     */
-    private ComponentName popPreviousComponent() {
-        if (!hasPreviousComponent()) {
-            return null;
-        }
-        return mPreviousComponents.remove(mPreviousComponents.size() - 1);
-    }
-    
-    /**
-     * Goes back to the previous component that was searched, if any.
-     * 
-     * @return <code>true</code> if there was a previous component that we could go back to.
-     */
-    private boolean backToPreviousComponent() {
-        ComponentName previous = popPreviousComponent();
-        if (previous == null) {
-            return false;
-        }
-
-        if (!show(previous, mAppSearchData, false)) {
-            Log.w(LOG_TAG, "Failed to switch to source " + previous);
-            return false;
-        }
-
-        // must touch text to trigger suggestions
-        // TODO: should this be the text as it was when the user left
-        // the source that we are now going back to?
-        String query = mSearchAutoComplete.getText().toString();
-        setUserQuery(query);
-        return true;
-    }
-    
-    /**
      * When a particular suggestion has been selected, perform the various lookups required
      * to use the suggestion.  This includes checking the cursor for suggestion-specific data,
      * and/or falling back to the XML for defaults;  It also creates REST style Uri data when
@@ -1582,10 +1147,9 @@
 
             String query = getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY);
             String extraData = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA);
-            String mode = mGlobalSearchMode ? SearchManager.MODE_GLOBAL_SEARCH_SUGGESTION : null;
 
             return createIntent(action, dataUri, extraData, query, componentName, actionKey,
-                    actionMsg, mode);
+                    actionMsg);
         } catch (RuntimeException e ) {
             int rowNum;
             try {                       // be really paranoid now
@@ -1616,16 +1180,13 @@
      * @return The intent.
      */
     private Intent createIntent(String action, Uri data, String extraData, String query,
-            String componentName, int actionKey, String actionMsg, String mode) {
+            String componentName, int actionKey, String actionMsg) {
         // Now build the Intent
         Intent intent = new Intent(action);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         // We need CLEAR_TOP to avoid reusing an old task that has other activities
         // on top of the one we want. We don't want to do this in in-app search though,
         // as it can be destructive to the activity stack.
-        if (mGlobalSearchMode) {
-            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        }
         if (data != null) {
             intent.setData(data);
         }
@@ -1636,9 +1197,6 @@
         if (extraData != null) {
             intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
         }
-        if (componentName != null) {
-            intent.putExtra(SearchManager.COMPONENT_NAME_KEY, componentName);
-        }
         if (mAppSearchData != null) {
             intent.putExtra(SearchManager.APP_DATA, mAppSearchData);
         }
@@ -1646,16 +1204,10 @@
             intent.putExtra(SearchManager.ACTION_KEY, actionKey);
             intent.putExtra(SearchManager.ACTION_MSG, actionMsg);
         }
-        if (mode != null) {
-            intent.putExtra(SearchManager.SEARCH_MODE, mode);
-        }
-        // Only allow 3rd-party intents from GlobalSearch
-        if (!mGlobalSearchMode) {
-            intent.setComponent(mSearchable.getSearchActivity());
-        }
+        intent.setComponent(mSearchable.getSearchActivity());
         return intent;
     }
-    
+
     /**
      * For a given suggestion and a given cursor row, get the action message.  If not provided
      * by the specific row/column, also check for a single definition (for the action key).
@@ -1812,12 +1364,8 @@
                 imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), 0)) {
             return;
         }
-        // Otherwise, go back to any previous source (e.g. back to QSB when
-        // pivoted into a source.
-        if (!backToPreviousComponent()) {
-            // If no previous source, close search dialog
-            cancel();
-        }
+        // Close search dialog
+        cancel();
     }
 
     /**
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 5a9a675..52cdc74 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -350,7 +350,7 @@
  * <p><b>Configuring your Content Provider to Receive Suggestion Queries.</b>  The basic job of
  * a search suggestions {@link android.content.ContentProvider Content Provider} is to provide
  * "live" (while-you-type) conversion of the user's query text into a set of zero or more 
- * suggestions.  Each application is free to define the conversion, and as described above there are
+ * suggestions. Each application is free to define the conversion, and as described above there are
  * many possible solutions.  This section simply defines how to communicate with the suggestion
  * provider.  
  * 
@@ -360,7 +360,8 @@
  * 
  * <p>Every query includes a Uri, and the Search Manager will format the Uri as shown:
  * <p><pre class="prettyprint">
- * content:// your.suggest.authority / your.suggest.path / SearchManager.SUGGEST_URI_PATH_QUERY</pre>
+ * content:// your.suggest.authority / your.suggest.path / SearchManager.SUGGEST_URI_PATH_QUERY
+ *    </pre>
  * 
  * <p>Your Content Provider can receive the query text in one of two ways.
  * <ul>
@@ -379,7 +380,7 @@
  * <p><b>Providing access to Content Providers that require permissions.</b>  If your content
  * provider declares an android:readPermission in your application's manifest, you must provide
  * access to the search infrastructure to the search suggestion path by including a path-permission
- * that grants android:readPermission access to "android.permission.GLOBAL_SEARCH".  Granting access
+ * that grants android:readPermission access to "android.permission.GLOBAL_SEARCH". Granting access
  * explicitly to the search infrastructure ensures it will be able to access the search suggestions
  * without needing to know ahead of time any other details of the permissions protecting your
  * provider.  Content providers that require no permissions are already available to the search
@@ -546,7 +547,8 @@
  * taken directly to a specific result.
  *   <ul>
  *   <li><b>Action:</b> {@link android.content.Intent#ACTION_VIEW ACTION_VIEW}</li>
- *   <li><b>Data:</b> a complete Uri, supplied by the cursor, that identifies the desired data.</li>
+ *   <li><b>Data:</b> a complete Uri, supplied by the cursor, that identifies the desired data.
+ *   </li>
  *   <li><b>Query:</b> query text supplied with the suggestion (probably ignored)</li>
  *   </ul>
  * </li>
@@ -570,7 +572,7 @@
  * 
  * <p><b>Suggestion Rewriting.</b>  If the user navigates through the suggestions list, the UI
  * may temporarily rewrite the user's query with a query that matches the currently selected 
- * suggestion.  This enables the user to see what query is being suggested, and also allows the user
+ * suggestion. This enables the user to see what query is being suggested, and also allows the user
  * to click or touch in the entry EditText element and make further edits to the query before
  * dispatching it.  In order to perform this correctly, the Search UI needs to know exactly what
  * text to rewrite the query with.
@@ -1289,15 +1291,6 @@
     public final static String SEARCH_MODE = "search_mode";
 
     /**
-     * Value for the {@link #SEARCH_MODE} key.
-     * This is used if the intent was launched by clicking a suggestion in global search
-     * mode (Quick Search Box).
-     *
-     * @hide
-     */
-    public static final String MODE_GLOBAL_SEARCH_SUGGESTION = "global_search_suggestion";
-
-    /**
      * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
      * {@link android.content.Intent#getIntExtra content.Intent.getIntExtra()}
      * to obtain the keycode that the user used to trigger this query.  It will be zero if the
@@ -1308,14 +1301,6 @@
     public final static String ACTION_KEY = "action_key";
     
     /**
-     * Intent component name key: This key will be used for the extra populated by the
-     * {@link #SUGGEST_COLUMN_INTENT_COMPONENT_NAME} column.
-     *
-     * {@hide}
-     */
-    public final static String COMPONENT_NAME_KEY = "intent_component_name_key";
-
-    /**
      * Intent extra data key: This key will be used for the extra populated by the
      * {@link #SUGGEST_COLUMN_INTENT_EXTRA_DATA} column.
      */
@@ -1329,58 +1314,6 @@
     public final static String EXTRA_SELECT_QUERY = "select_query";
 
     /**
-     * Defines the constants used in the communication between {@link android.app.SearchDialog} and
-     * the global search provider via {@link Cursor#respond(android.os.Bundle)}.
-     *
-     * @hide
-     */
-    public static class DialogCursorProtocol {
-
-        /**
-         * The sent bundle will contain this integer key, with a value set to one of the events
-         * below.
-         */
-        public final static String METHOD = "DialogCursorProtocol.method";
-
-        /**
-         * After data has been refreshed.
-         */
-        public final static int POST_REFRESH = 0;
-        public final static String POST_REFRESH_RECEIVE_ISPENDING
-                = "DialogCursorProtocol.POST_REFRESH.isPending";
-        public final static String POST_REFRESH_RECEIVE_DISPLAY_NOTIFY
-                = "DialogCursorProtocol.POST_REFRESH.displayNotify";
-
-        /**
-         * When a position has been clicked.
-         */
-        public final static int CLICK = 2;
-        public final static String CLICK_SEND_POSITION
-                = "DialogCursorProtocol.CLICK.sendPosition";
-        public final static String CLICK_SEND_MAX_DISPLAY_POS
-                = "DialogCursorProtocol.CLICK.sendDisplayPosition";
-        public final static String CLICK_SEND_ACTION_KEY
-                = "DialogCursorProtocol.CLICK.sendActionKey";
-        public final static String CLICK_SEND_ACTION_MSG
-                = "DialogCursorProtocol.CLICK.sendActionMsg";
-        public final static String CLICK_RECEIVE_SELECTED_POS
-                = "DialogCursorProtocol.CLICK.receiveSelectedPosition";
-
-        /**
-         * When the threshold received in {@link #POST_REFRESH_RECEIVE_DISPLAY_NOTIFY} is displayed.
-         */
-        public final static int THRESH_HIT = 3;
-
-        /**
-         * When a search is started without using a suggestion.
-         */
-        public final static int SEARCH = 4;
-        public final static String SEARCH_SEND_MAX_DISPLAY_POS
-                = "DialogCursorProtocol.SEARCH.sendDisplayPosition";
-        public final static String SEARCH_SEND_QUERY = "DialogCursorProtocol.SEARCH.query";
-    }
-
-    /**
      * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
      * {@link android.content.Intent#getStringExtra content.Intent.getStringExtra()}
      * to obtain the action message that was defined for a particular search action key and/or
@@ -1421,40 +1354,6 @@
     public final static String SHORTCUT_MIME_TYPE = 
             "vnd.android.cursor.item/vnd.android.search.suggest";
 
-
-    /**
-     * The authority of the provider to report clicks to when a click is detected after pivoting
-     * into a specific app's search from global search.
-     *
-     * In addition to the columns below, the suggestion columns are used to pass along the full
-     * suggestion so it can be shortcutted.
-     *
-     * @hide
-     */
-    public final static String SEARCH_CLICK_REPORT_AUTHORITY =
-            "com.android.globalsearch.stats";
-
-    /**
-     * The path the write goes to.
-     *
-     * @hide
-     */
-    public final static String SEARCH_CLICK_REPORT_URI_PATH = "click";
-
-    /**
-     * The column storing the query for the click.
-     *
-     * @hide
-     */
-    public final static String SEARCH_CLICK_REPORT_COLUMN_QUERY = "query";
-
-    /**
-     * The column storing the component name of the application that was pivoted into.
-     *
-     * @hide
-     */
-    public final static String SEARCH_CLICK_REPORT_COLUMN_COMPONENT = "component";
-
     /**
      * Column name for suggestions cursor.  <i>Unused - can be null or column can be omitted.</i>
      */
@@ -1531,10 +1430,7 @@
      */
     public final static String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data";
     /**
-     * Column name for suggestions cursor.  <i>Optional.</i>  This column allows suggestions
-     *  to provide additional arbitrary data which will be included as an extra under the key
-     *  {@link #COMPONENT_NAME_KEY}. For use by the global search system only - if other providers
-     *  attempt to use this column, the value will be overwritten by global search.
+     * TODO: Remove
      *
      * @hide
      */
@@ -1594,27 +1490,6 @@
     public final static String SUGGEST_PARAMETER_LIMIT = "limit";
 
     /**
-     * If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION},
-     * the search dialog will switch to a different suggestion source when the
-     * suggestion is clicked. 
-     * 
-     * {@link #SUGGEST_COLUMN_INTENT_DATA} must contain
-     * the flattened {@link ComponentName} of the activity which is to be searched.
-     * 
-     * TODO: Should {@link #SUGGEST_COLUMN_INTENT_DATA} instead contain a URI in the format
-     * used by {@link android.provider.Applications}?
-     * 
-     * TODO: This intent should be protected by the same permission that we use
-     * for replacing the global search provider.
-     * 
-     * The query text field will be set to the value of {@link #SUGGEST_COLUMN_QUERY}.
-     * 
-     * @hide Pending API council approval.
-     */
-    public final static String INTENT_ACTION_CHANGE_SEARCH_SOURCE 
-            = "android.search.action.CHANGE_SEARCH_SOURCE";
-
-    /**
      * Intent action for starting the global search activity.
      * The global search provider should handle this intent.
      *
@@ -1663,7 +1538,7 @@
      * @hide
      */
     public final static String INTENT_ACTION_NONE = "android.search.action.ZILCH";
-    
+
     /**
      * Reference to the shared system search service.
      */
@@ -1672,13 +1547,6 @@
     private final Context mContext;
 
     /**
-     * compact representation of the activity associated with this search manager so
-     * we can say who we are when starting search.  the search managerservice, in turn,
-     * uses this to properly handle the back stack.
-     */
-    private int mIdent;
-
-    /**
      * The package associated with this seach manager.
      */
     private String mAssociatedPackage;
@@ -1696,21 +1564,6 @@
         mService = ISearchManager.Stub.asInterface(
                 ServiceManager.getService(Context.SEARCH_SERVICE));
     }
-
-    /*package*/ boolean hasIdent() {
-        return mIdent != 0;
-    }
-    
-    /*package*/ void setIdent(int ident, ComponentName component) {
-        if (mIdent != 0) {
-            throw new IllegalStateException("mIdent already set");
-        }
-        if (component == null) {
-            throw new IllegalArgumentException("component must be non-null");
-        }
-        mIdent = ident;
-        mAssociatedPackage = component.getPackageName();
-    }
     
     /**
      * Launch search UI.
@@ -1757,15 +1610,14 @@
                             ComponentName launchActivity,
                             Bundle appSearchData,
                             boolean globalSearch) {
-        ensureSearchDialog();
-
         if (globalSearch) {
             startGlobalSearch(initialQuery, selectInitialQuery, appSearchData);
             return;
         }
 
-        mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData,
-                globalSearch);
+        ensureSearchDialog();
+
+        mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData);
     }
 
     private void ensureSearchDialog() {
@@ -1994,17 +1846,6 @@
             return null;
         }
     }
-    
-    /**
-     * Checks whether the given searchable is the default searchable.
-     * 
-     * @hide because SearchableInfo is not part of the API.
-     */
-    public boolean isDefaultSearchable(SearchableInfo searchable) {
-        SearchableInfo defaultSearchable = getSearchableInfo(null, true);
-        return defaultSearchable != null 
-                && defaultSearchable.getSearchActivity().equals(searchable.getSearchActivity());
-    }
 
     /**
      * Gets a cursor with search suggestions.
@@ -2091,56 +1932,4 @@
         }
     }
 
-    /**
-     * Returns a list of the searchable activities that handle web searches.
-     *
-     * @return a list of all searchable activities that handle
-     *         {@link android.content.Intent#ACTION_WEB_SEARCH}.
-     *
-     * @hide because SearchableInfo is not part of the API.
-     */
-    public List<SearchableInfo> getSearchablesForWebSearch() {
-        try {
-            return mService.getSearchablesForWebSearch();
-        } catch (RemoteException e) {
-            Log.e(TAG, "getSearchablesForWebSearch() failed: " + e);
-            return null;
-        }
-    }
-
-    /**
-     * Returns the default searchable activity for web searches.
-     *
-     * @return searchable information for the activity handling web searches by default.
-     *
-     * @hide because SearchableInfo is not part of the API.
-     */
-    public SearchableInfo getDefaultSearchableForWebSearch() {
-        try {
-            return mService.getDefaultSearchableForWebSearch();
-        } catch (RemoteException e) {
-            Log.e(TAG, "getDefaultSearchableForWebSearch() failed: " + e);
-            return null;
-        }
-    }
-
-    /**
-     * Sets the default searchable activity for web searches.
-     *
-     * @param component Name of the component to set as default activity for web searches.
-     *
-     * @hide
-     */
-    public void setDefaultWebSearch(ComponentName component) {
-        try {
-            mService.setDefaultWebSearch(component);
-        } catch (RemoteException e) {
-            Log.e(TAG, "setDefaultWebSearch() failed: " + e);
-        }
-    }
-
-    private static void debug(String msg) {
-        Thread thread = Thread.currentThread();
-        Log.d(TAG, msg + " (" + thread.getName() + "-" + thread.getId() + ")");
-    }
 }
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index 173c3e1..57795d1 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -16,7 +16,6 @@
 
 package android.app;
 
-import android.app.SearchManager.DialogCursorProtocol;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -30,12 +29,10 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
 import android.net.Uri;
-import android.os.Bundle;
 import android.text.Html;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.SparseArray;
-import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Filter;
@@ -65,7 +62,6 @@
     private Context mProviderContext;
     private WeakHashMap<String, Drawable.ConstantState> mOutsideDrawablesCache;
     private SparseArray<Drawable.ConstantState> mBackgroundsCache;
-    private boolean mGlobalSearchMode;
     private boolean mClosed = false;
 
     // Cached column indexes, updated when the cursor changes.
@@ -76,29 +72,8 @@
     private int mIconName2Col;
     private int mBackgroundColorCol;
     
-    // The extra used to tell a cursor to close itself. This is a hack, see the description by
-    // its use later in this file.
-    private static final String EXTRA_CURSOR_RESPOND_CLOSE_CURSOR = "cursor_respond_close_cursor";
-
-    // The bundle which contains {EXTRA_CURSOR_RESPOND_CLOSE_CURSOR=true}, just cached once
-    // so we don't bother recreating it a bunch.
-    private final Bundle mCursorRespondCloseCursorBundle;
-
-    // This value is stored in SuggestionsAdapter by the SearchDialog to indicate whether
-    // a particular list item should be selected upon the next call to notifyDataSetChanged.
-    // This is used to indicate the index of the "More results..." list item so that when
-    // the data set changes after a click of "More results...", we can correctly tell the
-    // ListView to scroll to the right line item. It gets reset to NONE every time it
-    // is consumed.
-    private int mListItemToSelect = NONE;
     static final int NONE = -1;
 
-    // holds the maximum position that has been displayed to the user
-    int mMaxDisplayed = NONE;
-
-    // holds the position that, when displayed, should result in notifying the cursor
-    int mDisplayNotifyPos = NONE;
-
     private final Runnable mStartSpinnerRunnable;
     private final Runnable mStopSpinnerRunnable;
 
@@ -110,8 +85,7 @@
 
     public SuggestionsAdapter(Context context, SearchDialog searchDialog,
             SearchableInfo searchable,
-            WeakHashMap<String, Drawable.ConstantState> outsideDrawablesCache,
-            boolean globalSearchMode) {
+            WeakHashMap<String, Drawable.ConstantState> outsideDrawablesCache) {
         super(context,
                 com.android.internal.R.layout.search_dropdown_item_icons_2line,
                 null,   // no initial cursor
@@ -126,7 +100,6 @@
 
         mOutsideDrawablesCache = outsideDrawablesCache;
         mBackgroundsCache = new SparseArray<Drawable.ConstantState>();
-        mGlobalSearchMode = globalSearchMode;
 
         mStartSpinnerRunnable = new Runnable() {
                 public void run() {
@@ -140,10 +113,6 @@
             }
         };
         
-        // Create this once because we'll reuse it a bunch.
-        mCursorRespondCloseCursorBundle = new Bundle();
-        mCursorRespondCloseCursorBundle.putBoolean(EXTRA_CURSOR_RESPOND_CLOSE_CURSOR, true);
-
         // delay 500ms when deleting
         getFilter().setDelayer(new Filter.Delayer() {
 
@@ -177,27 +146,22 @@
     public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
         if (DBG) Log.d(LOG_TAG, "runQueryOnBackgroundThread(" + constraint + ")");
         String query = (constraint == null) ? "" : constraint.toString();
-        if (!mGlobalSearchMode) {
-            /**
-             * for in app search we show the progress spinner until the cursor is returned with
-             * the results.  for global search we manage the progress bar using
-             * {@link DialogCursorProtocol#POST_REFRESH_RECEIVE_ISPENDING}.
-             */
-            mSearchDialog.getWindow().getDecorView().post(mStartSpinnerRunnable);
-        }
+        /**
+         * for in app search we show the progress spinner until the cursor is returned with
+         * the results.
+         */
+        mSearchDialog.getWindow().getDecorView().post(mStartSpinnerRunnable);
         try {
             final Cursor cursor = mSearchManager.getSuggestions(mSearchable, query, QUERY_LIMIT);
             // trigger fill window so the spinner stays up until the results are copied over and
             // closer to being ready
-            if (!mGlobalSearchMode && cursor != null) cursor.getCount();
+            if (cursor != null) cursor.getCount();
             return cursor;
         } catch (RuntimeException e) {
             Log.w(LOG_TAG, "Search suggestions query threw an exception.", e);
             return null;
         } finally {
-            if (!mGlobalSearchMode) {
-                mSearchDialog.getWindow().getDecorView().post(mStopSpinnerRunnable);
-            }
+            mSearchDialog.getWindow().getDecorView().post(mStopSpinnerRunnable);
         }
     }
 
@@ -221,21 +185,8 @@
         }
 
         try {
-            Cursor oldCursor = getCursor();
             super.changeCursor(c);
-            
-            // We send a special respond to the cursor to tell it to close itself directly because
-            // it may not happen correctly for some cursors currently. This was originally
-            // included as a fix to http://b/2036290, in which the search dialog was holding
-            // on to references to the web search provider unnecessarily. This is being caused by
-            // the fact that the cursor is not being correctly closed in
-            // BulkCursorToCursorAdapter#close, which remains unfixed (see http://b/2015069).
-            //
-            // TODO: Remove this hack once http://b/2015069 is fixed.
-            if (oldCursor != null && oldCursor != c) {
-                oldCursor.respond(mCursorRespondCloseCursorBundle);
-            }
-            
+
             if (c != null) {
                 mFormatCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_FORMAT);
                 mText1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1);
@@ -249,79 +200,6 @@
         }
     }
 
-    @Override
-    public void notifyDataSetChanged() {
-        if (DBG) Log.d(LOG_TAG, "notifyDataSetChanged");
-        super.notifyDataSetChanged();
-
-        callCursorPostRefresh(mCursor);
-
-        // look out for the pending item we are supposed to scroll to
-        if (mListItemToSelect != NONE) {
-            mSearchDialog.setListSelection(mListItemToSelect);
-            mListItemToSelect = NONE;
-        }
-    }
-
-    /**
-     * Handle sending and receiving information associated with
-     * {@link DialogCursorProtocol#POST_REFRESH}.
-     *
-     * @param cursor The cursor to call.
-     */
-    private void callCursorPostRefresh(Cursor cursor) {
-        if (!mGlobalSearchMode) return;
-        final Bundle request = new Bundle();
-        request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.POST_REFRESH);
-        final Bundle response = cursor.respond(request);
-
-        mSearchDialog.setWorking(
-                response.getBoolean(DialogCursorProtocol.POST_REFRESH_RECEIVE_ISPENDING, false));
-
-        mDisplayNotifyPos =
-                response.getInt(DialogCursorProtocol.POST_REFRESH_RECEIVE_DISPLAY_NOTIFY, -1);
-    }
-
-    /**
-     * Tell the cursor which position was clicked, handling sending and receiving information
-     * associated with {@link DialogCursorProtocol#CLICK}.
-     *
-     * @param cursor The cursor
-     * @param position The position that was clicked.
-     */
-    void callCursorOnClick(Cursor cursor, int position, int actionKey, String actionMsg) {
-        if (!mGlobalSearchMode) return;
-        final Bundle request = new Bundle(5);
-        request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.CLICK);
-        request.putInt(DialogCursorProtocol.CLICK_SEND_POSITION, position);
-        request.putInt(DialogCursorProtocol.CLICK_SEND_MAX_DISPLAY_POS, mMaxDisplayed);
-        if (actionKey != KeyEvent.KEYCODE_UNKNOWN) {
-            request.putInt(DialogCursorProtocol.CLICK_SEND_ACTION_KEY, actionKey);
-            request.putString(DialogCursorProtocol.CLICK_SEND_ACTION_MSG, actionMsg);
-        }
-        final Bundle response = cursor.respond(request);
-        mMaxDisplayed = -1;
-        mListItemToSelect = response.getInt(
-                DialogCursorProtocol.CLICK_RECEIVE_SELECTED_POS, SuggestionsAdapter.NONE);
-    }
-
-    /**
-     * Tell the cursor that a search was started without using a suggestion.
-     *
-     * @param query The search query.
-     */
-    void reportSearch(String query) {
-        if (!mGlobalSearchMode) return;
-        Cursor cursor = getCursor();
-        if (cursor == null) return;
-        final Bundle request = new Bundle(3);
-        request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.SEARCH);
-        request.putString(DialogCursorProtocol.SEARCH_SEND_QUERY, query);
-        request.putInt(DialogCursorProtocol.SEARCH_SEND_MAX_DISPLAY_POS, mMaxDisplayed);
-        // the response is always empty
-        cursor.respond(request);
-    }
-
     /**
      * Tags the view with cached child view look-ups.
      */
@@ -353,20 +231,6 @@
     @Override
     public void bindView(View view, Context context, Cursor cursor) {
         ChildViewCache views = (ChildViewCache) view.getTag();
-        final int pos = cursor.getPosition();
-
-        // update the maximum position displayed since last refresh
-        if (pos > mMaxDisplayed) {
-            mMaxDisplayed = pos;
-        }
-
-        // if the cursor wishes to be notified about this position, send it
-        if (mGlobalSearchMode && mDisplayNotifyPos != NONE && pos == mDisplayNotifyPos) {
-            final Bundle request = new Bundle();
-            request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.THRESH_HIT);
-            mCursor.respond(request);
-            mDisplayNotifyPos = NONE;  // only notify the first time
-        }
 
         int backgroundColor = 0;
         if (mBackgroundColorCol != -1) {
diff --git a/core/java/android/backup/BackupDataInput.java b/core/java/android/backup/BackupDataInput.java
index 67d51ea..295dc66 100644
--- a/core/java/android/backup/BackupDataInput.java
+++ b/core/java/android/backup/BackupDataInput.java
@@ -133,7 +133,7 @@
 
     /**
      * Consume the current record's data without actually reading it into a buffer
-     * for further processing.  This allows a {@link android.backup.BackupAgent} to
+     * for further processing.  This allows a {@link android.app.BackupAgent} to
      * efficiently discard obsolete or otherwise uninteresting records during the
      * restore operation.
      * 
diff --git a/core/java/android/backup/RestoreSession.java b/core/java/android/backup/RestoreSession.java
index fc53854..bc410c4 100644
--- a/core/java/android/backup/RestoreSession.java
+++ b/core/java/android/backup/RestoreSession.java
@@ -63,7 +63,7 @@
      *
      * @return Zero on success; nonzero on error.  The observer will only receive
      *   progress callbacks if this method returned zero.
-     * @param token The token from {@link getAvailableRestoreSets()} corresponding to
+     * @param token The token from {@link #getAvailableRestoreSets()} corresponding to
      *   the restore set that should be used.
      * @param observer If non-null, this binder points to an object that will receive
      *   progress callbacks during the restore operation.
@@ -120,8 +120,7 @@
      * object is no longer valid.
      *
      * <p><b>Note:</b> The caller <i>must</i> invoke this method to end the restore session,
-     *   even if {@link #getAvailableRestoreSets()} or
-     *   {@link #restorePackage(long, String, RestoreObserver)} failed.
+     *   even if {@link #restorePackage(String, RestoreObserver)} failed.
      */
     public void endRestoreSession() {
         try {
diff --git a/core/java/android/gesture/Learner.java b/core/java/android/gesture/Learner.java
index 60997e0..a105652 100755
--- a/core/java/android/gesture/Learner.java
+++ b/core/java/android/gesture/Learner.java
@@ -72,7 +72,8 @@
         for (int i = 0; i < count; i++) {
             final Instance instance = instances.get(i);
             // the label can be null, as specified in Instance
-            if ((instance.label == null && name == null) || instance.label.equals(name)) {
+            if ((instance.label == null && name == null)
+                    || (instance.label != null && instance.label.equals(name))) {
                 toDelete.add(instance);
             }
         }
diff --git a/core/java/android/text/AndroidCharacter.java b/core/java/android/text/AndroidCharacter.java
index af93b5d..05887c5 100644
--- a/core/java/android/text/AndroidCharacter.java
+++ b/core/java/android/text/AndroidCharacter.java
@@ -73,6 +73,11 @@
      * Replace the specified slice of <code>text</code> with the chars'
      * right-to-left mirrors (if any), returning true if any
      * replacements were made.
+     *
+     * @param text array of characters to apply mirror operation
+     * @param start first character in array to mirror
+     * @param count maximum number of characters to mirror
+     * @return true if replacements were made
      */
     public native static boolean mirror(char[] text, int start, int count);
 
diff --git a/core/java/android/text/style/LeadingMarginSpan.java b/core/java/android/text/style/LeadingMarginSpan.java
index 6635ddb8..f320701 100644
--- a/core/java/android/text/style/LeadingMarginSpan.java
+++ b/core/java/android/text/style/LeadingMarginSpan.java
@@ -45,7 +45,7 @@
 
     /**
      * Renders the leading margin.  This is called before the margin has been
-     * adjusted by the value returned by {@link getLeadingMargin(boolean)}.
+     * adjusted by the value returned by {@link #getLeadingMargin(boolean)}.
      * 
      * @param c the canvas
      * @param p the paint. The this should be left unchanged on exit.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e5db120..bc49439 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3050,6 +3050,7 @@
      *
      * @param enabled True if this view is enabled, false otherwise.
      */
+    @RemotableViewMethod
     public void setEnabled(boolean enabled) {
         if (enabled == isEnabled()) return;
 
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 254efe7..a79bbee 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2364,7 +2364,16 @@
     public void draw(Canvas canvas) {
         super.draw(canvas);
         if (mFastScroller != null) {
-            mFastScroller.draw(canvas);
+            final int scrollY = mScrollY;
+            if (scrollY != 0) {
+                // Pin the fast scroll thumb to the top/bottom during overscroll.
+                int restoreCount = canvas.save();
+                canvas.translate(0, (float) scrollY);
+                mFastScroller.draw(canvas);
+                canvas.restoreToCount(restoreCount);
+            } else {
+                mFastScroller.draw(canvas);
+            }
         }
     }
 
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 3853359..233ce30 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -32,6 +32,7 @@
 import android.net.Uri;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.RemotableViewMethod;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -69,6 +70,7 @@
     private ColorFilter mColorFilter;
     private int mAlpha = 255;
     private int mViewAlphaScale = 256;
+    private boolean mColorMod = false;
 
     private Drawable mDrawable = null;
     private int[] mState = null;
@@ -138,7 +140,7 @@
 
         int tint = a.getInt(com.android.internal.R.styleable.ImageView_tint, 0);
         if (tint != 0) {
-            setColorFilter(tint, PorterDuff.Mode.SRC_ATOP);
+            setColorFilter(tint);
         }
         
         mCropToPadding = a.getBoolean(
@@ -877,6 +879,18 @@
         setColorFilter(new PorterDuffColorFilter(color, mode));
     }
 
+    /**
+     * Set a tinting option for the image. Assumes
+     * {@link PorterDuff.Mode#SRC_ATOP} blending mode.
+     *
+     * @param color Color tint to apply.
+     * @attr ref android.R.styleable#ImageView_tint
+     */
+    @RemotableViewMethod
+    public final void setColorFilter(int color) {
+        setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+    }
+
     public final void clearColorFilter() {
         setColorFilter(null);
     }
@@ -889,22 +903,29 @@
     public void setColorFilter(ColorFilter cf) {
         if (mColorFilter != cf) {
             mColorFilter = cf;
+            mColorMod = true;
             applyColorMod();
             invalidate();
         }
     }
 
+    @RemotableViewMethod
     public void setAlpha(int alpha) {
         alpha &= 0xFF;          // keep it legal
         if (mAlpha != alpha) {
             mAlpha = alpha;
+            mColorMod = true;
             applyColorMod();
             invalidate();
         }
     }
 
     private void applyColorMod() {
-        if (mDrawable != null) {
+        // Only mutate and apply when modifications have occurred. This should
+        // not reset the mColorMod flag, since these filters need to be
+        // re-applied if the Drawable is changed.
+        if (mDrawable != null && mColorMod) {
+            mDrawable = mDrawable.mutate();
             mDrawable.setColorFilter(mColorFilter);
             mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8);
         }
diff --git a/core/java/android/widget/ViewFlipper.java b/core/java/android/widget/ViewFlipper.java
index aee25b0..8034961 100644
--- a/core/java/android/widget/ViewFlipper.java
+++ b/core/java/android/widget/ViewFlipper.java
@@ -38,7 +38,7 @@
 @RemoteView
 public class ViewFlipper extends ViewAnimator {
     private static final String TAG = "ViewFlipper";
-    private static final boolean LOGD = true;
+    private static final boolean LOGD = false;
 
     private static final int DEFAULT_INTERVAL = 3000;
 
diff --git a/core/jni/android_text_AndroidCharacter.cpp b/core/jni/android_text_AndroidCharacter.cpp
index 1353478..5d8d419 100644
--- a/core/jni/android_text_AndroidCharacter.cpp
+++ b/core/jni/android_text_AndroidCharacter.cpp
@@ -165,7 +165,8 @@
         goto MIRROR_END;
     }
 
-    if (start > start + count || env->GetArrayLength(charArray) < count) {
+    if (start < 0 || start > start + count
+            || env->GetArrayLength(charArray) < start + count) {
         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
         goto MIRROR_END;
     }
diff --git a/core/tests/coretests/src/android/app/SearchManagerTest.java b/core/tests/coretests/src/android/app/SearchManagerTest.java
index fc7e787..08b7f60 100644
--- a/core/tests/coretests/src/android/app/SearchManagerTest.java
+++ b/core/tests/coretests/src/android/app/SearchManagerTest.java
@@ -120,23 +120,6 @@
         assertSame(searchManager1, searchManager2 );
     }
 
-    @MediumTest
-    public void testSearchables() {
-        SearchManager searchManager = (SearchManager)
-                mContext.getSystemService(Context.SEARCH_SERVICE);
-        SearchableInfo si;
-
-        si = searchManager.getSearchableInfo(SEARCHABLE_ACTIVITY, false);
-        assertNotNull(si);
-        assertFalse(searchManager.isDefaultSearchable(si));
-        si = searchManager.getSearchableInfo(SEARCHABLE_ACTIVITY, true);
-        assertNotNull(si);
-        assertTrue(searchManager.isDefaultSearchable(si));
-        si = searchManager.getSearchableInfo(null, true);
-        assertNotNull(si);
-        assertTrue(searchManager.isDefaultSearchable(si));
-    }
-
     /**
      * Tests that startSearch() can be called multiple times without stopSearch()
      * in between.
diff --git a/core/tests/hosttests/Android.mk b/core/tests/hosttests/Android.mk
new file mode 100644
index 0000000..0001201
--- /dev/null
+++ b/core/tests/hosttests/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+#LOCAL_TEST_TYPE := hostSideOnly
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := FrameworkCoreHostTests
+
+LOCAL_JAVA_LIBRARIES := hosttestlib ddmlib junit
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/core/tests/hosttests/README b/core/tests/hosttests/README
new file mode 100644
index 0000000..d3bdb83
--- /dev/null
+++ b/core/tests/hosttests/README
@@ -0,0 +1,6 @@
+This dir contains tests which run on a host machine, and test aspects of
+package install etc via adb.
+
+To run, do:
+runtest framework-core-host
+
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
new file mode 100644
index 0000000..9c9d777
--- /dev/null
+++ b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.MultiLineReceiver;
+import com.android.ddmlib.SyncService;
+import com.android.ddmlib.SyncService.ISyncProgressMonitor;
+import com.android.ddmlib.SyncService.SyncResult;
+import com.android.hosttest.DeviceTestCase;
+import com.android.hosttest.DeviceTestSuite;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Test;
+
+/**
+ * Set of tests that verify host side install cases
+ */
+public class PackageManagerHostTests extends DeviceTestCase {
+
+    // testPushAppPrivate constants
+    // these constants must match values defined in test-apps/SimpleTestApp
+    private static final String SIMPLE_APK = "SimpleTestApp.apk";
+    private static final String SIMPLE_PKG = "com.android.framework.simpletestapp";
+    // TODO: get this value from Android Environment instead of hardcoding
+    private static final String APP_PRIVATE_PATH = "/data/app-private/";
+
+    private static final String LOG_TAG = "PackageManagerHostTests";
+
+    private static final int MAX_WAIT_FOR_DEVICE_TIME = 120 * 1000;
+    private static final int WAIT_FOR_DEVICE_POLL_TIME = 10 * 1000;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // ensure apk path has been set before test is run
+        assertNotNull(getTestAppPath());
+    }
+
+    /**
+     * Regression test to verify that pushing an apk to the private app directory doesn't install
+     * the app, and otherwise cause the system to blow up.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    public void testPushAppPrivate() throws IOException, InterruptedException {
+        Log.i(LOG_TAG, "testing pushing an apk to /data/app-private");
+        final String apkAppPrivatePath =  APP_PRIVATE_PATH + SIMPLE_APK;
+
+        // cleanup test app just in case it was accidently installed
+        getDevice().uninstallPackage(SIMPLE_PKG);
+        executeShellCommand("stop");
+        pushFile(getTestAppFilePath(SIMPLE_APK), apkAppPrivatePath);
+        // sanity check to make sure file is there
+        assertTrue(doesRemoteFileExist(apkAppPrivatePath));
+        executeShellCommand("start");
+
+        waitForDevice();
+
+        // grep for package to make sure its not installed
+        assertFalse(doesPackageExist(SIMPLE_PKG));
+        // ensure it has been deleted from app-private
+        assertFalse(doesRemoteFileExist(apkAppPrivatePath));
+    }
+
+    /**
+     * Helper method to push a file to device
+     * @param apkAppPrivatePath
+     * @throws IOException
+     */
+    private void pushFile(final String localFilePath, final String destFilePath)
+            throws IOException {
+        SyncResult result = getDevice().getSyncService().pushFile(
+                localFilePath, destFilePath,
+                new NullSyncProgressMonitor());
+        assertEquals(SyncService.RESULT_OK, result.getCode());
+    }
+
+    /**
+     * Helper method to determine if file on device exists.
+     *
+     * @param destPath the absolute path of file on device to check
+     * @return <code>true</code> if file exists, <code>false</code> otherwise.
+     * @throws IOException if adb shell command failed
+     */
+    private boolean doesRemoteFileExist(String destPath) throws IOException {
+        String lsGrep = executeShellCommand(String.format("ls %s",
+                destPath));
+        return !lsGrep.contains("No such file or directory");
+    }
+
+    /**
+     * Helper method to determine if package on device exists.
+     *
+     * @param packageName the Android manifest package to check.
+     * @return <code>true</code> if package exists, <code>false</code> otherwise
+     * @throws IOException if adb shell command failed
+     */
+    private boolean doesPackageExist(String packageName) throws IOException {
+        String pkgGrep = executeShellCommand(String.format("pm path %s",
+                packageName));
+        return pkgGrep.contains("package:");
+    }
+
+    /**
+     * Waits for device's package manager to respond.
+     *
+     * @throws InterruptedException
+     * @throws IOException
+     */
+    private void waitForDevice() throws InterruptedException, IOException {
+        Log.i(LOG_TAG, "waiting for device");
+        int currentWaitTime = 0;
+        // poll the package manager until it returns something for android
+        while (!doesPackageExist("android")) {
+            Thread.sleep(WAIT_FOR_DEVICE_POLL_TIME);
+            currentWaitTime += WAIT_FOR_DEVICE_POLL_TIME;
+            if (currentWaitTime > MAX_WAIT_FOR_DEVICE_TIME) {
+                Log.e(LOG_TAG, "time out waiting for device");
+                throw new InterruptedException();
+            }
+        }
+    }
+
+    /**
+     * Helper method which executes a adb shell command and returns output as a {@link String}
+     * @return
+     * @throws IOException
+     */
+    private String executeShellCommand(String command) throws IOException {
+        Log.d(LOG_TAG, String.format("adb shell %s", command));
+        CollectingOutputReceiver receiver = new CollectingOutputReceiver();
+        getDevice().executeShellCommand(command, receiver);
+        String output = receiver.getOutput();
+        Log.d(LOG_TAG, String.format("Result: %s", output));
+        return output;
+    }
+
+    /**
+     * Get the absolute file system location of test app with given filename
+     * @param fileName the file name of the test app apk
+     * @return {@link String} of absolute file path
+     */
+    private String getTestAppFilePath(String fileName) {
+        return String.format("%s%s%s", getTestAppPath(), File.separator, fileName);
+    }
+
+    public static Test suite() {
+        return new DeviceTestSuite(PackageManagerHostTests.class);
+    }
+
+    /**
+     * A {@link IShellOutputReceiver} which collects the whole shell output into one {@link String}
+     */
+    private static class CollectingOutputReceiver extends MultiLineReceiver {
+
+        private StringBuffer mOutputBuffer = new StringBuffer();
+
+        public String getOutput() {
+            return mOutputBuffer.toString();
+        }
+
+        @Override
+        public void processNewLines(String[] lines) {
+            for (String line: lines) {
+                mOutputBuffer.append(line);
+                mOutputBuffer.append("\n");
+            }
+        }
+
+        public boolean isCancelled() {
+            return false;
+        }
+    }
+
+    private static class NullSyncProgressMonitor implements ISyncProgressMonitor {
+        public void advance(int work) {
+            // ignore
+        }
+
+        public boolean isCanceled() {
+            // ignore
+            return false;
+        }
+
+        public void start(int totalWork) {
+            // ignore
+
+        }
+
+        public void startSubTask(String name) {
+            // ignore
+        }
+
+        public void stop() {
+            // ignore
+        }
+    }
+}
diff --git a/core/tests/hosttests/test-apps/Android.mk b/core/tests/hosttests/test-apps/Android.mk
new file mode 100644
index 0000000..e25764f
--- /dev/null
+++ b/core/tests/hosttests/test-apps/Android.mk
@@ -0,0 +1,21 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/core/tests/hosttests/test-apps/SimpleTestApp/Android.mk b/core/tests/hosttests/test-apps/SimpleTestApp/Android.mk
new file mode 100644
index 0000000..82543aa
--- /dev/null
+++ b/core/tests/hosttests/test-apps/SimpleTestApp/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_PACKAGE_NAME := SimpleTestApp
+
+include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/SimpleTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/SimpleTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..ae36fe7
--- /dev/null
+++ b/core/tests/hosttests/test-apps/SimpleTestApp/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.simpletestapp">
+
+    <!--
+    A simple empty app used to test various install scenarios/
+    -->
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/SimpleTestApp/src/com/android/framework/simpletestapp/SimpleAppActivity.java b/core/tests/hosttests/test-apps/SimpleTestApp/src/com/android/framework/simpletestapp/SimpleAppActivity.java
new file mode 100644
index 0000000..b7bbf94
--- /dev/null
+++ b/core/tests/hosttests/test-apps/SimpleTestApp/src/com/android/framework/simpletestapp/SimpleAppActivity.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.simpletestapp;
+
+import android.app.Activity;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class SimpleAppActivity extends Activity {
+
+}
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index b1d588e..b94df84 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -238,7 +238,10 @@
             final int count = sets.length;
             mStateListState.mStateSets = new int[count][];
             for (int i = 0; i < count; i++) {
-                mStateListState.mStateSets[i] = sets[i].clone();
+                final int[] set = sets[i];
+                if (set != null) {
+                    mStateListState.mStateSets[i] = set.clone();
+                }
             }
             mMutated = true;
         }
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index 207ad15..6288bc4 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -34,6 +34,12 @@
 
 Element::~Element()
 {
+    for (uint32_t ct = 0; ct < mRSC->mStateElement.mElements.size(); ct++) {
+        if (mRSC->mStateElement.mElements[ct] == this) {
+            mRSC->mStateElement.mElements.removeAt(ct);
+            break;
+        }
+    }
     clear();
 }
 
@@ -78,27 +84,62 @@
 }
 
 
-Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
+const Element * Element::create(Context *rsc, RsDataType dt, RsDataKind dk,
                             bool isNorm, uint32_t vecSize)
 {
+    // Look for an existing match.
+    for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
+        const Element *ee = rsc->mStateElement.mElements[ct];
+        if (!ee->getFieldCount() &&
+            (ee->getComponent().getType() == dt) &&
+            (ee->getComponent().getKind() == dk) &&
+            (ee->getComponent().getIsNormalized() == isNorm) &&
+            (ee->getComponent().getVectorSize() == vecSize)) {
+            // Match
+            ee->incUserRef();
+            return ee;
+        }
+    }
+
     Element *e = new Element(rsc);
     e->mComponent.set(dt, dk, isNorm, vecSize);
     e->mBits = e->mComponent.getBits();
+    rsc->mStateElement.mElements.push(e);
     return e;
 }
 
-Element * Element::create(Context *rsc, size_t count, const Element **ein,
+const Element * Element::create(Context *rsc, size_t count, const Element **ein,
                             const char **nin, const size_t * lengths)
 {
+    // Look for an existing match.
+    for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
+        const Element *ee = rsc->mStateElement.mElements[ct];
+        if (ee->getFieldCount() == count) {
+            bool match = true;
+            for (uint32_t i=0; i < count; i++) {
+                if ((ee->mFields[i].e.get() != ein[i]) ||
+                    (ee->mFields[i].name.length() != lengths[i]) ||
+                    (ee->mFields[i].name != nin[i])) {
+                    match = false;
+                    break;
+                }
+            }
+            if (match) {
+                ee->incUserRef();
+                return ee;
+            }
+        }
+    }
+
     Element *e = new Element(rsc);
     e->mFields = new ElementField_t [count];
     e->mFieldCount = count;
-
     for (size_t ct=0; ct < count; ct++) {
         e->mFields[ct].e.set(ein[ct]);
         e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
     }
 
+    rsc->mStateElement.mElements.push(e);
     return e;
 }
 
@@ -168,6 +209,7 @@
 
 ElementState::~ElementState()
 {
+    rsAssert(!mElements.size());
 }
 
 
@@ -184,9 +226,9 @@
                             uint32_t vecSize)
 {
     //LOGE("rsi_ElementCreate %i %i %i %i", dt, dk, norm, vecSize);
-    Element *e = Element::create(rsc, dt, dk, norm, vecSize);
+    const Element *e = Element::create(rsc, dt, dk, norm, vecSize);
     e->incUserRef();
-    return e;
+    return (RsElement)e;
 }
 
 RsElement rsi_ElementCreate2(Context *rsc,
@@ -196,9 +238,9 @@
                              const size_t * nameLengths)
 {
     //LOGE("rsi_ElementCreate2 %i", count);
-    Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths);
+    const Element *e = Element::create(rsc, count, (const Element **)ein, names, nameLengths);
     e->incUserRef();
-    return e;
+    return (RsElement)e;
 }
 
 
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index 777e8ee..02a1ca2 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -60,9 +60,9 @@
 
     void dumpLOGV(const char *prefix) const;
 
-    static Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
+    static const Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
                             bool isNorm, uint32_t vecSize);
-    static Element * create(Context *rsc, size_t count, const Element **,
+    static const Element * create(Context *rsc, size_t count, const Element **,
                             const char **, const size_t * lengths);
 
 protected:
@@ -89,6 +89,8 @@
     ElementState();
     ~ElementState();
 
+    // Cache of all existing elements.
+    Vector<const Element *> mElements;
 };
 
 
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 89c5b00..677413e 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -191,6 +191,7 @@
     LOGV("Dumping all objects");
     const ObjectBase * o = rsc->mObjHead;
     while (o) {
+        LOGV(" Object %p", o);
         o->dumpLOGV("  ");
         o = o->mNext;
     }
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index f247022..bb03b87 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -56,6 +56,7 @@
 protected:
     const char *mAllocFile;
     uint32_t mAllocLine;
+    Context *mRSC;
 
 private:
     void add() const;
@@ -64,7 +65,6 @@
     bool checkDelete() const;
 
     char * mName;
-    Context *mRSC;
     mutable int32_t mSysRefCount;
     mutable int32_t mUserRefCount;
 
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 28f13d4..a2b2df4 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -364,7 +364,7 @@
 
 void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
 {
-    RsElement e = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
+    RsElement e = (RsElement) Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1);
 
     rsi_TypeBegin(rsc, e);
     rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 22a267a..9d24c6c 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -31,6 +31,12 @@
 
 Type::~Type()
 {
+    for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
+        if (mRSC->mStateType.mTypes[ct] == this) {
+            mRSC->mStateType.mTypes.removeAt(ct);
+            break;
+        }
+    }
     if (mLODs) {
         delete [] mLODs;
     }
@@ -341,6 +347,18 @@
 {
     TypeState * stc = &rsc->mStateType;
 
+    for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
+        Type *t = stc->mTypes[ct];
+        if (t->getElement() != stc->mElement.get()) continue;
+        if (t->getDimX() != stc->mX) continue;
+        if (t->getDimY() != stc->mY) continue;
+        if (t->getDimZ() != stc->mZ) continue;
+        if (t->getDimLOD() != stc->mLOD) continue;
+        if (t->getDimFaces() != stc->mFaces) continue;
+        t->incUserRef();
+        return t;
+    }
+
     Type * st = new Type(rsc);
     st->incUserRef();
     st->setDimX(stc->mX);
@@ -351,7 +369,7 @@
     st->setDimFaces(stc->mFaces);
     st->compute();
     stc->mElement.clear();
-
+    stc->mTypes.push(st);
     return st;
 }
 
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 4fa4933..28e6274 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -137,6 +137,10 @@
     uint32_t mLOD;
     bool mFaces;
     ObjectBaseRef<const Element> mElement;
+
+
+    // Cache of all existing types.
+    Vector<Type *> mTypes;
 };
 
 
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 8c24ee1..2c0399e 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -59,8 +59,10 @@
 
     Location getLastKnownLocation(String provider);
 
-    /* used by location providers to tell the location manager when it has a new location */
-    void reportLocation(in Location location);
+    // Used by location providers to tell the location manager when it has a new location.
+    // Passive is true if the location is coming from the passive provider, in which case
+    // it need not be shared with other providers.
+    void reportLocation(in Location location, boolean passive);
 
     String getFromLocation(double latitude, double longitude, int maxResults,
         in GeocoderParams params, out List<Address> addrs);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 9027fc2..da760a1 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -81,6 +81,19 @@
     public static final String GPS_PROVIDER = "gps";
 
     /**
+     * A special location provider for receiving locations without actually initiating
+     * a location fix. This provider can be used to passively receive location updates
+     * when other applications or services request them without actually requesting
+     * the locations yourself.  This provider will return locations generated by other
+     * providers.  You can query the {@link Location#getProvider()} method to determine
+     * the origin of the location update.
+     *
+     * Requires the permission android.permission.ACCESS_FINE_LOCATION, although if the GPS
+     * is not enabled this provider might only return coarse fixes.
+     */
+    public static final String PASSIVE_PROVIDER = "passive";
+
+    /**
      * Key used for the Bundle extra holding a boolean indicating whether
      * a proximity alert is entering (true) or exiting (false)..
      */
diff --git a/location/java/android/location/LocationProvider.java b/location/java/android/location/LocationProvider.java
index 3faba58..bb3e2a5 100644
--- a/location/java/android/location/LocationProvider.java
+++ b/location/java/android/location/LocationProvider.java
@@ -71,6 +71,10 @@
      * false otherwise.
      */
     public boolean meetsCriteria(Criteria criteria) {
+        // We do not want to match the special passive provider based on criteria.
+        if (LocationManager.PASSIVE_PROVIDER.equals(mName)) {
+            return false;
+        }
         if ((criteria.getAccuracy() != Criteria.NO_REQUIREMENT) && 
             (criteria.getAccuracy() < getAccuracy())) {
             return false;
diff --git a/location/java/android/location/provider/LocationProvider.java b/location/java/android/location/provider/LocationProvider.java
index 0d028c0..4163def 100644
--- a/location/java/android/location/provider/LocationProvider.java
+++ b/location/java/android/location/provider/LocationProvider.java
@@ -156,7 +156,7 @@
      */
     public void reportLocation(Location location) {
         try {
-            mLocationManager.reportLocation(location);
+            mLocationManager.reportLocation(location, false);
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in reportLocation: ", e);
         }
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index dce3b27..8e84106 100755
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -863,7 +863,7 @@
             }
 
             try {
-                mLocationManager.reportLocation(mLocation);
+                mLocationManager.reportLocation(mLocation, false);
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException calling reportLocation");
             }
diff --git a/location/java/com/android/internal/location/MockProvider.java b/location/java/com/android/internal/location/MockProvider.java
index 2f6fdee..bc1893e 100644
--- a/location/java/com/android/internal/location/MockProvider.java
+++ b/location/java/com/android/internal/location/MockProvider.java
@@ -143,7 +143,7 @@
         mLocation.set(l);
         mHasLocation = true;
         try {
-            mLocationManager.reportLocation(mLocation);
+            mLocationManager.reportLocation(mLocation, false);
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException calling reportLocation");
         }
diff --git a/location/java/com/android/internal/location/PassiveProvider.java b/location/java/com/android/internal/location/PassiveProvider.java
new file mode 100644
index 0000000..7eb711d
--- /dev/null
+++ b/location/java/com/android/internal/location/PassiveProvider.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.location;
+
+import android.location.ILocationManager;
+import android.location.Location;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.location.LocationProviderInterface;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * A passive location provider reports locations received from other providers
+ * for clients that want to listen passively without actually triggering
+ * location updates.
+ *
+ * {@hide}
+ */
+public class PassiveProvider implements LocationProviderInterface {
+
+    private static final String TAG = "PassiveProvider";
+
+    private final ILocationManager mLocationManager;
+    private boolean mTracking;
+
+    public PassiveProvider(ILocationManager locationManager) {
+        mLocationManager = locationManager;
+    }
+
+    public String getName() {
+        return LocationManager.PASSIVE_PROVIDER;
+    }
+
+    public boolean requiresNetwork() {
+        return false;
+    }
+
+    public boolean requiresSatellite() {
+        return false;
+    }
+
+    public boolean requiresCell() {
+        return false;
+    }
+
+    public boolean hasMonetaryCost() {
+        return false;
+    }
+
+    public boolean supportsAltitude() {
+        return false;
+    }
+
+    public boolean supportsSpeed() {
+        return false;
+    }
+
+    public boolean supportsBearing() {
+        return false;
+    }
+
+    public int getPowerRequirement() {
+        return -1;
+    }
+
+    public int getAccuracy() {
+        return -1;
+    }
+
+    public boolean isEnabled() {
+        return true;
+    }
+
+    public void enable() {
+    }
+
+    public void disable() {
+    }
+
+    public int getStatus(Bundle extras) {
+        if (mTracking) {
+            return LocationProvider.AVAILABLE;
+        } else {
+            return LocationProvider.TEMPORARILY_UNAVAILABLE;
+        }
+    }
+
+    public long getStatusUpdateTime() {
+        return -1;
+    }
+
+    public void enableLocationTracking(boolean enable) {
+        mTracking = enable;
+    }
+
+    public void setMinTime(long minTime) {
+    }
+
+    public void updateNetworkState(int state, NetworkInfo info) {
+    }
+
+    public void updateLocation(Location location) {
+        if (mTracking) {
+            try {
+                // pass the location back to the location manager
+                mLocationManager.reportLocation(location, true);
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException calling reportLocation");
+            }
+        }
+    }
+
+    public boolean sendExtraCommand(String command, Bundle extras) {
+        return false;
+    }
+
+    public void addListener(int uid) {
+    }
+
+    public void removeListener(int uid) {
+    }
+}
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index 62a4fe9..18ce5c1 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -327,8 +327,6 @@
      * iterates through all the active streams and pauses any that
      * are playing. It also sets a flag so that any streams that
      * are playing can be resumed by calling autoResume().
-     *
-     * @hide
      */
     public native final void autoPause();
 
@@ -337,8 +335,6 @@
      *
      * Automatically resumes all streams that were paused in previous
      * calls to autoPause().
-     *
-     * @hide
      */
     public native final void autoResume();
 
@@ -412,8 +408,6 @@
     /**
      * Interface definition for a callback to be invoked when all the
      * sounds are loaded.
-     *
-     * @hide
      */
     public interface OnLoadCompleteListener
     {
@@ -429,8 +423,6 @@
 
     /**
      * Sets the callback hook for the OnLoadCompleteListener.
-     *
-     * @hide
      */
     public void setOnLoadCompleteListener(OnLoadCompleteListener listener)
     {
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 1c9f4fd..59a5f9d 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -401,6 +401,9 @@
 
 void AwesomePlayer::onBufferingUpdate() {
     Mutex::Autolock autoLock(mLock);
+    if (!mBufferingEventPending) {
+        return;
+    }
     mBufferingEventPending = false;
 
     if (mDurationUs >= 0) {
@@ -425,6 +428,9 @@
     // Posted whenever any stream finishes playing.
 
     Mutex::Autolock autoLock(mLock);
+    if (!mStreamDoneEventPending) {
+        return;
+    }
     mStreamDoneEventPending = false;
 
     if (mFlags & LOOPING) {
@@ -918,6 +924,12 @@
 
 void AwesomePlayer::onCheckAudioStatus() {
     Mutex::Autolock autoLock(mLock);
+    if (!mAudioStatusEventPending) {
+        // Event was dispatched and while we were blocking on the mutex,
+        // has already been cancelled.
+        return;
+    }
+
     mAudioStatusEventPending = false;
 
     if (mWatchForAudioSeekComplete && !mAudioPlayer->isSeeking()) {
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 75b7b6f..6cf7cff 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -102,7 +102,6 @@
     { MEDIA_MIMETYPE_IMAGE_JPEG, "OMX.TI.JPEG.decode" },
     { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" },
     { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" },
-    { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" },
     { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" },
     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" },
     { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" },
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index d43039d..ea0fc65 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -66,6 +66,7 @@
 import java.io.EOFException;
 import java.io.File;
 import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -517,6 +518,9 @@
                     }
                 }
             }
+        } catch (FileNotFoundException fnf) {
+            // Probably innocuous
+            Log.v(TAG, "No ancestral data");
         } catch (IOException e) {
             Log.w(TAG, "Unable to read token file", e);
         }
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index f0bab81..b566fb7e 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -486,9 +486,11 @@
         // the status bar should be totally disabled, the calls below will
         // have no effect until the device is unlocked.
         if (mStatusBarManager != null) {
-            mStatusBarManager.disable(enabled
+            long ident = Binder.clearCallingIdentity();
+            mStatusBarManager.disable(enabled 
                 ? StatusBarManager.DISABLE_NOTIFICATION_TICKER
                 : StatusBarManager.DISABLE_NONE);
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index e12f2e1..9068966 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -71,6 +71,7 @@
 import com.android.internal.location.GpsNetInitiatedHandler;
 import com.android.internal.location.LocationProviderProxy;
 import com.android.internal.location.MockProvider;
+import com.android.internal.location.PassiveProvider;
 
 /**
  * The service class that manages LocationProviders and issues location
@@ -452,6 +453,11 @@
             mGpsLocationProvider = gpsProvider;
         }
 
+        // create a passive location provider, which is always enabled
+        PassiveProvider passiveProvider = new PassiveProvider(this);
+        addProvider(passiveProvider);
+        mEnabledProviders.add(passiveProvider.getName());
+
         // initialize external network location and geocoder services
         Resources resources = mContext.getResources();
         String serviceName = resources.getString(
@@ -538,7 +544,8 @@
     }
 
     private void checkPermissionsSafe(String provider) {
-        if (LocationManager.GPS_PROVIDER.equals(provider)
+        if ((LocationManager.GPS_PROVIDER.equals(provider)
+                 || LocationManager.PASSIVE_PROVIDER.equals(provider))
             && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
                 != PackageManager.PERMISSION_GRANTED)) {
             throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
@@ -1343,7 +1350,7 @@
         }
     }
 
-    public void reportLocation(Location location) {
+    public void reportLocation(Location location, boolean passive) {
         if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission");
@@ -1351,6 +1358,7 @@
 
         mLocationHandler.removeMessages(MESSAGE_LOCATION_CHANGED, location);
         Message m = Message.obtain(mLocationHandler, MESSAGE_LOCATION_CHANGED, location);
+        m.arg1 = (passive ? 1 : 0);
         mLocationHandler.sendMessageAtFrontOfQueue(m);
     }
 
@@ -1415,8 +1423,8 @@
         return true;
     }
 
-    private void handleLocationChangedLocked(Location location) {
-        String provider = location.getProvider();
+    private void handleLocationChangedLocked(Location location, boolean passive) {
+        String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider());
         ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
         if (records == null || records.size() == 0) {
             return;
@@ -1502,17 +1510,20 @@
                     synchronized (mLock) {
                         Location location = (Location) msg.obj;
                         String provider = location.getProvider();
+                        boolean passive = (msg.arg1 == 1);
 
-                        // notify other providers of the new location
-                        for (int i = mProviders.size() - 1; i >= 0; i--) {
-                            LocationProviderInterface p = mProviders.get(i);
-                            if (!provider.equals(p.getName())) {
-                                p.updateLocation(location);
+                        if (!passive) {
+                            // notify other providers of the new location
+                            for (int i = mProviders.size() - 1; i >= 0; i--) {
+                                LocationProviderInterface p = mProviders.get(i);
+                                if (!provider.equals(p.getName())) {
+                                    p.updateLocation(location);
+                                }
                             }
                         }
 
                         if (isAllowedBySettingsLocked(provider)) {
-                            handleLocationChangedLocked(location);
+                            handleLocationChangedLocked(location, passive);
                         }
                     }
                 }
@@ -1687,6 +1698,10 @@
         boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
         checkMockPermissionsSafe();
 
+        if (LocationManager.PASSIVE_PROVIDER.equals(name)) {
+            throw new IllegalArgumentException("Cannot mock the passive location provider");
+        }
+
         long identity = Binder.clearCallingIdentity();
         synchronized (mLock) {
             MockProvider provider = new MockProvider(name, this,
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 586f63f..6797f78 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1654,7 +1654,7 @@
         if (DBG) log("processPlusCodeWithinNanp,networkDialStr=" + networkDialStr);
         // If there is a plus sign at the beginning of the dial string,
         // Convert the plus sign to the default IDP since it's an international number
-        if (networkDialStr != null &
+        if (networkDialStr != null &&
             networkDialStr.charAt(0) == PLUS_SIGN_CHAR &&
             networkDialStr.length() > 1) {
             String newStr = networkDialStr.substring(1);