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 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.app.Activity; 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.pm.ActivityInfo; 26 import android.content.pm.ApplicationInfo; 27 import android.content.pm.ResolveInfo; 28 import android.graphics.drawable.Drawable; 29 import android.os.Bundle; 30 import android.os.Parcel; 31 import android.os.Parcelable; 32 import android.os.UserHandle; 33 34 import com.android.internal.app.ResolverActivity; 35 import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; 36 37 import java.util.ArrayList; 38 import java.util.List; 39 40 /** 41 * A TargetInfo plus additional information needed to render it (such as icon and label) and 42 * resolve it to an activity. 43 */ 44 public class DisplayResolveInfo implements TargetInfo, Parcelable { 45 private final ResolveInfo mResolveInfo; 46 private CharSequence mDisplayLabel; 47 private Drawable mDisplayIcon; 48 private CharSequence mExtendedInfo; 49 private final Intent mResolvedIntent; 50 private final List<Intent> mSourceIntents = new ArrayList<>(); 51 private boolean mIsSuspended; 52 private ResolveInfoPresentationGetter mResolveInfoPresentationGetter; 53 private boolean mPinned = false; 54 DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, Intent pOrigIntent, ResolveInfoPresentationGetter resolveInfoPresentationGetter)55 public DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, Intent pOrigIntent, 56 ResolveInfoPresentationGetter resolveInfoPresentationGetter) { 57 this(originalIntent, pri, null /*mDisplayLabel*/, null /*mExtendedInfo*/, pOrigIntent, 58 resolveInfoPresentationGetter); 59 } 60 DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel, CharSequence pInfo, @NonNull Intent resolvedIntent, @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter)61 public DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel, 62 CharSequence pInfo, @NonNull Intent resolvedIntent, 63 @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter) { 64 mSourceIntents.add(originalIntent); 65 mResolveInfo = pri; 66 mDisplayLabel = pLabel; 67 mExtendedInfo = pInfo; 68 mResolveInfoPresentationGetter = resolveInfoPresentationGetter; 69 70 final Intent intent = new Intent(resolvedIntent); 71 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT 72 | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); 73 final ActivityInfo ai = mResolveInfo.activityInfo; 74 intent.setComponent(new ComponentName(ai.applicationInfo.packageName, ai.name)); 75 76 mIsSuspended = (ai.applicationInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0; 77 78 mResolvedIntent = intent; 79 } 80 DisplayResolveInfo(DisplayResolveInfo other, Intent fillInIntent, int flags, ResolveInfoPresentationGetter resolveInfoPresentationGetter)81 private DisplayResolveInfo(DisplayResolveInfo other, Intent fillInIntent, int flags, 82 ResolveInfoPresentationGetter resolveInfoPresentationGetter) { 83 mSourceIntents.addAll(other.getAllSourceIntents()); 84 mResolveInfo = other.mResolveInfo; 85 mDisplayLabel = other.mDisplayLabel; 86 mDisplayIcon = other.mDisplayIcon; 87 mExtendedInfo = other.mExtendedInfo; 88 mResolvedIntent = new Intent(other.mResolvedIntent); 89 mResolvedIntent.fillIn(fillInIntent, flags); 90 mResolveInfoPresentationGetter = resolveInfoPresentationGetter; 91 } 92 DisplayResolveInfo(DisplayResolveInfo other)93 DisplayResolveInfo(DisplayResolveInfo other) { 94 mSourceIntents.addAll(other.getAllSourceIntents()); 95 mResolveInfo = other.mResolveInfo; 96 mDisplayLabel = other.mDisplayLabel; 97 mDisplayIcon = other.mDisplayIcon; 98 mExtendedInfo = other.mExtendedInfo; 99 mResolvedIntent = other.mResolvedIntent; 100 mResolveInfoPresentationGetter = other.mResolveInfoPresentationGetter; 101 } 102 getResolveInfo()103 public ResolveInfo getResolveInfo() { 104 return mResolveInfo; 105 } 106 getDisplayLabel()107 public CharSequence getDisplayLabel() { 108 if (mDisplayLabel == null && mResolveInfoPresentationGetter != null) { 109 mDisplayLabel = mResolveInfoPresentationGetter.getLabel(); 110 mExtendedInfo = mResolveInfoPresentationGetter.getSubLabel(); 111 } 112 return mDisplayLabel; 113 } 114 hasDisplayLabel()115 public boolean hasDisplayLabel() { 116 return mDisplayLabel != null; 117 } 118 setDisplayLabel(CharSequence displayLabel)119 public void setDisplayLabel(CharSequence displayLabel) { 120 mDisplayLabel = displayLabel; 121 } 122 setExtendedInfo(CharSequence extendedInfo)123 public void setExtendedInfo(CharSequence extendedInfo) { 124 mExtendedInfo = extendedInfo; 125 } 126 getDisplayIcon(Context context)127 public Drawable getDisplayIcon(Context context) { 128 return mDisplayIcon; 129 } 130 131 @Override cloneFilledIn(Intent fillInIntent, int flags)132 public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) { 133 return new DisplayResolveInfo(this, fillInIntent, flags, mResolveInfoPresentationGetter); 134 } 135 136 @Override getAllSourceIntents()137 public List<Intent> getAllSourceIntents() { 138 return mSourceIntents; 139 } 140 addAlternateSourceIntent(Intent alt)141 public void addAlternateSourceIntent(Intent alt) { 142 mSourceIntents.add(alt); 143 } 144 setDisplayIcon(Drawable icon)145 public void setDisplayIcon(Drawable icon) { 146 mDisplayIcon = icon; 147 } 148 hasDisplayIcon()149 public boolean hasDisplayIcon() { 150 return mDisplayIcon != null; 151 } 152 getExtendedInfo()153 public CharSequence getExtendedInfo() { 154 return mExtendedInfo; 155 } 156 getResolvedIntent()157 public Intent getResolvedIntent() { 158 return mResolvedIntent; 159 } 160 161 @Override getResolvedComponentName()162 public ComponentName getResolvedComponentName() { 163 return new ComponentName(mResolveInfo.activityInfo.packageName, 164 mResolveInfo.activityInfo.name); 165 } 166 167 @Override start(Activity activity, Bundle options)168 public boolean start(Activity activity, Bundle options) { 169 activity.startActivity(mResolvedIntent, options); 170 return true; 171 } 172 173 @Override startAsCaller(ResolverActivity activity, Bundle options, int userId)174 public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) { 175 TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, userId); 176 activity.startActivityAsCaller(mResolvedIntent, options, false, userId); 177 return true; 178 } 179 180 @Override startAsUser(Activity activity, Bundle options, UserHandle user)181 public boolean startAsUser(Activity activity, Bundle options, UserHandle user) { 182 TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, user.getIdentifier()); 183 activity.startActivityAsUser(mResolvedIntent, options, user); 184 return false; 185 } 186 isSuspended()187 public boolean isSuspended() { 188 return mIsSuspended; 189 } 190 191 @Override isPinned()192 public boolean isPinned() { 193 return mPinned; 194 } 195 setPinned(boolean pinned)196 public void setPinned(boolean pinned) { 197 mPinned = pinned; 198 } 199 200 @Override describeContents()201 public int describeContents() { 202 return 0; 203 } 204 205 @Override writeToParcel(Parcel dest, int flags)206 public void writeToParcel(Parcel dest, int flags) { 207 dest.writeCharSequence(mDisplayLabel); 208 dest.writeCharSequence(mExtendedInfo); 209 dest.writeParcelable(mResolvedIntent, 0); 210 dest.writeTypedList(mSourceIntents); 211 dest.writeBoolean(mIsSuspended); 212 dest.writeBoolean(mPinned); 213 dest.writeParcelable(mResolveInfo, 0); 214 } 215 216 public static final Parcelable.Creator<DisplayResolveInfo> CREATOR = 217 new Parcelable.Creator<DisplayResolveInfo>() { 218 public DisplayResolveInfo createFromParcel(Parcel in) { 219 return new DisplayResolveInfo(in); 220 } 221 222 public DisplayResolveInfo[] newArray(int size) { 223 return new DisplayResolveInfo[size]; 224 } 225 }; 226 DisplayResolveInfo(Parcel in)227 private DisplayResolveInfo(Parcel in) { 228 mDisplayLabel = in.readCharSequence(); 229 mExtendedInfo = in.readCharSequence(); 230 mResolvedIntent = in.readParcelable(null /* ClassLoader */, android.content.Intent.class); 231 in.readTypedList(mSourceIntents, Intent.CREATOR); 232 mIsSuspended = in.readBoolean(); 233 mPinned = in.readBoolean(); 234 mResolveInfo = in.readParcelable(null /* ClassLoader */, android.content.pm.ResolveInfo.class); 235 } 236 } 237