From 031a043554bc7d66a886cb98e4bc2fb2e81c5561 Mon Sep 17 00:00:00 2001 From: Raff Tsai Date: Fri, 27 Sep 2019 13:26:02 +0800 Subject: [PATCH] Extend SearchIndexableResources to use SearchIndexableData - We used Class as the input value, then use reflection to get SearchIndexProvider from class, that is not work for proguarded apps. Change the interface which takes SearchIndexableBundle as input which contains Class and SearchIndexProvider, we can check SearchIndexProvider is existed in compile time. And without the reflection code in Settings, we get some performance improvement. Bug: 135053028 Test: robolectric Change-Id: I27a898c36a388d2b532d6452b63abb09f493ef24 --- .../search/IndexableProcessor.java | 27 +++++++---- .../search/SearchIndexableData.java | 48 +++++++++++++++++++ .../search/SearchIndexableResources.java | 11 ++--- 3 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexableData.java diff --git a/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java b/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java index 5dc9061a81a0b..de45ea536e272 100644 --- a/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java +++ b/packages/SettingsLib/search/processor-src/com/android/settingslib/search/IndexableProcessor.java @@ -21,7 +21,6 @@ import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; import java.io.IOException; @@ -73,10 +72,12 @@ public class IndexableProcessor extends AbstractProcessor { } mRanOnce = true; + final ClassName searchIndexableData = ClassName.get(PACKAGE, "SearchIndexableData"); + final FieldSpec providers = FieldSpec.builder( ParameterizedTypeName.get( ClassName.get(Set.class), - TypeName.get(Class.class)), + searchIndexableData), "mProviders", Modifier.PRIVATE, Modifier.FINAL) .initializer("new $T()", HashSet.class) @@ -84,7 +85,7 @@ public class IndexableProcessor extends AbstractProcessor { final MethodSpec addIndex = MethodSpec.methodBuilder("addIndex") .addModifiers(Modifier.PUBLIC) - .addParameter(ClassName.get(Class.class), "indexClass") + .addParameter(searchIndexableData, "indexClass") .addCode("$N.add(indexClass);\n", providers) .build(); @@ -113,19 +114,25 @@ public class IndexableProcessor extends AbstractProcessor { SearchIndexable searchIndexable = element.getAnnotation(SearchIndexable.class); int forTarget = searchIndexable.forTarget(); + MethodSpec.Builder builder = baseConstructorBuilder; + if (forTarget == SearchIndexable.ALL) { - baseConstructorBuilder.addCode("$N($L.class);\n", addIndex, className); + builder = baseConstructorBuilder; } else if ((forTarget & SearchIndexable.MOBILE) != 0) { - mobileConstructorBuilder.addCode("$N($L.class);\n", addIndex, className); + builder = mobileConstructorBuilder; } else if ((forTarget & SearchIndexable.TV) != 0) { - tvConstructorBuilder.addCode("$N($L.class);\n", addIndex, className); + builder = tvConstructorBuilder; } else if ((forTarget & SearchIndexable.WEAR) != 0) { - wearConstructorBuilder.addCode("$N($L.class);\n", addIndex, className); + builder = wearConstructorBuilder; } else if ((forTarget & SearchIndexable.AUTO) != 0) { - autoConstructorBuilder.addCode("$N($L.class);\n", addIndex, className); + builder = autoConstructorBuilder; } else if ((forTarget & SearchIndexable.ARC) != 0) { - arcConstructorBuilder.addCode("$N($L.class);\n", addIndex, className); + builder = arcConstructorBuilder; } + builder.addCode( + "$N(new SearchIndexableData($L.class, $L" + + ".SEARCH_INDEX_DATA_PROVIDER));\n", + addIndex, className, className); } else { throw new IllegalStateException("Null classname from " + element); } @@ -137,7 +144,7 @@ public class IndexableProcessor extends AbstractProcessor { .addModifiers(Modifier.PUBLIC) .returns(ParameterizedTypeName.get( ClassName.get(Collection.class), - TypeName.get(Class.class))) + searchIndexableData)) .addCode("return $N;\n", providers) .build(); diff --git a/packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexableData.java b/packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexableData.java new file mode 100644 index 0000000000000..8b8f2688b93f7 --- /dev/null +++ b/packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexableData.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2019 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.settingslib.search; + +/** + * A Bundle class used in {@link SearchIndexableResources} to provide search Index data. + */ +public class SearchIndexableData { + private final Class mTargetClass; + private final Indexable.SearchIndexProvider mSearchIndexProvider; + + /** + * Constructs a SearchIndexableData + * + * @param targetClass The target opening class of the {@link Indexable.SearchIndexProvider}. It + * should be a {@link android.app.Activity} or fragment {@link + * androidx.fragment.app.Fragment}. + * But fragment is only supported in Android Settings. Other apps should use + * {@link android.app.Activity} + * @param provider provides searchable data for Android Settings + */ + public SearchIndexableData(Class targetClass, Indexable.SearchIndexProvider provider) { + mTargetClass = targetClass; + mSearchIndexProvider = provider; + } + + public Class getTargetClass() { + return mTargetClass; + } + + public Indexable.SearchIndexProvider getSearchIndexProvider() { + return mSearchIndexProvider; + } +} diff --git a/packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexableResources.java b/packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexableResources.java index 976647b3e88f0..e00ca718ce1c9 100644 --- a/packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexableResources.java +++ b/packages/SettingsLib/search/src/com/android/settingslib/search/SearchIndexableResources.java @@ -21,15 +21,12 @@ import java.util.Collection; public interface SearchIndexableResources { /** - * Returns a collection of classes that should be indexed for search. - * - * Each class should have the SEARCH_INDEX_DATA_PROVIDER public static member. + * Returns a Collection of {@link SearchIndexableData} that should be indexed for search. */ - Collection getProviderValues(); + Collection getProviderValues(); /** - * For testing. Can't use @VisibleForTesting here because this builds as a host binary as well - * as a device binary. + * Add {@link SearchIndexableData} for search in Android Settings. */ - void addIndex(Class indexClass); + void addIndex(SearchIndexableData indexBundle); } \ No newline at end of file