1 /* 2 * Copyright (C) 2024 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 android.app.contextualsearch; 18 19 import static android.Manifest.permission.ACCESS_CONTEXTUAL_SEARCH; 20 21 import android.annotation.FlaggedApi; 22 import android.annotation.IntDef; 23 import android.annotation.RequiresPermission; 24 import android.annotation.SystemApi; 25 import android.app.contextualsearch.flags.Flags; 26 import android.content.Context; 27 import android.os.IBinder; 28 import android.os.RemoteException; 29 import android.os.ServiceManager; 30 import android.os.SystemClock; 31 import android.util.Log; 32 33 import java.lang.annotation.Retention; 34 import java.lang.annotation.RetentionPolicy; 35 36 /** 37 * {@link ContextualSearchManager} is a system service to facilitate contextual search experience on 38 * configured Android devices. 39 * <p> 40 * This class lets a caller start contextual search by calling {@link #startContextualSearch} 41 * method. 42 * 43 * @hide 44 */ 45 @SystemApi 46 @FlaggedApi(Flags.FLAG_ENABLE_SERVICE) 47 public final class ContextualSearchManager { 48 49 /** 50 * Key to get the entrypoint from the extras of the activity launched by contextual search. 51 * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH. 52 */ 53 public static final String EXTRA_ENTRYPOINT = 54 "android.app.contextualsearch.extra.ENTRYPOINT"; 55 56 /** 57 * Key to get the flag_secure value from the extras of the activity launched by contextual 58 * search. The value will be true if flag_secure is found in any of the visible activities. 59 * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH. 60 */ 61 public static final String EXTRA_FLAG_SECURE_FOUND = 62 "android.app.contextualsearch.extra.FLAG_SECURE_FOUND"; 63 64 /** 65 * Key to get the screenshot from the extras of the activity launched by contextual search. 66 * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH. 67 */ 68 public static final String EXTRA_SCREENSHOT = 69 "android.app.contextualsearch.extra.SCREENSHOT"; 70 71 /** 72 * Key to check whether managed profile is visible from the extras of the activity launched by 73 * contextual search. The value will be true if any one of the visible apps is managed. 74 * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH. 75 */ 76 public static final String EXTRA_IS_MANAGED_PROFILE_VISIBLE = 77 "android.app.contextualsearch.extra.IS_MANAGED_PROFILE_VISIBLE"; 78 79 /** 80 * Key to get the list of visible packages from the extras of the activity launched by 81 * contextual search. 82 * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH. 83 */ 84 public static final String EXTRA_VISIBLE_PACKAGE_NAMES = 85 "android.app.contextualsearch.extra.VISIBLE_PACKAGE_NAMES"; 86 87 /** 88 * Key to get the time the user made the invocation request, based on 89 * {@link SystemClock#uptimeMillis()}. 90 * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH. 91 * 92 * TODO: un-hide in W 93 * 94 * @hide 95 */ 96 public static final String EXTRA_INVOCATION_TIME_MS = 97 "android.app.contextualsearch.extra.INVOCATION_TIME_MS"; 98 99 /** 100 * Key to get the binder token from the extras of the activity launched by contextual search. 101 * This token is needed to invoke {@link CallbackToken#getContextualSearchState} method. 102 * Only supposed to be used with ACTON_LAUNCH_CONTEXTUAL_SEARCH. 103 */ 104 public static final String EXTRA_TOKEN = "android.app.contextualsearch.extra.TOKEN"; 105 /** 106 * Intent action for contextual search invocation. The app providing the contextual search 107 * experience must add this intent filter action to the activity it wants to be launched. 108 * <br> 109 * <b>Note</b> This activity must not be exported. 110 */ 111 public static final String ACTION_LAUNCH_CONTEXTUAL_SEARCH = 112 "android.app.contextualsearch.action.LAUNCH_CONTEXTUAL_SEARCH"; 113 114 /** Entrypoint to be used when a user long presses on the nav handle. */ 115 public static final int ENTRYPOINT_LONG_PRESS_NAV_HANDLE = 1; 116 /** Entrypoint to be used when a user long presses on the home button. */ 117 public static final int ENTRYPOINT_LONG_PRESS_HOME = 2; 118 /** Entrypoint to be used when a user long presses on the overview button. */ 119 public static final int ENTRYPOINT_LONG_PRESS_OVERVIEW = 3; 120 /** Entrypoint to be used when a user presses the action button in overview. */ 121 public static final int ENTRYPOINT_OVERVIEW_ACTION = 4; 122 /** Entrypoint to be used when a user presses the context menu button in overview. */ 123 public static final int ENTRYPOINT_OVERVIEW_MENU = 5; 124 /** Entrypoint to be used by system actions like TalkBack, Accessibility etc. */ 125 public static final int ENTRYPOINT_SYSTEM_ACTION = 9; 126 /** Entrypoint to be used when a user long presses on the meta key. */ 127 public static final int ENTRYPOINT_LONG_PRESS_META = 10; 128 /** 129 * The {@link Entrypoint} annotation is used to standardize the entrypoints supported by 130 * {@link #startContextualSearch} method. 131 * 132 * @hide 133 */ 134 @IntDef(prefix = {"ENTRYPOINT_"}, value = { 135 ENTRYPOINT_LONG_PRESS_NAV_HANDLE, 136 ENTRYPOINT_LONG_PRESS_HOME, 137 ENTRYPOINT_LONG_PRESS_OVERVIEW, 138 ENTRYPOINT_OVERVIEW_ACTION, 139 ENTRYPOINT_OVERVIEW_MENU, 140 ENTRYPOINT_SYSTEM_ACTION, 141 ENTRYPOINT_LONG_PRESS_META 142 }) 143 @Retention(RetentionPolicy.SOURCE) 144 public @interface Entrypoint { 145 } 146 private static final String TAG = ContextualSearchManager.class.getSimpleName(); 147 private static final boolean DEBUG = false; 148 149 private final IContextualSearchManager mService; 150 151 /** @hide */ ContextualSearchManager()152 public ContextualSearchManager() { 153 if (DEBUG) Log.d(TAG, "ContextualSearchManager created"); 154 IBinder b = ServiceManager.getService(Context.CONTEXTUAL_SEARCH_SERVICE); 155 mService = IContextualSearchManager.Stub.asInterface(b); 156 } 157 158 /** 159 * Used to start contextual search. 160 * <p> 161 * When {@link #startContextualSearch} is called, the system server does the following: 162 * <ul> 163 * <li>Resolves the activity using the package name and intent filter. The package name 164 * is fetched from the config specified in ContextualSearchManagerService. 165 * The activity must have ACTION_LAUNCH_CONTEXTUAL_SEARCH specified in its manifest. 166 * <li>Puts the required extras in the launch intent. 167 * <li>Launches the activity. 168 * </ul> 169 * </p> 170 * 171 * @param entrypoint the invocation entrypoint 172 */ 173 @RequiresPermission(ACCESS_CONTEXTUAL_SEARCH) startContextualSearch(@ntrypoint int entrypoint)174 public void startContextualSearch(@Entrypoint int entrypoint) { 175 if (DEBUG) Log.d(TAG, "startContextualSearch for entrypoint: " + entrypoint); 176 try { 177 mService.startContextualSearch(entrypoint); 178 } catch (RemoteException e) { 179 if (DEBUG) Log.d(TAG, "Failed to startContextualSearch", e); 180 e.rethrowFromSystemServer(); 181 } 182 } 183 } 184