Merge change I7daa7ae8 into eclair-mr2

* changes:
  move event log tags used by SyncAdapter into a local .logtags file
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 1f17476..5d9034b 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -16,10 +16,16 @@
 
 package android.app;
 
+import android.Manifest;
+import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Bundle;
@@ -1326,6 +1332,21 @@
     public final static String EXTRA_DATA_KEY = "intent_extra_data_key";
 
     /**
+     * String extra data key for {@link Intent#ACTION_GLOBAL_SEARCH} intents. Contains the initial
+     * query to show in the global search activity.
+     *
+     * @hide Pending API council approval
+     */
+    public final static String INITIAL_QUERY = "initial_query";
+
+    /**
+     * Boolean extra data key for {@link Intent#ACTION_GLOBAL_SEARCH} intents. If {@code true},
+     * the initial query should be selected.
+     *
+     * @hide Pending API council approval
+     */
+    public final static String SELECT_INITIAL_QUERY = "select_initial_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)}.
      *
@@ -1756,7 +1777,13 @@
                             boolean globalSearch) {
         if (mIdent == 0) throw new IllegalArgumentException(
                 "Called from outside of an Activity context");
-        if (!globalSearch && !mAssociatedPackage.equals(launchActivity.getPackageName())) {
+
+        if (globalSearch) {
+            startGlobalSearch(initialQuery, selectInitialQuery, appSearchData);
+            return;
+        }
+
+        if (!mAssociatedPackage.equals(launchActivity.getPackageName())) {
             Log.w(TAG, "invoking app search on a different package " +
                     "not associated with this search manager");
         }
@@ -1770,6 +1797,65 @@
     }
 
     /**
+     * Starts the global search activity.
+     */
+    private void startGlobalSearch(String initialQuery, boolean selectInitialQuery,
+            Bundle appSearchData) {
+        ComponentName globalSearchActivity = getGlobalSearchActivity();
+        if (globalSearchActivity == null) {
+            Log.w(TAG, "No global search activity found.");
+            return;
+        }
+        Intent intent = new Intent(Intent.ACTION_GLOBAL_SEARCH);
+        intent.setComponent(globalSearchActivity);
+        // TODO: Always pass name of calling package as an extra?
+        if (appSearchData != null) {
+            intent.putExtra(APP_DATA, appSearchData);
+        }
+        if (!TextUtils.isEmpty(initialQuery)) {
+            intent.putExtra(INITIAL_QUERY, initialQuery);
+        }
+        if (selectInitialQuery) {
+            intent.putExtra(SELECT_INITIAL_QUERY, selectInitialQuery);
+        }
+        try {
+            if (DBG) Log.d(TAG, "Starting global search: " + intent.toUri(0));
+            mContext.startActivity(intent);
+        } catch (ActivityNotFoundException ex) {
+            Log.e(TAG, "Global search activity not found: " + globalSearchActivity);
+        }
+    }
+
+    /**
+     * Gets the name of the global search activity.
+     *
+     * This is currently implemented by returning the first activity that handles
+     * the GLOBAL_SEARCH intent and has the GLOBAL_SEARCH permission. If we allow
+     * more than one global search acitivity to be installed, this code must be changed.
+     *
+     * TODO: Doing this every time we start global search is inefficient. Will fix that once
+     * we have settled on the right mechanism for finding the global search activity.
+     */
+    private ComponentName getGlobalSearchActivity() {
+        Intent intent = new Intent(Intent.ACTION_GLOBAL_SEARCH);
+        PackageManager pm = mContext.getPackageManager();
+        List<ResolveInfo> activities =
+                pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+        int count = activities.size();
+        for (int i = 0; i < count; i++) {
+            ActivityInfo ai = activities.get(i).activityInfo;
+            if (pm.checkPermission(Manifest.permission.GLOBAL_SEARCH,
+                    ai.packageName) == PackageManager.PERMISSION_GRANTED) {
+                return new ComponentName(ai.packageName, ai.name);
+            } else {
+                Log.w(TAG, "Package " + ai.packageName + " wants to handle GLOBAL_SEARCH, "
+                        + "but does not have the GLOBAL_SEARCH permission.");
+            }
+        }
+        return null;
+    }
+
+    /**
      * Similar to {@link #startSearch} but actually fires off the search query after invoking
      * the search dialog.  Made available for testing purposes.
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a96e896..dfdfa15 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1102,6 +1102,16 @@
     public static final String ACTION_SEARCH_LONG_PRESS = "android.intent.action.SEARCH_LONG_PRESS";
 
     /**
+     * Activity Action: Start the global search activity.
+     * <p>Input: Nothing.
+     * <p>Output: Nothing.
+     *
+     * @hide Pending API council approval
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_GLOBAL_SEARCH = "android.intent.action.GLOBAL_SEARCH";
+
+    /**
      * Activity Action: The user pressed the "Report" button in the crash/ANR dialog.
      * This intent is delivered to the package which installed the application, usually
      * the Market.
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index a796fe9..ae53dbe2 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -1252,6 +1252,28 @@
                 }
 
                 /**
+                 * Convenience method to move a playlist item to a new location
+                 * @param res The content resolver to use
+                 * @param playlistId The numeric id of the playlist
+                 * @param from The position of the item to move
+                 * @param to The position to move the item to
+                 * @return true on success
+                 * @hide
+                 */
+                public static final boolean moveItem(ContentResolver res,
+                        long playlistId, int from, int to) {
+                    Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external",
+                            playlistId)
+                            .buildUpon()
+                            .appendEncodedPath(String.valueOf(from))
+                            .appendQueryParameter("move", "true")
+                            .build();
+                    ContentValues values = new ContentValues();
+                    values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, to);
+                    return res.update(uri, values, null, null) != 0;
+                }
+
+                /**
                  * The ID within the playlist.
                  */
                 public static final String _ID = "_id";
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index b8f0a7e..8f24041 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -489,7 +490,10 @@
                 mUri = null;
             }
         } else if (mUri != null) {
-            if ("content".equals(mUri.getScheme())) {
+            String scheme = mUri.getScheme();
+            if (ContentResolver.SCHEME_CONTENT.equals(scheme)
+                    || ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)
+                    || ContentResolver.SCHEME_FILE.equals(scheme)) {
                 try {
                     d = Drawable.createFromStream(
                         mContext.getContentResolver().openInputStream(mUri),