• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Arrays;
39 import java.util.List;
40 
41 /**
42  * A TargetInfo plus additional information needed to render it (such as icon and label) and
43  * resolve it to an activity.
44  */
45 public class DisplayResolveInfo implements TargetInfo, Parcelable {
46     // Temporary flag for new chooser delegate behavior. There are occassional token
47     // permission errors from bouncing through the delegate. Watch out before reenabling:
48     // b/157272342 is one example but this issue has been reported many times
49     private static final boolean ENABLE_CHOOSER_DELEGATE = false;
50 
51     private final ResolveInfo mResolveInfo;
52     private CharSequence mDisplayLabel;
53     private Drawable mDisplayIcon;
54     private CharSequence mExtendedInfo;
55     private final Intent mResolvedIntent;
56     private final List<Intent> mSourceIntents = new ArrayList<>();
57     private boolean mIsSuspended;
58     private ResolveInfoPresentationGetter mResolveInfoPresentationGetter;
59     private boolean mPinned = false;
60 
DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, Intent pOrigIntent, ResolveInfoPresentationGetter resolveInfoPresentationGetter)61     public DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, Intent pOrigIntent,
62             ResolveInfoPresentationGetter resolveInfoPresentationGetter) {
63         this(originalIntent, pri, null /*mDisplayLabel*/, null /*mExtendedInfo*/, pOrigIntent,
64                 resolveInfoPresentationGetter);
65     }
66 
DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel, CharSequence pInfo, @NonNull Intent resolvedIntent, @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter)67     public DisplayResolveInfo(Intent originalIntent, ResolveInfo pri, CharSequence pLabel,
68             CharSequence pInfo, @NonNull Intent resolvedIntent,
69             @Nullable ResolveInfoPresentationGetter resolveInfoPresentationGetter) {
70         mSourceIntents.add(originalIntent);
71         mResolveInfo = pri;
72         mDisplayLabel = pLabel;
73         mExtendedInfo = pInfo;
74         mResolveInfoPresentationGetter = resolveInfoPresentationGetter;
75 
76         final Intent intent = new Intent(resolvedIntent);
77         intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
78                 | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
79         final ActivityInfo ai = mResolveInfo.activityInfo;
80         intent.setComponent(new ComponentName(ai.applicationInfo.packageName, ai.name));
81 
82         mIsSuspended = (ai.applicationInfo.flags & ApplicationInfo.FLAG_SUSPENDED) != 0;
83 
84         mResolvedIntent = intent;
85     }
86 
DisplayResolveInfo(DisplayResolveInfo other, Intent fillInIntent, int flags, ResolveInfoPresentationGetter resolveInfoPresentationGetter)87     private DisplayResolveInfo(DisplayResolveInfo other, Intent fillInIntent, int flags,
88             ResolveInfoPresentationGetter resolveInfoPresentationGetter) {
89         mSourceIntents.addAll(other.getAllSourceIntents());
90         mResolveInfo = other.mResolveInfo;
91         mDisplayLabel = other.mDisplayLabel;
92         mDisplayIcon = other.mDisplayIcon;
93         mExtendedInfo = other.mExtendedInfo;
94         mResolvedIntent = new Intent(other.mResolvedIntent);
95         mResolvedIntent.fillIn(fillInIntent, flags);
96         mResolveInfoPresentationGetter = resolveInfoPresentationGetter;
97     }
98 
DisplayResolveInfo(DisplayResolveInfo other)99     DisplayResolveInfo(DisplayResolveInfo other) {
100         mSourceIntents.addAll(other.getAllSourceIntents());
101         mResolveInfo = other.mResolveInfo;
102         mDisplayLabel = other.mDisplayLabel;
103         mDisplayIcon = other.mDisplayIcon;
104         mExtendedInfo = other.mExtendedInfo;
105         mResolvedIntent = other.mResolvedIntent;
106         mResolveInfoPresentationGetter = other.mResolveInfoPresentationGetter;
107     }
108 
getResolveInfo()109     public ResolveInfo getResolveInfo() {
110         return mResolveInfo;
111     }
112 
getDisplayLabel()113     public CharSequence getDisplayLabel() {
114         if (mDisplayLabel == null && mResolveInfoPresentationGetter != null) {
115             mDisplayLabel = mResolveInfoPresentationGetter.getLabel();
116             mExtendedInfo = mResolveInfoPresentationGetter.getSubLabel();
117         }
118         return mDisplayLabel;
119     }
120 
hasDisplayLabel()121     public boolean hasDisplayLabel() {
122         return mDisplayLabel != null;
123     }
124 
setDisplayLabel(CharSequence displayLabel)125     public void setDisplayLabel(CharSequence displayLabel) {
126         mDisplayLabel = displayLabel;
127     }
128 
setExtendedInfo(CharSequence extendedInfo)129     public void setExtendedInfo(CharSequence extendedInfo) {
130         mExtendedInfo = extendedInfo;
131     }
132 
getDisplayIcon(Context context)133     public Drawable getDisplayIcon(Context context) {
134         return mDisplayIcon;
135     }
136 
137     @Override
cloneFilledIn(Intent fillInIntent, int flags)138     public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
139         return new DisplayResolveInfo(this, fillInIntent, flags, mResolveInfoPresentationGetter);
140     }
141 
142     @Override
getAllSourceIntents()143     public List<Intent> getAllSourceIntents() {
144         return mSourceIntents;
145     }
146 
addAlternateSourceIntent(Intent alt)147     public void addAlternateSourceIntent(Intent alt) {
148         mSourceIntents.add(alt);
149     }
150 
setDisplayIcon(Drawable icon)151     public void setDisplayIcon(Drawable icon) {
152         mDisplayIcon = icon;
153     }
154 
hasDisplayIcon()155     public boolean hasDisplayIcon() {
156         return mDisplayIcon != null;
157     }
158 
getExtendedInfo()159     public CharSequence getExtendedInfo() {
160         return mExtendedInfo;
161     }
162 
getResolvedIntent()163     public Intent getResolvedIntent() {
164         return mResolvedIntent;
165     }
166 
167     @Override
getResolvedComponentName()168     public ComponentName getResolvedComponentName() {
169         return new ComponentName(mResolveInfo.activityInfo.packageName,
170                 mResolveInfo.activityInfo.name);
171     }
172 
173     @Override
start(Activity activity, Bundle options)174     public boolean start(Activity activity, Bundle options) {
175         activity.startActivity(mResolvedIntent, options);
176         return true;
177     }
178 
179     @Override
startAsCaller(ResolverActivity activity, Bundle options, int userId)180     public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) {
181         if (ENABLE_CHOOSER_DELEGATE) {
182             return activity.startAsCallerImpl(mResolvedIntent, options, false, userId);
183         } else {
184             activity.startActivityAsCaller(mResolvedIntent, options, null, false, userId);
185             return true;
186         }
187     }
188 
189     @Override
startAsUser(Activity activity, Bundle options, UserHandle user)190     public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
191         activity.startActivityAsUser(mResolvedIntent, options, user);
192         return false;
193     }
194 
isSuspended()195     public boolean isSuspended() {
196         return mIsSuspended;
197     }
198 
199     @Override
isPinned()200     public boolean isPinned() {
201         return mPinned;
202     }
203 
setPinned(boolean pinned)204     public void setPinned(boolean pinned) {
205         mPinned = pinned;
206     }
207 
208     @Override
describeContents()209     public int describeContents() {
210         return 0;
211     }
212 
213     @Override
writeToParcel(Parcel dest, int flags)214     public void writeToParcel(Parcel dest, int flags) {
215         dest.writeCharSequence(mDisplayLabel);
216         dest.writeCharSequence(mExtendedInfo);
217         dest.writeParcelable(mResolvedIntent, 0);
218         dest.writeParcelableArray((Intent[]) mSourceIntents.toArray(), 0);
219         dest.writeBoolean(mIsSuspended);
220         dest.writeBoolean(mPinned);
221         dest.writeParcelable(mResolveInfo, 0);
222     }
223 
224     public static final Parcelable.Creator<DisplayResolveInfo> CREATOR =
225             new Parcelable.Creator<DisplayResolveInfo>() {
226         public DisplayResolveInfo createFromParcel(Parcel in) {
227             return new DisplayResolveInfo(in);
228         }
229 
230         public DisplayResolveInfo[] newArray(int size) {
231             return new DisplayResolveInfo[size];
232         }
233     };
234 
DisplayResolveInfo(Parcel in)235     private DisplayResolveInfo(Parcel in) {
236         mDisplayLabel = in.readCharSequence();
237         mExtendedInfo = in.readCharSequence();
238         mResolvedIntent = in.readParcelable(null /* ClassLoader */);
239         mSourceIntents.addAll(
240                 Arrays.asList((Intent[]) in.readParcelableArray(null /* ClassLoader */)));
241         mIsSuspended = in.readBoolean();
242         mPinned = in.readBoolean();
243         mResolveInfo = in.readParcelable(null /* ClassLoader */);
244     }
245 }
246