arangelov | b0802dc | 2019-10-18 18:03:44 +0100 | [diff] [blame] | 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.UserHandle; |
| 31 | |
| 32 | import com.android.internal.app.ResolverActivity; |
| 33 | import com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; |
| 34 | |
| 35 | import java.util.ArrayList; |
| 36 | import java.util.List; |
| 37 | |
| 38 | /** |
| 39 | * A TargetInfo plus additional information needed to render it (such as icon and label) and |
| 40 | * resolve it to an activity. |
| 41 | */ |
| 42 | public class DisplayResolveInfo implements TargetInfo { |
Matt Pietal | 9a17836 | 2020-06-09 15:00:38 -0400 | [diff] [blame^] | 43 | // Temporary flag for new chooser delegate behavior. There are occassional token |
| 44 | // permission errors from bouncing through the delegate. Watch out before reenabling: |
| 45 | // b/157272342 is one example but this issue has been reported many times |
| 46 | private static final boolean ENABLE_CHOOSER_DELEGATE = false; |
arangelov | b0802dc | 2019-10-18 18:03:44 +0100 | [diff] [blame] | 47 | |
| 48 | private final ResolveInfo mResolveInfo; |
| 49 | private CharSequence mDisplayLabel; |
| 50 | private Drawable mDisplayIcon; |
| 51 | private CharSequence mExtendedInfo; |
| 52 | private final Intent mResolvedIntent; |
| 53 | private final List<Intent> mSourceIntents = new ArrayList<>(); |
| 54 | private boolean mIsSuspended; |
| 55 | private ResolveInfoPresentationGetter mResolveInfoPresentationGetter; |
Alison Cichowlas | 1fd4715 | 2019-11-14 19:50:55 -0500 | [diff] [blame] | 56 | private boolean mPinned = false; |
arangelov | b0802dc | 2019-10-18 18:03:44 +0100 | [diff] [blame] | 57 | |
| 58 | public DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, Intent pOrigIntent, |
| 59 | ResolveInfoPresentationGetter resolveInfoPresentationGetter) { |
| 60 | this(originalIntent, pri, null /*mDisplayLabel*/, null /*mExtendedInfo*/, pOrigIntent, |
| 61 | resolveInfoPresentationGetter); |
| 62 | } |
| 63 | |
| 64 | public DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel, |
| 65 | CharSequence pInfo, @NonNull Intent resolvedIntent, |
| 66 | @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter) { |
| 67 | mSourceIntents.add(originalIntent); |
| 68 | mResolveInfo = pri; |
| 69 | mDisplayLabel = pLabel; |
| 70 | mExtendedInfo = pInfo; |
| 71 | mResolveInfoPresentationGetter = resolveInfoPresentationGetter; |
| 72 | |
| 73 | final Intent intent = new Intent(resolvedIntent); |
| 74 | intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT |
| 75 | | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); |
| 76 | final ActivityInfo ai = mResolveInfo.activityInfo; |
| 77 | intent.setComponent(new ComponentName(ai.applicationInfo.packageName, ai.name)); |
| 78 | |
| 79 | mIsSuspended = (ai.applicationInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0; |
| 80 | |
| 81 | mResolvedIntent = intent; |
| 82 | } |
| 83 | |
| 84 | private DisplayResolveInfo(DisplayResolveInfo other, Intent fillInIntent, int flags, |
| 85 | ResolveInfoPresentationGetter resolveInfoPresentationGetter) { |
| 86 | mSourceIntents.addAll(other.getAllSourceIntents()); |
| 87 | mResolveInfo = other.mResolveInfo; |
| 88 | mDisplayLabel = other.mDisplayLabel; |
| 89 | mDisplayIcon = other.mDisplayIcon; |
| 90 | mExtendedInfo = other.mExtendedInfo; |
| 91 | mResolvedIntent = new Intent(other.mResolvedIntent); |
| 92 | mResolvedIntent.fillIn(fillInIntent, flags); |
| 93 | mResolveInfoPresentationGetter = resolveInfoPresentationGetter; |
| 94 | } |
| 95 | |
Alison Cichowlas | 19ee292 | 2019-12-16 19:43:12 -0500 | [diff] [blame] | 96 | DisplayResolveInfo(DisplayResolveInfo other) { |
| 97 | mSourceIntents.addAll(other.getAllSourceIntents()); |
| 98 | mResolveInfo = other.mResolveInfo; |
| 99 | mDisplayLabel = other.mDisplayLabel; |
| 100 | mDisplayIcon = other.mDisplayIcon; |
| 101 | mExtendedInfo = other.mExtendedInfo; |
| 102 | mResolvedIntent = other.mResolvedIntent; |
| 103 | mResolveInfoPresentationGetter = other.mResolveInfoPresentationGetter; |
| 104 | } |
| 105 | |
arangelov | b0802dc | 2019-10-18 18:03:44 +0100 | [diff] [blame] | 106 | public ResolveInfo getResolveInfo() { |
| 107 | return mResolveInfo; |
| 108 | } |
| 109 | |
| 110 | public CharSequence getDisplayLabel() { |
| 111 | if (mDisplayLabel == null && mResolveInfoPresentationGetter != null) { |
| 112 | mDisplayLabel = mResolveInfoPresentationGetter.getLabel(); |
| 113 | mExtendedInfo = mResolveInfoPresentationGetter.getSubLabel(); |
| 114 | } |
| 115 | return mDisplayLabel; |
| 116 | } |
| 117 | |
| 118 | public boolean hasDisplayLabel() { |
| 119 | return mDisplayLabel != null; |
| 120 | } |
| 121 | |
| 122 | public void setDisplayLabel(CharSequence displayLabel) { |
| 123 | mDisplayLabel = displayLabel; |
| 124 | } |
| 125 | |
| 126 | public void setExtendedInfo(CharSequence extendedInfo) { |
| 127 | mExtendedInfo = extendedInfo; |
| 128 | } |
| 129 | |
| 130 | public Drawable getDisplayIcon(Context context) { |
| 131 | return mDisplayIcon; |
| 132 | } |
| 133 | |
| 134 | @Override |
| 135 | public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) { |
| 136 | return new DisplayResolveInfo(this, fillInIntent, flags, mResolveInfoPresentationGetter); |
| 137 | } |
| 138 | |
| 139 | @Override |
| 140 | public List<Intent> getAllSourceIntents() { |
| 141 | return mSourceIntents; |
| 142 | } |
| 143 | |
| 144 | public void addAlternateSourceIntent(Intent alt) { |
| 145 | mSourceIntents.add(alt); |
| 146 | } |
| 147 | |
| 148 | public void setDisplayIcon(Drawable icon) { |
| 149 | mDisplayIcon = icon; |
| 150 | } |
| 151 | |
| 152 | public boolean hasDisplayIcon() { |
| 153 | return mDisplayIcon != null; |
| 154 | } |
| 155 | |
| 156 | public CharSequence getExtendedInfo() { |
| 157 | return mExtendedInfo; |
| 158 | } |
| 159 | |
| 160 | public Intent getResolvedIntent() { |
| 161 | return mResolvedIntent; |
| 162 | } |
| 163 | |
| 164 | @Override |
| 165 | public ComponentName getResolvedComponentName() { |
| 166 | return new ComponentName(mResolveInfo.activityInfo.packageName, |
| 167 | mResolveInfo.activityInfo.name); |
| 168 | } |
| 169 | |
| 170 | @Override |
| 171 | public boolean start(Activity activity, Bundle options) { |
| 172 | activity.startActivity(mResolvedIntent, options); |
| 173 | return true; |
| 174 | } |
| 175 | |
| 176 | @Override |
| 177 | public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) { |
| 178 | if (ENABLE_CHOOSER_DELEGATE) { |
| 179 | return activity.startAsCallerImpl(mResolvedIntent, options, false, userId); |
| 180 | } else { |
| 181 | activity.startActivityAsCaller(mResolvedIntent, options, null, false, userId); |
| 182 | return true; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | @Override |
| 187 | public boolean startAsUser(Activity activity, Bundle options, UserHandle user) { |
| 188 | activity.startActivityAsUser(mResolvedIntent, options, user); |
| 189 | return false; |
| 190 | } |
| 191 | |
| 192 | public boolean isSuspended() { |
| 193 | return mIsSuspended; |
| 194 | } |
Alison Cichowlas | 1fd4715 | 2019-11-14 19:50:55 -0500 | [diff] [blame] | 195 | |
| 196 | @Override |
| 197 | public boolean isPinned() { |
| 198 | return mPinned; |
| 199 | } |
| 200 | |
| 201 | public void setPinned(boolean pinned) { |
| 202 | mPinned = pinned; |
| 203 | } |
Alison Cichowlas | 19ee292 | 2019-12-16 19:43:12 -0500 | [diff] [blame] | 204 | |
arangelov | b0802dc | 2019-10-18 18:03:44 +0100 | [diff] [blame] | 205 | } |