Loading src/com/android/settings/SettingsActivity.java +2 −2 Original line number Diff line number Diff line Loading @@ -253,7 +253,7 @@ public class SettingsActivity extends SettingsDrawerActivity String action = intent.getAction(); if (action.equals(Intent.ACTION_USER_ADDED) || action.equals(Intent.ACTION_USER_REMOVED)) { Index.getInstance(getApplicationContext()).update(); mSearchFeatureProvider.updateIndex(getApplicationContext()); } } }; Loading Loading @@ -310,7 +310,7 @@ public class SettingsActivity extends SettingsDrawerActivity @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Index.getInstance(this).update(); mSearchFeatureProvider.updateIndex(getApplicationContext()); } @Override Loading src/com/android/settings/search2/DatabaseIndexingManager.java 0 → 100644 +963 −0 File added.Preview size limit exceeded, changes collapsed. Show changes src/com/android/settings/search2/DatabaseIndexingUtils.java 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.android.settings.search2; import android.Manifest; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.text.TextUtils; import android.util.Log; import com.android.settings.search.Indexable; import java.lang.reflect.Field; /** * Utility class for {@like DatabaseIndexingManager} to handle the mapping between Payloads * and Preference controllers, and managing indexable classes. */ public class DatabaseIndexingUtils { private static final String LOG_TAG = "IndexingUtil"; private static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER = "SEARCH_INDEX_DATA_PROVIDER"; public static Class<?> getIndexableClass(String className) { final Class<?> clazz; try { clazz = Class.forName(className); } catch (ClassNotFoundException e) { Log.d(LOG_TAG, "Cannot find class: " + className); return null; } return isIndexableClass(clazz) ? clazz : null; } public static boolean isIndexableClass(final Class<?> clazz) { return (clazz != null) && Indexable.class.isAssignableFrom(clazz); } public static Indexable.SearchIndexProvider getSearchIndexProvider(final Class<?> clazz) { try { final Field f = clazz.getField(FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER); return (Indexable.SearchIndexProvider) f.get(null); } catch (NoSuchFieldException e) { Log.d(LOG_TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); } catch (SecurityException se) { Log.d(LOG_TAG, "Security exception for field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); } catch (IllegalAccessException e) { Log.d(LOG_TAG, "Illegal access to field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); } catch (IllegalArgumentException e) { Log.d(LOG_TAG, "Illegal argument when accessing field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); } return null; } /** * Only allow a "well known" SearchIndexablesProvider. The provider should: * * - have read/write {@link Manifest.permission#READ_SEARCH_INDEXABLES} * - be from a privileged package */ public static boolean isWellKnownProvider(ResolveInfo info, Context context) { final String authority = info.providerInfo.authority; final String packageName = info.providerInfo.applicationInfo.packageName; if (TextUtils.isEmpty(authority) || TextUtils.isEmpty(packageName)) { return false; } final String readPermission = info.providerInfo.readPermission; final String writePermission = info.providerInfo.writePermission; if (TextUtils.isEmpty(readPermission) || TextUtils.isEmpty(writePermission)) { return false; } if (!android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(readPermission) || !android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(writePermission)) { return false; } return isPrivilegedPackage(packageName, context); } public static boolean isPrivilegedPackage(String packageName, Context context) { final PackageManager pm = context.getPackageManager(); try { PackageInfo packInfo = pm.getPackageInfo(packageName, 0); return ((packInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); } catch (PackageManager.NameNotFoundException e) { return false; } } } src/com/android/settings/search2/SearchFeatureProvider.java +10 −0 Original line number Diff line number Diff line Loading @@ -46,4 +46,14 @@ public interface SearchFeatureProvider { * Returns a new loader to search installed apps. */ InstalledAppResultLoader getInstalledAppSearchLoader(Context context, String query); /** * Returns the manager for indexing Settings data. */ DatabaseIndexingManager getIndexingManager(Context context); /** * Updates the Settings indexes */ void updateIndex(Context context); } src/com/android/settings/search2/SearchFeatureProviderImpl.java +21 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.view.Menu; import android.view.MenuItem; import com.android.settings.R; import com.android.settings.search.Index; import com.android.settings.applications.PackageManagerWrapperImpl; /** Loading @@ -31,6 +33,7 @@ import com.android.settings.applications.PackageManagerWrapperImpl; public class SearchFeatureProviderImpl implements SearchFeatureProvider { protected Context mContext; private DatabaseIndexingManager mDatabaseIndexingManager; public SearchFeatureProviderImpl(Context context) { mContext = context; Loading Loading @@ -71,4 +74,22 @@ public class SearchFeatureProviderImpl implements SearchFeatureProvider { return new InstalledAppResultLoader( context, new PackageManagerWrapperImpl(context.getPackageManager()), query); } @Override public DatabaseIndexingManager getIndexingManager(Context context) { if (mDatabaseIndexingManager == null) { mDatabaseIndexingManager = new DatabaseIndexingManager(context.getApplicationContext(), context.getPackageName()); } return mDatabaseIndexingManager; } @Override public void updateIndex(Context context) { if (isEnabled()) { getIndexingManager(context).update(); } else { Index.getInstance(context).update(); } } } Loading
src/com/android/settings/SettingsActivity.java +2 −2 Original line number Diff line number Diff line Loading @@ -253,7 +253,7 @@ public class SettingsActivity extends SettingsDrawerActivity String action = intent.getAction(); if (action.equals(Intent.ACTION_USER_ADDED) || action.equals(Intent.ACTION_USER_REMOVED)) { Index.getInstance(getApplicationContext()).update(); mSearchFeatureProvider.updateIndex(getApplicationContext()); } } }; Loading Loading @@ -310,7 +310,7 @@ public class SettingsActivity extends SettingsDrawerActivity @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Index.getInstance(this).update(); mSearchFeatureProvider.updateIndex(getApplicationContext()); } @Override Loading
src/com/android/settings/search2/DatabaseIndexingManager.java 0 → 100644 +963 −0 File added.Preview size limit exceeded, changes collapsed. Show changes
src/com/android/settings/search2/DatabaseIndexingUtils.java 0 → 100644 +118 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.android.settings.search2; import android.Manifest; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.text.TextUtils; import android.util.Log; import com.android.settings.search.Indexable; import java.lang.reflect.Field; /** * Utility class for {@like DatabaseIndexingManager} to handle the mapping between Payloads * and Preference controllers, and managing indexable classes. */ public class DatabaseIndexingUtils { private static final String LOG_TAG = "IndexingUtil"; private static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER = "SEARCH_INDEX_DATA_PROVIDER"; public static Class<?> getIndexableClass(String className) { final Class<?> clazz; try { clazz = Class.forName(className); } catch (ClassNotFoundException e) { Log.d(LOG_TAG, "Cannot find class: " + className); return null; } return isIndexableClass(clazz) ? clazz : null; } public static boolean isIndexableClass(final Class<?> clazz) { return (clazz != null) && Indexable.class.isAssignableFrom(clazz); } public static Indexable.SearchIndexProvider getSearchIndexProvider(final Class<?> clazz) { try { final Field f = clazz.getField(FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER); return (Indexable.SearchIndexProvider) f.get(null); } catch (NoSuchFieldException e) { Log.d(LOG_TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); } catch (SecurityException se) { Log.d(LOG_TAG, "Security exception for field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); } catch (IllegalAccessException e) { Log.d(LOG_TAG, "Illegal access to field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); } catch (IllegalArgumentException e) { Log.d(LOG_TAG, "Illegal argument when accessing field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'"); } return null; } /** * Only allow a "well known" SearchIndexablesProvider. The provider should: * * - have read/write {@link Manifest.permission#READ_SEARCH_INDEXABLES} * - be from a privileged package */ public static boolean isWellKnownProvider(ResolveInfo info, Context context) { final String authority = info.providerInfo.authority; final String packageName = info.providerInfo.applicationInfo.packageName; if (TextUtils.isEmpty(authority) || TextUtils.isEmpty(packageName)) { return false; } final String readPermission = info.providerInfo.readPermission; final String writePermission = info.providerInfo.writePermission; if (TextUtils.isEmpty(readPermission) || TextUtils.isEmpty(writePermission)) { return false; } if (!android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(readPermission) || !android.Manifest.permission.READ_SEARCH_INDEXABLES.equals(writePermission)) { return false; } return isPrivilegedPackage(packageName, context); } public static boolean isPrivilegedPackage(String packageName, Context context) { final PackageManager pm = context.getPackageManager(); try { PackageInfo packInfo = pm.getPackageInfo(packageName, 0); return ((packInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); } catch (PackageManager.NameNotFoundException e) { return false; } } }
src/com/android/settings/search2/SearchFeatureProvider.java +10 −0 Original line number Diff line number Diff line Loading @@ -46,4 +46,14 @@ public interface SearchFeatureProvider { * Returns a new loader to search installed apps. */ InstalledAppResultLoader getInstalledAppSearchLoader(Context context, String query); /** * Returns the manager for indexing Settings data. */ DatabaseIndexingManager getIndexingManager(Context context); /** * Updates the Settings indexes */ void updateIndex(Context context); }
src/com/android/settings/search2/SearchFeatureProviderImpl.java +21 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,8 @@ import android.view.Menu; import android.view.MenuItem; import com.android.settings.R; import com.android.settings.search.Index; import com.android.settings.applications.PackageManagerWrapperImpl; /** Loading @@ -31,6 +33,7 @@ import com.android.settings.applications.PackageManagerWrapperImpl; public class SearchFeatureProviderImpl implements SearchFeatureProvider { protected Context mContext; private DatabaseIndexingManager mDatabaseIndexingManager; public SearchFeatureProviderImpl(Context context) { mContext = context; Loading Loading @@ -71,4 +74,22 @@ public class SearchFeatureProviderImpl implements SearchFeatureProvider { return new InstalledAppResultLoader( context, new PackageManagerWrapperImpl(context.getPackageManager()), query); } @Override public DatabaseIndexingManager getIndexingManager(Context context) { if (mDatabaseIndexingManager == null) { mDatabaseIndexingManager = new DatabaseIndexingManager(context.getApplicationContext(), context.getPackageName()); } return mDatabaseIndexingManager; } @Override public void updateIndex(Context context) { if (isEnabled()) { getIndexingManager(context).update(); } else { Index.getInstance(context).update(); } } }