1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.settings.search; 18 19 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE; 20 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_CLASS_NAME; 21 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ENTRIES; 22 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ICON_RESID; 23 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_ACTION; 24 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_CLASS; 25 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE; 26 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEY; 27 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEYWORDS; 28 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SCREEN_TITLE; 29 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_OFF; 30 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_ON; 31 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_TITLE; 32 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_USER_ID; 33 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME; 34 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID; 35 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION; 36 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS; 37 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE; 38 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK; 39 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID; 40 import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS; 41 import static android.provider.SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS; 42 import static android.provider.SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS; 43 44 import android.database.Cursor; 45 import android.database.MatrixCursor; 46 import android.provider.SearchIndexablesProvider; 47 48 import com.android.car.settings.common.Logger; 49 import com.android.internal.annotations.VisibleForTesting; 50 import com.android.settingslib.search.SearchIndexableData; 51 import com.android.settingslib.search.SearchIndexableRaw; 52 import com.android.settingslib.search.SearchIndexableResources; 53 import com.android.settingslib.search.SearchIndexableResourcesAuto; 54 55 import java.util.Objects; 56 57 /** 58 * Automotive Settings Provider for Search. 59 */ 60 public class CarSettingsSearchIndexablesProvider extends SearchIndexablesProvider { 61 private static final Logger LOG = new Logger(CarSettingsSearchIndexablesProvider.class); 62 63 private SearchIndexableResources mSearchIndexableResources; 64 65 @Override queryXmlResources(String[] projection)66 public Cursor queryXmlResources(String[] projection) { 67 MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS); 68 69 getResources() 70 .getProviderValues() 71 .stream() 72 .map(SearchIndexableData::getSearchIndexProvider) 73 .map(i -> i.getXmlResourcesToIndex(getContext(), true)) 74 .filter(Objects::nonNull) 75 .forEach(list -> list.forEach(val -> { 76 Object[] ref = new Object[INDEXABLES_XML_RES_COLUMNS.length]; 77 ref[COLUMN_INDEX_XML_RES_RANK] = val.rank; 78 ref[COLUMN_INDEX_XML_RES_RESID] = val.xmlResId; 79 ref[COLUMN_INDEX_XML_RES_CLASS_NAME] = val.className; 80 ref[COLUMN_INDEX_XML_RES_ICON_RESID] = val.iconResId; 81 ref[COLUMN_INDEX_XML_RES_INTENT_ACTION] = val.intentAction; 82 ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE] = val.intentTargetPackage; 83 ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = val.intentTargetClass; 84 cursor.addRow(ref); 85 })); 86 87 return cursor; 88 } 89 90 @Override queryRawData(String[] projection)91 public Cursor queryRawData(String[] projection) { 92 MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS); 93 94 getResources() 95 .getProviderValues() 96 .stream() 97 .map(SearchIndexableData::getSearchIndexProvider) 98 .map(p -> p.getRawDataToIndex(getContext(), true)) 99 .filter(Objects::nonNull) 100 .forEach(list -> list.forEach( 101 raw -> { 102 cursor.addRow(createIndexableRawColumnObjects(raw)); 103 })); 104 105 return cursor; 106 } 107 createIndexableRawColumnObjects(SearchIndexableRaw raw)108 private static Object[] createIndexableRawColumnObjects(SearchIndexableRaw raw) { 109 Object[] ref = new Object[INDEXABLES_RAW_COLUMNS.length]; 110 ref[COLUMN_INDEX_RAW_TITLE] = raw.title; 111 ref[COLUMN_INDEX_RAW_SUMMARY_ON] = raw.summaryOn; 112 ref[COLUMN_INDEX_RAW_SUMMARY_OFF] = raw.summaryOff; 113 ref[COLUMN_INDEX_RAW_ENTRIES] = raw.entries; 114 ref[COLUMN_INDEX_RAW_KEYWORDS] = raw.keywords; 115 ref[COLUMN_INDEX_RAW_SCREEN_TITLE] = raw.screenTitle; 116 ref[COLUMN_INDEX_RAW_CLASS_NAME] = raw.className; 117 ref[COLUMN_INDEX_RAW_ICON_RESID] = raw.iconResId; 118 ref[COLUMN_INDEX_RAW_INTENT_ACTION] = raw.intentAction; 119 ref[COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE] = raw.intentTargetPackage; 120 ref[COLUMN_INDEX_RAW_INTENT_TARGET_CLASS] = raw.intentTargetClass; 121 ref[COLUMN_INDEX_RAW_KEY] = raw.key; 122 ref[COLUMN_INDEX_RAW_USER_ID] = raw.userId; 123 return ref; 124 } 125 126 @Override queryNonIndexableKeys(String[] projection)127 public Cursor queryNonIndexableKeys(String[] projection) { 128 MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS); 129 130 getResources().getProviderValues() 131 .stream() 132 .map(SearchIndexableData::getSearchIndexProvider) 133 .map(provider -> { 134 try { 135 return provider.getNonIndexableKeys(getContext()); 136 } catch (Exception e) { 137 LOG.w("Could not get keys for provider " + provider.toString()); 138 return null; 139 } 140 }) 141 .filter(Objects::nonNull) 142 .forEach(keys -> 143 keys.forEach(key -> { 144 Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length]; 145 ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = key; 146 cursor.addRow(ref); 147 })); 148 149 return cursor; 150 } 151 152 @Override onCreate()153 public boolean onCreate() { 154 return true; 155 } 156 getResources()157 private SearchIndexableResources getResources() { 158 if (mSearchIndexableResources == null) { 159 mSearchIndexableResources = new SearchIndexableResourcesAuto(); 160 } 161 return mSearchIndexableResources; 162 } 163 164 @VisibleForTesting setResources(SearchIndexableResources resources)165 void setResources(SearchIndexableResources resources) { 166 mSearchIndexableResources = resources; 167 } 168 } 169