1 /* 2 * Copyright (C) 2017 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.settings.intelligence.search.indexing; 18 19 import static android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY; 20 import static android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI; 21 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.net.Uri; 26 import android.text.TextUtils; 27 28 /** 29 * Utility class for {@like DatabaseIndexingManager} to handle the mapping between Payloads 30 * and Preference controllers, and managing indexable classes. 31 */ 32 public class DatabaseIndexingUtils { 33 34 private static final String TAG = "DatabaseIndexingUtils"; 35 36 // frameworks/base/proto/src/metrics_constants.proto#DASHBOARD_SEARCH_RESULTS 37 // Have to hardcode value here because we can't depend on internal framework constants. 38 public static final int DASHBOARD_SEARCH_RESULTS = 34; 39 40 /** 41 * Below are internal contract between Settings/SettingsIntelligence to launch a search result 42 * page. 43 */ 44 public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment"; 45 public static final String EXTRA_SOURCE_METRICS_CATEGORY = ":settings:source_metrics"; 46 public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key"; 47 public static final String EXTRA_SHOW_FRAGMENT_TITLE = ":settings:show_fragment_title"; 48 public static final String SEARCH_RESULT_TRAMPOLINE_ACTION = 49 "com.android.settings.SEARCH_RESULT_TRAMPOLINE"; 50 51 // Additional extra of Settings#ACTION_SETTINGS_LARGE_SCREEN_DEEP_LINK. 52 // Set & get Uri of the Intent separately to prevent failure of Intent#ParseUri. 53 private static final String EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA = 54 "settings_large_screen_deep_link_intent_data"; 55 56 /** 57 * Builds intent that launches the search destination as a sub-setting. 58 */ buildSearchTrampolineIntent(String className, String key, String screenTitle, String highlightMenuKey)59 public static Intent buildSearchTrampolineIntent(String className, String key, 60 String screenTitle, String highlightMenuKey) { 61 final Intent intent = new Intent(SEARCH_RESULT_TRAMPOLINE_ACTION); 62 intent.putExtra(EXTRA_SHOW_FRAGMENT, className) 63 .putExtra(EXTRA_SHOW_FRAGMENT_TITLE, screenTitle) 64 .putExtra(EXTRA_SOURCE_METRICS_CATEGORY, DASHBOARD_SEARCH_RESULTS) 65 .putExtra(EXTRA_FRAGMENT_ARG_KEY, key) 66 .putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey); 67 return intent; 68 } 69 70 /** 71 * Builds intent that launches the search destination as a deep link. 72 */ buildSearchTrampolineIntent(String action, String targetPackage, String targetClass, String key, String highlightMenuKey)73 public static Intent buildSearchTrampolineIntent(String action, String targetPackage, 74 String targetClass, String key, String highlightMenuKey) { 75 final Intent intent = new Intent(SEARCH_RESULT_TRAMPOLINE_ACTION); 76 intent.putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI, 77 buildDirectSearchResultIntent(action, targetPackage, targetClass, key) 78 .toUri(Intent.URI_INTENT_SCHEME)) 79 .putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey); 80 return intent; 81 } 82 83 /** 84 * Builds intent that launches the search destination as a deep link. 85 */ buildSearchTrampolineIntent(Intent targetIntent, String highlightMenuKey)86 public static Intent buildSearchTrampolineIntent(Intent targetIntent, String highlightMenuKey) { 87 // Relay target intent data to prevent future failure of Intent#ParseUri. 88 final Uri data = targetIntent.getData(); 89 targetIntent = new Intent(targetIntent); 90 targetIntent.setData(null); 91 final Intent intent = new Intent(SEARCH_RESULT_TRAMPOLINE_ACTION); 92 intent.putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI, 93 targetIntent.toUri(Intent.URI_INTENT_SCHEME)) 94 .putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey) 95 .putExtra(EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA, data); 96 return intent; 97 } 98 buildDirectSearchResultIntent(String action, String targetPackage, String targetClass, String key)99 public static Intent buildDirectSearchResultIntent(String action, String targetPackage, 100 String targetClass, String key) { 101 final Intent intent = new Intent(action).putExtra(EXTRA_FRAGMENT_ARG_KEY, key); 102 if (!TextUtils.isEmpty(targetPackage) && !TextUtils.isEmpty(targetClass)) { 103 final ComponentName component = new ComponentName(targetPackage, targetClass); 104 intent.setComponent(component); 105 } 106 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 107 return intent; 108 } 109 110 // TODO REFACTOR (b/62807132) Add inline support with proper intents. 111 // /** 112 // * @param className which wil provide the map between from {@link Uri}s to 113 // * {@link PreferenceControllerMixin} 114 // * @return A map between {@link Uri}s and {@link PreferenceControllerMixin}s to get the 115 // payload 116 // * types for Settings. 117 // */ 118 // public static Map<String, PreferenceControllerMixin> getPreferenceControllerUriMap( 119 // String className, Context context) { 120 // if (context == null) { 121 // return null; 122 // } 123 // 124 // final Class<?> clazz = getIndexableClass(className); 125 // 126 // if (clazz == null) { 127 // Log.d(TAG, "SearchIndexableResource '" + className + 128 // "' should implement the " + Indexable.class.getName() + " interface!"); 129 // return null; 130 // } 131 // 132 // // Will be non null only for a Local provider implementing a 133 // // SEARCH_INDEX_DATA_PROVIDER field 134 // final Indexable.SearchIndexProvider provider = getSearchIndexProvider(clazz); 135 // 136 // List<AbstractPreferenceController> controllers = 137 // provider.getPreferenceControllers(context); 138 // 139 // if (controllers == null) { 140 // return null; 141 // } 142 // 143 // ArrayMap<String, PreferenceControllerMixin> map = new ArrayMap<>(); 144 // 145 // for (AbstractPreferenceController controller : controllers) { 146 // if (controller instanceof PreferenceControllerMixin) { 147 // map.put(controller.getPreferenceKey(), (PreferenceControllerMixin) controller); 148 // } else { 149 // throw new IllegalStateException(controller.getClass().getName() 150 // + " must implement " + PreferenceControllerMixin.class.getName()); 151 // } 152 // } 153 // 154 // return map; 155 // } 156 // 157 // /** 158 // * @param uriMap Map between the {@link PreferenceControllerMixin} keys 159 // * and the controllers themselves. 160 // * @param key The look-up key 161 // * @return The Payload from the {@link PreferenceControllerMixin} specified by the key, 162 // * if it exists. Otherwise null. 163 // */ 164 // public static ResultPayload getPayloadFromUriMap(Map<String, PreferenceControllerMixin> 165 // uriMap, 166 // String key) { 167 // if (uriMap == null) { 168 // return null; 169 // } 170 // 171 // PreferenceControllerMixin controller = uriMap.get(key); 172 // if (controller == null) { 173 // return null; 174 // } 175 // 176 // return controller.getResultPayload(); 177 // } 178 179 } 180