1 /* 2 * Copyright (C) 2019 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.internal.app.chooser; 18 19 20 import static android.security.Flags.preventIntentRedirect; 21 22 import android.app.Activity; 23 import android.app.ActivityManager; 24 import android.content.ComponentName; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.content.pm.ResolveInfo; 28 import android.graphics.drawable.Drawable; 29 import android.os.Bundle; 30 import android.os.RemoteException; 31 import android.os.UserHandle; 32 33 import com.android.internal.app.ResolverActivity; 34 35 import java.util.List; 36 37 /** 38 * A single target as represented in the chooser. 39 */ 40 public interface TargetInfo { 41 /** 42 * Get the resolved intent that represents this target. Note that this may not be the 43 * intent that will be launched by calling one of the <code>start</code> methods provided; 44 * this is the intent that will be credited with the launch. 45 * 46 * @return the resolved intent for this target 47 */ getResolvedIntent()48 Intent getResolvedIntent(); 49 50 /** 51 * Get the resolved component name that represents this target. Note that this may not 52 * be the component that will be directly launched by calling one of the <code>start</code> 53 * methods provided; this is the component that will be credited with the launch. 54 * 55 * @return the resolved ComponentName for this target 56 */ getResolvedComponentName()57 ComponentName getResolvedComponentName(); 58 59 /** 60 * Start the activity referenced by this target. 61 * 62 * @param activity calling Activity performing the launch 63 * @param options ActivityOptions bundle 64 * @return true if the start completed successfully 65 */ start(Activity activity, Bundle options)66 boolean start(Activity activity, Bundle options); 67 68 /** 69 * Start the activity referenced by this target as if the ResolverActivity's caller 70 * was performing the start operation. 71 * 72 * @param activity calling Activity (actually) performing the launch 73 * @param options ActivityOptions bundle 74 * @param userId userId to start as or {@link UserHandle#USER_NULL} for activity's caller 75 * @return true if the start completed successfully 76 */ startAsCaller(ResolverActivity activity, Bundle options, int userId)77 boolean startAsCaller(ResolverActivity activity, Bundle options, int userId); 78 79 /** 80 * Start the activity referenced by this target as a given user. 81 * 82 * @param activity calling activity performing the launch 83 * @param options ActivityOptions bundle 84 * @param user handle for the user to start the activity as 85 * @return true if the start completed successfully 86 */ startAsUser(Activity activity, Bundle options, UserHandle user)87 boolean startAsUser(Activity activity, Bundle options, UserHandle user); 88 89 /** 90 * Return the ResolveInfo about how and why this target matched the original query 91 * for available targets. 92 * 93 * @return ResolveInfo representing this target's match 94 */ getResolveInfo()95 ResolveInfo getResolveInfo(); 96 97 /** 98 * Return the human-readable text label for this target. 99 * 100 * @return user-visible target label 101 */ getDisplayLabel()102 CharSequence getDisplayLabel(); 103 104 /** 105 * Return any extended info for this target. This may be used to disambiguate 106 * otherwise identical targets. 107 * 108 * @return human-readable disambig string or null if none present 109 */ getExtendedInfo()110 CharSequence getExtendedInfo(); 111 112 /** 113 * @return The drawable that should be used to represent this target including badge 114 * @param context 115 */ getDisplayIcon(Context context)116 Drawable getDisplayIcon(Context context); 117 118 /** 119 * Clone this target with the given fill-in information. 120 */ cloneFilledIn(Intent fillInIntent, int flags)121 TargetInfo cloneFilledIn(Intent fillInIntent, int flags); 122 123 /** 124 * @return the list of supported source intents deduped against this single target 125 */ getAllSourceIntents()126 List<Intent> getAllSourceIntents(); 127 128 /** 129 * @return true if this target cannot be selected by the user 130 */ isSuspended()131 boolean isSuspended(); 132 133 /** 134 * @return true if this target should be pinned to the front by the request of the user 135 */ isPinned()136 boolean isPinned(); 137 138 /** 139 * Fix the URIs in {@code intent} if cross-profile sharing is required. This should be called 140 * before launching the intent as another user. 141 */ prepareIntentForCrossProfileLaunch(Intent intent, int targetUserId)142 static void prepareIntentForCrossProfileLaunch(Intent intent, int targetUserId) { 143 final int currentUserId = UserHandle.myUserId(); 144 if (targetUserId != currentUserId) { 145 intent.fixUris(currentUserId); 146 } 147 } 148 149 /** 150 * refreshes intent's creatorToken with its current intent key fields. This allows 151 * ChooserActivity to still keep original creatorToken's creator uid after making changes to 152 * the intent and still keep it valid. 153 * @param intent the intent's creatorToken needs to up refreshed. 154 */ refreshIntentCreatorToken(Intent intent)155 static void refreshIntentCreatorToken(Intent intent) { 156 if (!preventIntentRedirect()) return; 157 try { 158 intent.setCreatorToken(ActivityManager.getService().refreshIntentCreatorToken( 159 intent.cloneForCreatorToken())); 160 } catch (RemoteException e) { 161 throw new RuntimeException("Failure from system", e); 162 } 163 } 164 } 165