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; 2064442c11555d828a41af0b8a58ab933357889061Amith Yamasaniimport com.android.internal.util.IndentingPrintWriter; 21ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert 22c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasaniimport android.app.ActivityManager; 23c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasaniimport android.app.ActivityManagerNative; 24c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasaniimport android.app.AppGlobals; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ISearchManager; 268d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringertimport android.app.SearchManager; 272126aac7f992b57fc52141a8bd09fa7a45ac2509Bjorn Bringertimport android.app.SearchableInfo; 282c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringertimport android.content.BroadcastReceiver; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName; 30ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamathimport android.content.ContentResolver; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 332c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringertimport android.content.IntentFilter; 34c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasaniimport android.content.pm.IPackageManager; 35c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasaniimport android.content.pm.PackageManager; 36ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamathimport android.content.pm.ResolveInfo; 37ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamathimport android.database.ContentObserver; 385bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasaniimport android.os.Binder; 392c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringertimport android.os.Process; 40c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasaniimport android.os.RemoteException; 41f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackbornimport android.os.UserHandle; 42258848d2ae04f447ff1c18023fa76b139fcc0862Amith Yamasaniimport android.os.UserManager; 43ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamathimport android.provider.Settings; 448d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringertimport android.util.Log; 45c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasaniimport android.util.Slog; 465bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasaniimport android.util.SparseArray; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4864442c11555d828a41af0b8a58ab933357889061Amith Yamasaniimport java.io.FileDescriptor; 4964442c11555d828a41af0b8a58ab933357889061Amith Yamasaniimport java.io.PrintWriter; 506d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringertimport java.util.List; 516d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 53444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert * The search manager service handles the search UI, and maintains a registry of searchable 54444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert * activities. 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 56444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringertpublic class SearchManagerService extends ISearchManager.Stub { 57444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert 58444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // general debugging support 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "SearchManagerService"; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 61444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // Context that the service is running in. 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 63f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath 64ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert // This field is initialized lazily in getSearchables(), and then never modified. 6564442c11555d828a41af0b8a58ab933357889061Amith Yamasani private final SparseArray<Searchables> mSearchables = new SparseArray<Searchables>(); 66ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 68875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * Initializes the Search Manager service in the provided system context. 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Only one instance of this object should be created! 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context to use for accessing DB, window manager, etc. 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 73f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath public SearchManagerService(Context context) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 752c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert mContext.registerReceiver(new BootCompletedReceiver(), 762c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); 77e6687942308b64e32d292ae1e5d38beeb86c951fAmith Yamasani mContext.registerReceiver(new UserReceiver(), 7864442c11555d828a41af0b8a58ab933357889061Amith Yamasani new IntentFilter(Intent.ACTION_USER_REMOVED)); 7964442c11555d828a41af0b8a58ab933357889061Amith Yamasani new MyPackageMonitor().register(context, null, UserHandle.ALL, true); 80444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert } 81444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert 8264442c11555d828a41af0b8a58ab933357889061Amith Yamasani private Searchables getSearchables(int userId) { 8364442c11555d828a41af0b8a58ab933357889061Amith Yamasani long origId = Binder.clearCallingIdentity(); 8464442c11555d828a41af0b8a58ab933357889061Amith Yamasani try { 8564442c11555d828a41af0b8a58ab933357889061Amith Yamasani boolean userExists = ((UserManager) mContext.getSystemService(Context.USER_SERVICE)) 8664442c11555d828a41af0b8a58ab933357889061Amith Yamasani .getUserInfo(userId) != null; 8764442c11555d828a41af0b8a58ab933357889061Amith Yamasani if (!userExists) return null; 8864442c11555d828a41af0b8a58ab933357889061Amith Yamasani } finally { 8964442c11555d828a41af0b8a58ab933357889061Amith Yamasani Binder.restoreCallingIdentity(origId); 90ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert } 9164442c11555d828a41af0b8a58ab933357889061Amith Yamasani synchronized (mSearchables) { 9264442c11555d828a41af0b8a58ab933357889061Amith Yamasani Searchables searchables = mSearchables.get(userId); 935bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani 9464442c11555d828a41af0b8a58ab933357889061Amith Yamasani if (searchables == null) { 9540e9f2922cae76ffcbc521481e5be8e80e8744efDianne Hackborn //Log.i(TAG, "Building list of searchable activities for userId=" + userId); 9664442c11555d828a41af0b8a58ab933357889061Amith Yamasani searchables = new Searchables(mContext, userId); 9764442c11555d828a41af0b8a58ab933357889061Amith Yamasani searchables.buildSearchableList(); 9864442c11555d828a41af0b8a58ab933357889061Amith Yamasani mSearchables.append(userId, searchables); 9964442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 10064442c11555d828a41af0b8a58ab933357889061Amith Yamasani return searchables; 10164442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 10264442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 1035bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani 10464442c11555d828a41af0b8a58ab933357889061Amith Yamasani private void onUserRemoved(int userId) { 10564442c11555d828a41af0b8a58ab933357889061Amith Yamasani if (userId != UserHandle.USER_OWNER) { 10664442c11555d828a41af0b8a58ab933357889061Amith Yamasani synchronized (mSearchables) { 10764442c11555d828a41af0b8a58ab933357889061Amith Yamasani mSearchables.remove(userId); 10864442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 1095bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani } 1109bc75cb9c23e5df528a28acc1fbbb4b5be51c33dBjorn Bringert } 1113ed6a3342b89651e8359956cefcc0076b6a4a30aKarl Rosaen 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1132c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert * Creates the initial searchables list after boot. 1142c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert */ 1152c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert private final class BootCompletedReceiver extends BroadcastReceiver { 1162c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert @Override 1172c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert public void onReceive(Context context, Intent intent) { 1182c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert new Thread() { 1192c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert @Override 1202c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert public void run() { 1212c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1222c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert mContext.unregisterReceiver(BootCompletedReceiver.this); 1235bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani getSearchables(0); 1242c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert } 1252c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert }.start(); 1262c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert } 1272c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert } 1282c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert 12964442c11555d828a41af0b8a58ab933357889061Amith Yamasani private final class UserReceiver extends BroadcastReceiver { 13064442c11555d828a41af0b8a58ab933357889061Amith Yamasani @Override 13164442c11555d828a41af0b8a58ab933357889061Amith Yamasani public void onReceive(Context context, Intent intent) { 13264442c11555d828a41af0b8a58ab933357889061Amith Yamasani onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_OWNER)); 13364442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 13464442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 13564442c11555d828a41af0b8a58ab933357889061Amith Yamasani 1362c7b197a4ab1aff671a6fa2e6db540d391f553e6Bjorn Bringert /** 137444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert * Refreshes the "searchables" list when packages are added/removed. 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 139ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert class MyPackageMonitor extends PackageMonitor { 14013bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 142ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert public void onSomePackagesChanged() { 14313bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani updateSearchables(); 14413bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani } 14513bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani 14613bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani @Override 14713bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani public void onPackageModified(String pkg) { 14813bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani updateSearchables(); 14913bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani } 15013bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani 15113bc602b2118af550c7ed99c4582fb7db7622002Amith Yamasani private void updateSearchables() { 15264442c11555d828a41af0b8a58ab933357889061Amith Yamasani final int changingUserId = getChangingUserId(); 15364442c11555d828a41af0b8a58ab933357889061Amith Yamasani synchronized (mSearchables) { 1545bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani // Update list of searchable activities 1555bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani for (int i = 0; i < mSearchables.size(); i++) { 15664442c11555d828a41af0b8a58ab933357889061Amith Yamasani if (changingUserId == mSearchables.keyAt(i)) { 15764442c11555d828a41af0b8a58ab933357889061Amith Yamasani getSearchables(mSearchables.keyAt(i)).buildSearchableList(); 15864442c11555d828a41af0b8a58ab933357889061Amith Yamasani break; 15964442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 1605bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani } 1615bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani } 162ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert // Inform all listeners that the list of searchables has been updated. 163ab5d96c5daf4bcc9b7a0cde44357454a11a8e48aBjorn Bringert Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); 164e6687942308b64e32d292ae1e5d38beeb86c951fAmith Yamasani intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING 165e6687942308b64e32d292ae1e5d38beeb86c951fAmith Yamasani | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); 16664442c11555d828a41af0b8a58ab933357889061Amith Yamasani mContext.sendBroadcastAsUser(intent, new UserHandle(changingUserId)); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 170ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath class GlobalSearchProviderObserver extends ContentObserver { 171ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath private final ContentResolver mResolver; 172ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath 173ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath public GlobalSearchProviderObserver(ContentResolver resolver) { 174ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath super(null); 175ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath mResolver = resolver; 176ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath mResolver.registerContentObserver( 177ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath Settings.Secure.getUriFor(Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY), 178ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath false /* notifyDescendants */, 179ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath this); 180ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath } 181ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath 182ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath @Override 183ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath public void onChange(boolean selfChange) { 18464442c11555d828a41af0b8a58ab933357889061Amith Yamasani synchronized (mSearchables) { 1855bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani for (int i = 0; i < mSearchables.size(); i++) { 1865bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani getSearchables(mSearchables.keyAt(i)).buildSearchableList(); 1875bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani } 1885bb87cd9b81506b0c25d3f9184e406762a9e9d9cAmith Yamasani } 189ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath Intent intent = new Intent(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); 190ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 1915ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 192ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath } 193ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath 194ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath } 195ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath 196444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // 197444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // Searchable activities API 198444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert // 199a48a5af931f2fb43c948416180b85dfe9ecdc9a1Bjorn Bringert 200a48a5af931f2fb43c948416180b85dfe9ecdc9a1Bjorn Bringert /** 201444c727e0eecf83e9d0b9c4e7af5cbf5fc4135f8Bjorn Bringert * Returns the SearchableInfo for a given activity. 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param launchActivity The activity from which we're launching this search. 204875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * @return Returns a SearchableInfo record describing the parameters of the search, 205875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen * or null if no searchable metadata was available. 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2076cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert public SearchableInfo getSearchableInfo(final ComponentName launchActivity) { 2086cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert if (launchActivity == null) { 2096cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert Log.e(TAG, "getSearchableInfo(), activity == null"); 2106cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert return null; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 212f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getSearchables(UserHandle.getCallingUserId()).getSearchableInfo(launchActivity); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 214f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath 2156d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert /** 2166d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert * Returns a list of the searchable activities that can be included in global search. 2176d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert */ 2186d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert public List<SearchableInfo> getSearchablesInGlobalSearch() { 219f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getSearchables(UserHandle.getCallingUserId()).getSearchablesInGlobalSearchList(); 2206d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert } 221875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen 222ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath public List<ResolveInfo> getGlobalSearchActivities() { 223f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getSearchables(UserHandle.getCallingUserId()).getGlobalSearchActivities(); 224ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath } 225ee69ff4eaee9342843d5f25338288865dda2d36aNarayan Kamath 226f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath /** 2276cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert * Gets the name of the global search activity. 228f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath */ 2296cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert public ComponentName getGlobalSearchActivity() { 230f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getSearchables(UserHandle.getCallingUserId()).getGlobalSearchActivity(); 231f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath } 232f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath 233f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath /** 2346cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert * Gets the name of the web search activity. 235f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath */ 2366cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert public ComponentName getWebSearchActivity() { 237f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn return getSearchables(UserHandle.getCallingUserId()).getWebSearchActivity(); 238f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath } 239f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath 240c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani @Override 241c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani public ComponentName getAssistIntent(int userHandle) { 242c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani try { 243f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn if (userHandle != UserHandle.getCallingUserId()) { 244c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani // Requesting a different user, make sure that they have the permission 245c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani if (ActivityManager.checkComponentPermission( 246c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 247c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani Binder.getCallingUid(), -1, true) 248c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani == PackageManager.PERMISSION_GRANTED) { 249c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani // Translate to the current user id, if caller wasn't aware 250f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn if (userHandle == UserHandle.USER_CURRENT) { 251c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani long identity = Binder.clearCallingIdentity(); 252c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani userHandle = ActivityManagerNative.getDefault().getCurrentUser().id; 253c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani Binder.restoreCallingIdentity(identity); 254c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani } 255c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani } else { 256c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani String msg = "Permission Denial: " 257c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani + "Request to getAssistIntent for " + userHandle 258f02b60aa4f367516f40cf3d60fffae0c6fe3e1b8Dianne Hackborn + " but is calling from user " + UserHandle.getCallingUserId() 259c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani + "; this requires " 260c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 261c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani Slog.w(TAG, msg); 262c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani return null; 263c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani } 264c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani } 265c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani IPackageManager pm = AppGlobals.getPackageManager(); 266c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani Intent assistIntent = new Intent(Intent.ACTION_ASSIST); 267c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani ResolveInfo info = 268c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani pm.resolveIntent(assistIntent, 269c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani assistIntent.resolveTypeIfNeeded(mContext.getContentResolver()), 270c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani PackageManager.MATCH_DEFAULT_ONLY, userHandle); 271c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani if (info != null) { 272c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani return new ComponentName( 273c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani info.activityInfo.applicationInfo.packageName, 274c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani info.activityInfo.name); 275c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani } 276c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani } catch (RemoteException re) { 277c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani // Local call 278c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani Log.e(TAG, "RemoteException in getAssistIntent: " + re); 279c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani } catch (Exception e) { 280c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani Log.e(TAG, "Exception in getAssistIntent: " + e); 281c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani } 282c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani return null; 283c1d07a4bd26c0ecf87bfa151ae43cb92c0c73791Amith Yamasani } 28464442c11555d828a41af0b8a58ab933357889061Amith Yamasani 28564442c11555d828a41af0b8a58ab933357889061Amith Yamasani @Override 28664442c11555d828a41af0b8a58ab933357889061Amith Yamasani public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 28752801aae89196b7ad16ef21b07d2d621e7d0bb61Jeff Sharkey mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); 28852801aae89196b7ad16ef21b07d2d621e7d0bb61Jeff Sharkey 28964442c11555d828a41af0b8a58ab933357889061Amith Yamasani IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 29064442c11555d828a41af0b8a58ab933357889061Amith Yamasani synchronized (mSearchables) { 29164442c11555d828a41af0b8a58ab933357889061Amith Yamasani for (int i = 0; i < mSearchables.size(); i++) { 29264442c11555d828a41af0b8a58ab933357889061Amith Yamasani ipw.print("\nUser: "); ipw.println(mSearchables.keyAt(i)); 29364442c11555d828a41af0b8a58ab933357889061Amith Yamasani ipw.increaseIndent(); 29464442c11555d828a41af0b8a58ab933357889061Amith Yamasani mSearchables.valueAt(i).dump(fd, ipw, args); 29564442c11555d828a41af0b8a58ab933357889061Amith Yamasani ipw.decreaseIndent(); 29664442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 29764442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 29864442c11555d828a41af0b8a58ab933357889061Amith Yamasani } 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 300