1fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert/* 2fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * Copyright (C) 2009 The Android Open Source Project 3fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * 4fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 5fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * you may not use this file except in compliance with the License. 6fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * You may obtain a copy of the License at 7fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * 8fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 9fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * 10fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * Unless required by applicable law or agreed to in writing, software 11fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 12fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * See the License for the specific language governing permissions and 14fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * limitations under the License. 15fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert */ 16fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 17fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertpackage com.android.quicksearchbox; 18fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 19516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwoodimport com.android.quicksearchbox.util.NamedTaskExecutor; 20516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood 21fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.app.SearchManager; 22fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.app.SearchableInfo; 23fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.content.ComponentName; 24fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.content.Context; 25fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.content.pm.PackageManager.NameNotFoundException; 26e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwoodimport android.os.Handler; 27fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport android.util.Log; 28fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 29fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport java.util.Collection; 30fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringertimport java.util.HashMap; 31b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringertimport java.util.List; 32fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 33fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert/** 34fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * Maintains a list of search sources. 35fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert */ 36883c1bf364e38c5b133afb55f8493a14b65f4dd4Bjorn Bringertpublic class SearchableSources implements Sources { 37fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 38fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // set to true to enable the more verbose debug logging for this file 39fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final boolean DBG = false; 40fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private static final String TAG = "QSB.SearchableSources"; 41fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 42fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private final Context mContext; 43fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private final SearchManager mSearchManager; 44e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood private final Handler mUiThread; 45cd4accc7899fa7b756e1c430d6b196525abd5c3cMathew Inwood private final Config mConfig; 46fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 4762adab88055fd0ef6779242245cdc8c3ae5f999cBjorn Bringert // All suggestion sources, by name. 4862adab88055fd0ef6779242245cdc8c3ae5f999cBjorn Bringert private HashMap<String, Source> mSources; 49fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 50fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert // The web search source to use. 51fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert private Source mWebSearchSource; 52fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 53516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood private final NamedTaskExecutor mIconLoaderExecutor; 54516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood 55fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert /** 56fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * 57fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert * @param context Used for looking up source information etc. 58fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert */ 59cd4accc7899fa7b756e1c430d6b196525abd5c3cMathew Inwood public SearchableSources(Context context, Handler uiThread, 60cd4accc7899fa7b756e1c430d6b196525abd5c3cMathew Inwood NamedTaskExecutor iconLoader, Config config) { 61fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mContext = context; 62fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert mSearchManager = (SearchManager) context.getSystemService(Context.SEARCH_SERVICE); 63e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood mUiThread = uiThread; 64516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood mIconLoaderExecutor = iconLoader; 65cd4accc7899fa7b756e1c430d6b196525abd5c3cMathew Inwood mConfig = config; 66fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 67fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 6849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert protected Context getContext() { 6949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return mContext; 7049fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 7149fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 72e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood protected Handler getUiThreadHandler() { 73e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood return mUiThread; 74e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood } 75e29d52aa72c96c3147fa91d83aeb8dafc6d1f578Mathew Inwood 7649fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert protected SearchManager getSearchManager() { 7749fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert return mSearchManager; 7849fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert } 7949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert 80516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood protected NamedTaskExecutor getIconLoaderExecutor() { 81516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood return mIconLoaderExecutor; 82516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood } 83516781305d7427e79928c95c6ea2b7689a4bf6ceMathew Inwood 84cd4accc7899fa7b756e1c430d6b196525abd5c3cMathew Inwood protected Config getConfig() { 85cd4accc7899fa7b756e1c430d6b196525abd5c3cMathew Inwood return mConfig; 86cd4accc7899fa7b756e1c430d6b196525abd5c3cMathew Inwood } 87cd4accc7899fa7b756e1c430d6b196525abd5c3cMathew Inwood 88fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public Collection<Source> getSources() { 89fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return mSources.values(); 90fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 91fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 9262adab88055fd0ef6779242245cdc8c3ae5f999cBjorn Bringert public Source getSource(String name) { 93fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return mSources.get(name); 94fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 95fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 96fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert public Source getWebSearchSource() { 97fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return mWebSearchSource; 98fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 99fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 100fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert /** 10121bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert * Updates the list of suggestion sources. 102fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert */ 10321bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert public void update() { 10421bff9bbf4286907b01d3153bff2fbd6b5ec5df8Bjorn Bringert if (DBG) Log.d(TAG, "update()"); 10562adab88055fd0ef6779242245cdc8c3ae5f999cBjorn Bringert mSources = new HashMap<String,Source>(); 106b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert 107b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert addSearchableSources(); 108b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert 109f3f70e5ae88f06ff6dabdec9e7c71a19ca1e7108Bjorn Bringert addInternalSources(); 110f3f70e5ae88f06ff6dabdec9e7c71a19ca1e7108Bjorn Bringert 111b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert mWebSearchSource = createWebSearchSource(); 112848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani if (mWebSearchSource != null) { 113848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani addSource(mWebSearchSource); 114848fa7a19abedc372452073abaf52780c7b6d78dAmith Yamasani } 115b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert } 116b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert 117f3f70e5ae88f06ff6dabdec9e7c71a19ca1e7108Bjorn Bringert protected void addInternalSources() { 118f3f70e5ae88f06ff6dabdec9e7c71a19ca1e7108Bjorn Bringert } 119f3f70e5ae88f06ff6dabdec9e7c71a19ca1e7108Bjorn Bringert 120b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert private void addSearchableSources() { 121b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert List<SearchableInfo> searchables = mSearchManager.getSearchablesInGlobalSearch(); 122b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert if (searchables == null) { 123b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert Log.e(TAG, "getSearchablesInGlobalSearch() returned null"); 124b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert return; 125b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert } 126b46040af250f9d5cf65ea4e39595c7b88531241aBjorn Bringert for (SearchableInfo searchable : searchables) { 127cc10dcf07c4e787abd66f4e2cfed31a09580a3b0Bjorn Bringert SearchableSource source = createSearchableSource(searchable); 12881a0897ff9685f3313c58294bf7973700c468b2bBjorn Bringert if (source != null) { 129fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (DBG) Log.d(TAG, "Created source " + source); 130fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert addSource(source); 131fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 132fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 133fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 134fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 135f3f70e5ae88f06ff6dabdec9e7c71a19ca1e7108Bjorn Bringert protected void addSource(Source source) { 13662adab88055fd0ef6779242245cdc8c3ae5f999cBjorn Bringert mSources.put(source.getName(), source); 137fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 138fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 13949fd8e0994577badc6194c2c3b5f771f2b793fe4Bjorn Bringert protected Source createWebSearchSource() { 14093bd2e70b8b08da1ec37fd0e990dac05551d2e90Bjorn Bringert return QsbApplication.get(getContext()).getGoogleSource(); 141fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 142fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert 14325cbd7d054b92df1fe857d155ccc12f8191c12cfMathew Inwood protected SearchableSource createSearchableSource(SearchableInfo searchable) { 144fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert if (searchable == null) return null; 145fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert try { 14677909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert return new SearchableSource(mContext, searchable, getUiThreadHandler(), 14777909685887bd6db7454b73cf274afc3aca2f58dBjorn Bringert getIconLoaderExecutor()); 148fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } catch (NameNotFoundException ex) { 149fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert Log.e(TAG, "Source not found: " + ex); 150fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert return null; 151fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 152fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert } 1531e53e72fbfc32995a97bbd25ae44bfea7b8781deMathew Inwood 1541e53e72fbfc32995a97bbd25ae44bfea7b8781deMathew Inwood public Source createSourceFor(ComponentName component) { 1551e53e72fbfc32995a97bbd25ae44bfea7b8781deMathew Inwood SearchableInfo info = mSearchManager.getSearchableInfo(component); 1561e53e72fbfc32995a97bbd25ae44bfea7b8781deMathew Inwood SearchableSource source = createSearchableSource(info); 1572fd5aa82682f077660faa8ec60c04238026a8731Mathew Inwood if (DBG) Log.d(TAG, "SearchableSource for " + component + ": " + source); 1581e53e72fbfc32995a97bbd25ae44bfea7b8781deMathew Inwood return source; 1591e53e72fbfc32995a97bbd25ae44bfea7b8781deMathew Inwood } 160fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert} 161