19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.server.search; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringertimport com.android.internal.content.PackageMonitor; 20ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ISearchManager; 228d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringertimport android.app.SearchManager; 232126aac7f992b57fc52141a8bd09fa7a45ac2509Bjorn Bringertimport android.app.SearchableInfo; 242c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringertimport android.content.BroadcastReceiver; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 282c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringertimport android.content.IntentFilter; 292c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringertimport android.os.Process; 308d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringertimport android.util.Log; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 326d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringertimport java.util.List; 336d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 35444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert * The search manager service handles the search UI, and maintains a registry of searchable 36444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert * activities. 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 38444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringertpublic class SearchManagerService extends ISearchManager.Stub { 39444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert 40444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // general debugging support 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "SearchManagerService"; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // Context that the service is running in. 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 45f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath 46ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert // This field is initialized lazily in getSearchables(), and then never modified. 479bc75cb9c23e5df528a28acc1fbbb4b5be51c33dBjorn Bringert private Searchables mSearchables; 483ed6a3342b89651e8359956cefcc0076b6a4a30aKarl Rosaen 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 50875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * Initializes the Search Manager service in the provided system context. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Only one instance of this object should be created! 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context to use for accessing DB, window manager, etc. 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 55f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath public SearchManagerService(Context context) { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 572c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert mContext.registerReceiver(new BootCompletedReceiver(), 582c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); 59444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert } 60444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert 619bc75cb9c23e5df528a28acc1fbbb4b5be51c33dBjorn Bringert private synchronized Searchables getSearchables() { 62ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert if (mSearchables == null) { 632c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert Log.i(TAG, "Building list of searchable activities"); 642c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert new MyPackageMonitor().register(mContext, true); 65ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert mSearchables = new Searchables(mContext); 66ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert mSearchables.buildSearchableList(); 67ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert } 689bc75cb9c23e5df528a28acc1fbbb4b5be51c33dBjorn Bringert return mSearchables; 699bc75cb9c23e5df528a28acc1fbbb4b5be51c33dBjorn Bringert } 703ed6a3342b89651e8359956cefcc0076b6a4a30aKarl Rosaen 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 722c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert * Creates the initial searchables list after boot. 732c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert */ 742c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert private final class BootCompletedReceiver extends BroadcastReceiver { 752c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert @Override 762c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert public void onReceive(Context context, Intent intent) { 772c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert new Thread() { 782c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert @Override 792c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert public void run() { 802c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 812c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert mContext.unregisterReceiver(BootCompletedReceiver.this); 822c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert getSearchables(); 832c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert } 842c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert }.start(); 852c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert } 862c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert } 872c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert 882c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert /** 89444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert * Refreshes the "searchables" list when packages are added/removed. 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 91ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert class MyPackageMonitor extends PackageMonitor { 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 93ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert public void onSomePackagesChanged() { 94ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert // Update list of searchable activities 95ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert getSearchables().buildSearchableList(); 96ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert // Inform all listeners that the list of searchables has been updated. 97ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); 98ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 99ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert mContext.sendBroadcast(intent); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 103444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // 104444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // Searchable activities API 105444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // 106a48a5af931f2fb43c948416180b85dfe9ecdc9a1Bjorn Bringert 107a48a5af931f2fb43c948416180b85dfe9ecdc9a1Bjorn Bringert /** 108444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert * Returns the SearchableInfo for a given activity. 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param launchActivity The activity from which we're launching this search. 111875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @return Returns a SearchableInfo record describing the parameters of the search, 112875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * or null if no searchable metadata was available. 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1146cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert public SearchableInfo getSearchableInfo(final ComponentName launchActivity) { 1156cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert if (launchActivity == null) { 1166cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert Log.e(TAG, "getSearchableInfo(), activity == null"); 1176cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert return null; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1196cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert return getSearchables().getSearchableInfo(launchActivity); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 121f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath 1226d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert /** 1236d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert * Returns a list of the searchable activities that can be included in global search. 1246d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert */ 1256d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert public List<SearchableInfo> getSearchablesInGlobalSearch() { 1269bc75cb9c23e5df528a28acc1fbbb4b5be51c33dBjorn Bringert return getSearchables().getSearchablesInGlobalSearchList(); 1276d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert } 128875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 129f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath /** 1306cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert * Gets the name of the global search activity. 131f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath */ 1326cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert public ComponentName getGlobalSearchActivity() { 1336cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert return getSearchables().getGlobalSearchActivity(); 134f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath } 135f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath 136f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath /** 1376cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert * Gets the name of the web search activity. 138f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath */ 1396cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert public ComponentName getWebSearchActivity() { 1406cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert return getSearchables().getWebSearchActivity(); 141f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath } 142f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 144