149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert/* 249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * Copyright (C) 2010 The Android Open Source Project 349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * 449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * you may not use this file except in compliance with the License. 649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * You may obtain a copy of the License at 749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * 849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * 1049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 1149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 1249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * See the License for the specific language governing permissions and 1449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * limitations under the License. 1549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert */ 1649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 1749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertpackage com.android.quicksearchbox; 1849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 19516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwoodimport com.android.quicksearchbox.util.NamedTaskExecutor; 20e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwoodimport com.android.quicksearchbox.util.NowOrLater; 215229b06f00d20aac76cd8519b37f2a579d61c54fMathew Inwood 2249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.app.SearchManager; 2349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.content.ComponentName; 2449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.content.Context; 2549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.content.Intent; 2649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.graphics.drawable.Drawable; 2749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.net.Uri; 2849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.os.Bundle; 29e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwoodimport android.os.Handler; 3049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertimport android.util.Log; 3149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 3249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert/** 3349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert * Abstract suggestion source implementation. 3449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert */ 3549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringertpublic abstract class AbstractSource implements Source { 3649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 3749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert private static final String TAG = "QSB.AbstractSource"; 3849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 3949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert private final Context mContext; 40e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood private final Handler mUiThread; 4149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 4249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert private IconLoader mIconLoader; 4349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 44516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood private final NamedTaskExecutor mIconLoaderExecutor; 455229b06f00d20aac76cd8519b37f2a579d61c54fMathew Inwood 46516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood public AbstractSource(Context context, Handler uiThread, NamedTaskExecutor iconLoader) { 4749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert mContext = context; 48e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood mUiThread = uiThread; 49516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood mIconLoaderExecutor = iconLoader; 5049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 5149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 5249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert protected Context getContext() { 5349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return mContext; 5449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 5549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 5649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert protected IconLoader getIconLoader() { 5749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert if (mIconLoader == null) { 5849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert String iconPackage = getIconPackage(); 59e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood mIconLoader = new CachingIconLoader( 60516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood new PackageIconLoader(mContext, iconPackage, mUiThread, mIconLoaderExecutor)); 6149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 6249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return mIconLoader; 6349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 6449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 6549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert protected abstract String getIconPackage(); 6649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 6725cbd7d054b92df1fe857d155ccc12f8191c12cfMathew Inwood public boolean isVersionCodeCompatible(int version) { 6825cbd7d054b92df1fe857d155ccc12f8191c12cfMathew Inwood return getVersionCode() == version; 6925cbd7d054b92df1fe857d155ccc12f8191c12cfMathew Inwood } 7025cbd7d054b92df1fe857d155ccc12f8191c12cfMathew Inwood 71e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood public NowOrLater<Drawable> getIcon(String drawableId) { 7249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return getIconLoader().getIcon(drawableId); 7349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 7449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 7549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert public Uri getIconUri(String drawableId) { 7649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return getIconLoader().getIconUri(drawableId); 7749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 7849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 7949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert public Intent createSearchIntent(String query, Bundle appData) { 8049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return createSourceSearchIntent(getIntentComponent(), query, appData); 8149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 8249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 8349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert public static Intent createSourceSearchIntent(ComponentName activity, String query, 8449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert Bundle appData) { 8549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert if (activity == null) { 8649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert Log.w(TAG, "Tried to create search intent with no target activity"); 8749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return null; 8849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 8949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert Intent intent = new Intent(Intent.ACTION_SEARCH); 9049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert intent.setComponent(activity); 9149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert // We need CLEAR_TOP to avoid reusing an old task that has other activities 9349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert // on top of the one we want. 9449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 9549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert intent.putExtra(SearchManager.USER_QUERY, query); 9649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert intent.putExtra(SearchManager.QUERY, query); 9749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert if (appData != null) { 9849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert intent.putExtra(SearchManager.APP_DATA, appData); 9949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 10049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return intent; 10149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 10249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 10349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert protected Intent createVoiceWebSearchIntent(Bundle appData) { 10449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return QsbApplication.get(mContext).getVoiceSearch() 10549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert .createVoiceWebSearchIntent(appData); 10649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 10749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 108848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani public Source getRoot() { 109848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani return this; 110848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 111848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani 11249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert @Override 11349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert public boolean equals(Object o) { 114848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani if (o != null && o instanceof Source) { 115848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani Source s = ((Source) o).getRoot(); 116848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani if (s.getClass().equals(this.getClass())) { 117848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani return s.getName().equals(getName()); 118848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 11949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 12049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return false; 12149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 12249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 12349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert @Override 12449fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert public int hashCode() { 12549fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return getName().hashCode(); 12649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 12749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 12849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert @Override 12949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert public String toString() { 13049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return "Source{name=" + getName() + "}"; 13149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 13249fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 13349fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert} 134