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