Loading api/current.xml +11 −0 Original line number Diff line number Diff line Loading @@ -23917,6 +23917,17 @@ visibility="public" > </field> <field name="INTENT_ACTION_SELECT_SEARCH_SOURCE" type="java.lang.String" transient="false" volatile="false" value=""android.intent.action.SELECT_SEARCH_SOURCE"" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="INTENT_ACTION_WEB_SEARCH_SETTINGS" type="java.lang.String" transient="false" core/java/android/app/SearchDialog.java +12 −7 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ import android.widget.AdapterView; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; Loading Loading @@ -106,7 +105,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS // views & widgets private TextView mBadgeLabel; private ImageView mAppIcon; private SearchSourceSelector mSourceSelector; private SearchAutoComplete mSearchAutoComplete; private Button mGoButton; private ImageButton mVoiceButton; Loading Loading @@ -209,7 +208,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS mBadgeLabel = (TextView) findViewById(com.android.internal.R.id.search_badge); mSearchAutoComplete = (SearchAutoComplete) findViewById(com.android.internal.R.id.search_src_text); mAppIcon = (ImageView) findViewById(com.android.internal.R.id.search_app_icon); mSourceSelector = new SearchSourceSelector( findViewById(com.android.internal.R.id.search_source_selector)); mGoButton = (Button) findViewById(com.android.internal.R.id.search_go_btn); mVoiceButton = (ImageButton) findViewById(com.android.internal.R.id.search_voice_btn); mSearchPlate = findViewById(com.android.internal.R.id.search_plate); Loading Loading @@ -606,13 +606,16 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS } private void updateSearchAppIcon() { mSourceSelector.setSource(mSearchable.getSearchActivity()); mSourceSelector.setAppSearchData(mAppSearchData); // In Donut, we special-case the case of the browser to hide the app icon as if it were // global search, for extra space for url entry. // // TODO: Remove this special case once the issue has been reconciled in Eclair. if (mGlobalSearchMode || isBrowserSearch()) { mAppIcon.setImageResource(0); mAppIcon.setVisibility(View.GONE); mSourceSelector.setSourceIcon(null); mSourceSelector.setVisibility(View.GONE); mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_GLOBAL, mSearchPlate.getPaddingTop(), mSearchPlate.getPaddingRight(), Loading @@ -628,8 +631,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS icon = pm.getDefaultActivityIcon(); Log.w(LOG_TAG, mLaunchComponent + " not found, using generic app icon"); } mAppIcon.setImageDrawable(icon); mAppIcon.setVisibility(View.VISIBLE); mSourceSelector.setSourceIcon(icon); mSourceSelector.setVisibility(View.VISIBLE); mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_NON_GLOBAL, mSearchPlate.getPaddingTop(), mSearchPlate.getPaddingRight(), Loading Loading @@ -812,6 +815,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS if (!mSearchAutoComplete.isPerformingCompletion()) { // The user changed the query, remember it. mUserQuery = s == null ? "" : s.toString(); mSourceSelector.setQuery(mUserQuery); } } Loading Loading @@ -1927,6 +1931,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS query = ""; } mUserQuery = query; mSourceSelector.setQuery(query); mSearchAutoComplete.setText(query); mSearchAutoComplete.setSelection(query.length()); } Loading core/java/android/app/SearchManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -1346,6 +1346,7 @@ public class SearchManager * @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)}. Loading Loading @@ -1611,6 +1612,15 @@ public class SearchManager */ public final static String SUGGEST_PARAMETER_LIMIT = "limit"; /** * Intent action for opening the search source selection activity. * The intent may include these extra values: * {@link #QUERY}, * {@link #APP_DATA}. */ public static final String INTENT_ACTION_SELECT_SEARCH_SOURCE = "android.intent.action.SELECT_SEARCH_SOURCE"; /** * If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION}, * the search dialog will switch to a different suggestion source when the Loading core/java/android/app/SearchSourceSelector.java 0 → 100644 +197 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 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.app; import com.android.internal.R; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Intent; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.ImageButton; import java.util.List; /** * Utilities for setting up the search source selector. * * This class has two copies: * android.app.SearchSourceSelector * com.android.quicksearchbox.ui.SearchSourceSelector * * They should keep the same look and feel as much as possible, * but only the intent details must absolutely stay in sync. * * @hide */ public class SearchSourceSelector implements View.OnClickListener { private static final String TAG = "SearchSourceSelector"; // TODO: This should be defined in android.provider.Applications, // and have a less made-up value. private static final String APPLICATION_TYPE = "application/vnd.android.application"; public static final int ICON_VIEW_ID = R.id.search_source_selector_icon; private final View mView; private final ImageButton mIconView; private ComponentName mSource; private Bundle mAppSearchData; private String mQuery; public SearchSourceSelector(View view) { mView = view; mIconView = (ImageButton) view.findViewById(ICON_VIEW_ID); mIconView.setOnClickListener(this); } /** * Sets the icon displayed in the search source selector. */ public void setSourceIcon(Drawable icon) { mIconView.setImageDrawable(icon); } /** * Sets the current search source. */ public void setSource(ComponentName source) { mSource = source; } /** * Sets the app-specific data that will be passed to the search activity if * the user opens the source selector and chooses a source. */ public void setAppSearchData(Bundle appSearchData) { mAppSearchData = appSearchData; } /** * Sets the initial query that will be passed to the search activity if * the user opens the source selector and chooses a source. */ public void setQuery(String query) { mQuery = query; } public void setVisibility(int visibility) { mView.setVisibility(visibility); } /** * Creates an intent for opening the search source selector activity. * * @param source The current search source. * @param query The initial query that will be passed to the search activity if * the user opens the source selector and chooses a source. * @param appSearchData The app-specific data that will be passed to the search * activity if the user opens the source selector and chooses a source. */ public static Intent createIntent(ComponentName source, String query, Bundle appSearchData) { Intent intent = new Intent(SearchManager.INTENT_ACTION_SELECT_SEARCH_SOURCE); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); Uri sourceUri = componentNameToUri(source); if (sourceUri != null) { intent.setDataAndType(sourceUri, APPLICATION_TYPE); } if (query != null) { intent.putExtra(SearchManager.QUERY, query); } if (query != null) { intent.putExtra(SearchManager.APP_DATA, appSearchData); } return intent; } /** * Gets the search source from which the given * {@link SearchManager.INTENT_ACTION_SELECT_SEARCH_SOURCE} intent was sent. */ public static ComponentName getSource(Intent intent) { return uriToComponentName(intent.getData()); } private static Uri componentNameToUri(ComponentName name) { if (name == null) return null; // TODO: This URI format is specificed in android.provider.Applications which is @hidden return new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority("applications") .appendEncodedPath("applications") .appendPath(name.getPackageName()) .appendPath(name.getClassName()) .build(); } private static ComponentName uriToComponentName(Uri uri) { if (uri == null) return null; List<String> path = uri.getPathSegments(); if (path == null || path.size() != 3) return null; String pkg = path.get(1); String cls = path.get(2); if (TextUtils.isEmpty(pkg) || TextUtils.isEmpty(cls)) return null; return new ComponentName(pkg, cls); } public void onClick(View v) { trigger(); } private void trigger() { try { Intent intent = createIntent(mSource, mQuery, mAppSearchData); intent.setSourceBounds(getOnScreenRect(mIconView)); mIconView.getContext().startActivity(intent); } catch (ActivityNotFoundException ex) { Log.e(TAG, "No source selector activity found", ex); } } // TODO: This code is replicated in lots of places: // - android.provider.ContactsContract.QuickContact.showQuickContact() // - android.widget.RemoteViews.setOnClickPendingIntent() // - com.android.launcher2.Launcher.onClick() // - com.android.launcher.Launcher.onClick() // - com.android.server.status.StatusBarService.Launcher.onClick() private static Rect getOnScreenRect(View v) { final float appScale = v.getResources().getCompatibilityInfo().applicationScale; final int[] pos = new int[2]; v.getLocationOnScreen(pos); final Rect rect = new Rect(); rect.left = (int) (pos[0] * appScale + 0.5f); rect.top = (int) (pos[1] * appScale + 0.5f); rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f); rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f); return rect; } } core/res/res/drawable-hdpi/search_source_selector_indicator.png 0 → 100644 +252 B Loading image diff... Loading
api/current.xml +11 −0 Original line number Diff line number Diff line Loading @@ -23917,6 +23917,17 @@ visibility="public" > </field> <field name="INTENT_ACTION_SELECT_SEARCH_SOURCE" type="java.lang.String" transient="false" volatile="false" value=""android.intent.action.SELECT_SEARCH_SOURCE"" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> <field name="INTENT_ACTION_WEB_SEARCH_SETTINGS" type="java.lang.String" transient="false"
core/java/android/app/SearchDialog.java +12 −7 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ import android.widget.AdapterView; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; Loading Loading @@ -106,7 +105,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS // views & widgets private TextView mBadgeLabel; private ImageView mAppIcon; private SearchSourceSelector mSourceSelector; private SearchAutoComplete mSearchAutoComplete; private Button mGoButton; private ImageButton mVoiceButton; Loading Loading @@ -209,7 +208,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS mBadgeLabel = (TextView) findViewById(com.android.internal.R.id.search_badge); mSearchAutoComplete = (SearchAutoComplete) findViewById(com.android.internal.R.id.search_src_text); mAppIcon = (ImageView) findViewById(com.android.internal.R.id.search_app_icon); mSourceSelector = new SearchSourceSelector( findViewById(com.android.internal.R.id.search_source_selector)); mGoButton = (Button) findViewById(com.android.internal.R.id.search_go_btn); mVoiceButton = (ImageButton) findViewById(com.android.internal.R.id.search_voice_btn); mSearchPlate = findViewById(com.android.internal.R.id.search_plate); Loading Loading @@ -606,13 +606,16 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS } private void updateSearchAppIcon() { mSourceSelector.setSource(mSearchable.getSearchActivity()); mSourceSelector.setAppSearchData(mAppSearchData); // In Donut, we special-case the case of the browser to hide the app icon as if it were // global search, for extra space for url entry. // // TODO: Remove this special case once the issue has been reconciled in Eclair. if (mGlobalSearchMode || isBrowserSearch()) { mAppIcon.setImageResource(0); mAppIcon.setVisibility(View.GONE); mSourceSelector.setSourceIcon(null); mSourceSelector.setVisibility(View.GONE); mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_GLOBAL, mSearchPlate.getPaddingTop(), mSearchPlate.getPaddingRight(), Loading @@ -628,8 +631,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS icon = pm.getDefaultActivityIcon(); Log.w(LOG_TAG, mLaunchComponent + " not found, using generic app icon"); } mAppIcon.setImageDrawable(icon); mAppIcon.setVisibility(View.VISIBLE); mSourceSelector.setSourceIcon(icon); mSourceSelector.setVisibility(View.VISIBLE); mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_NON_GLOBAL, mSearchPlate.getPaddingTop(), mSearchPlate.getPaddingRight(), Loading Loading @@ -812,6 +815,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS if (!mSearchAutoComplete.isPerformingCompletion()) { // The user changed the query, remember it. mUserQuery = s == null ? "" : s.toString(); mSourceSelector.setQuery(mUserQuery); } } Loading Loading @@ -1927,6 +1931,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS query = ""; } mUserQuery = query; mSourceSelector.setQuery(query); mSearchAutoComplete.setText(query); mSearchAutoComplete.setSelection(query.length()); } Loading
core/java/android/app/SearchManager.java +10 −0 Original line number Diff line number Diff line Loading @@ -1346,6 +1346,7 @@ public class SearchManager * @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)}. Loading Loading @@ -1611,6 +1612,15 @@ public class SearchManager */ public final static String SUGGEST_PARAMETER_LIMIT = "limit"; /** * Intent action for opening the search source selection activity. * The intent may include these extra values: * {@link #QUERY}, * {@link #APP_DATA}. */ public static final String INTENT_ACTION_SELECT_SEARCH_SOURCE = "android.intent.action.SELECT_SEARCH_SOURCE"; /** * If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION}, * the search dialog will switch to a different suggestion source when the Loading
core/java/android/app/SearchSourceSelector.java 0 → 100644 +197 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 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.app; import com.android.internal.R; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Intent; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.ImageButton; import java.util.List; /** * Utilities for setting up the search source selector. * * This class has two copies: * android.app.SearchSourceSelector * com.android.quicksearchbox.ui.SearchSourceSelector * * They should keep the same look and feel as much as possible, * but only the intent details must absolutely stay in sync. * * @hide */ public class SearchSourceSelector implements View.OnClickListener { private static final String TAG = "SearchSourceSelector"; // TODO: This should be defined in android.provider.Applications, // and have a less made-up value. private static final String APPLICATION_TYPE = "application/vnd.android.application"; public static final int ICON_VIEW_ID = R.id.search_source_selector_icon; private final View mView; private final ImageButton mIconView; private ComponentName mSource; private Bundle mAppSearchData; private String mQuery; public SearchSourceSelector(View view) { mView = view; mIconView = (ImageButton) view.findViewById(ICON_VIEW_ID); mIconView.setOnClickListener(this); } /** * Sets the icon displayed in the search source selector. */ public void setSourceIcon(Drawable icon) { mIconView.setImageDrawable(icon); } /** * Sets the current search source. */ public void setSource(ComponentName source) { mSource = source; } /** * Sets the app-specific data that will be passed to the search activity if * the user opens the source selector and chooses a source. */ public void setAppSearchData(Bundle appSearchData) { mAppSearchData = appSearchData; } /** * Sets the initial query that will be passed to the search activity if * the user opens the source selector and chooses a source. */ public void setQuery(String query) { mQuery = query; } public void setVisibility(int visibility) { mView.setVisibility(visibility); } /** * Creates an intent for opening the search source selector activity. * * @param source The current search source. * @param query The initial query that will be passed to the search activity if * the user opens the source selector and chooses a source. * @param appSearchData The app-specific data that will be passed to the search * activity if the user opens the source selector and chooses a source. */ public static Intent createIntent(ComponentName source, String query, Bundle appSearchData) { Intent intent = new Intent(SearchManager.INTENT_ACTION_SELECT_SEARCH_SOURCE); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); Uri sourceUri = componentNameToUri(source); if (sourceUri != null) { intent.setDataAndType(sourceUri, APPLICATION_TYPE); } if (query != null) { intent.putExtra(SearchManager.QUERY, query); } if (query != null) { intent.putExtra(SearchManager.APP_DATA, appSearchData); } return intent; } /** * Gets the search source from which the given * {@link SearchManager.INTENT_ACTION_SELECT_SEARCH_SOURCE} intent was sent. */ public static ComponentName getSource(Intent intent) { return uriToComponentName(intent.getData()); } private static Uri componentNameToUri(ComponentName name) { if (name == null) return null; // TODO: This URI format is specificed in android.provider.Applications which is @hidden return new Uri.Builder() .scheme(ContentResolver.SCHEME_CONTENT) .authority("applications") .appendEncodedPath("applications") .appendPath(name.getPackageName()) .appendPath(name.getClassName()) .build(); } private static ComponentName uriToComponentName(Uri uri) { if (uri == null) return null; List<String> path = uri.getPathSegments(); if (path == null || path.size() != 3) return null; String pkg = path.get(1); String cls = path.get(2); if (TextUtils.isEmpty(pkg) || TextUtils.isEmpty(cls)) return null; return new ComponentName(pkg, cls); } public void onClick(View v) { trigger(); } private void trigger() { try { Intent intent = createIntent(mSource, mQuery, mAppSearchData); intent.setSourceBounds(getOnScreenRect(mIconView)); mIconView.getContext().startActivity(intent); } catch (ActivityNotFoundException ex) { Log.e(TAG, "No source selector activity found", ex); } } // TODO: This code is replicated in lots of places: // - android.provider.ContactsContract.QuickContact.showQuickContact() // - android.widget.RemoteViews.setOnClickPendingIntent() // - com.android.launcher2.Launcher.onClick() // - com.android.launcher.Launcher.onClick() // - com.android.server.status.StatusBarService.Launcher.onClick() private static Rect getOnScreenRect(View v) { final float appScale = v.getResources().getCompatibilityInfo().applicationScale; final int[] pos = new int[2]; v.getLocationOnScreen(pos); final Rect rect = new Rect(); rect.left = (int) (pos[0] * appScale + 0.5f); rect.top = (int) (pos[1] * appScale + 0.5f); rect.right = (int) ((pos[0] + v.getWidth()) * appScale + 0.5f); rect.bottom = (int) ((pos[1] + v.getHeight()) * appScale + 0.5f); return rect; } }
core/res/res/drawable-hdpi/search_source_selector_indicator.png 0 → 100644 +252 B Loading image diff...