• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.intentresolver.icons;
18 
19 import android.annotation.Nullable;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.pm.ActivityInfo;
23 import android.content.pm.LauncherApps;
24 import android.content.pm.PackageManager;
25 import android.content.pm.ShortcutInfo;
26 import android.graphics.Bitmap;
27 import android.graphics.drawable.BitmapDrawable;
28 import android.graphics.drawable.Drawable;
29 import android.graphics.drawable.Icon;
30 import android.os.Trace;
31 import android.util.Log;
32 
33 import androidx.annotation.WorkerThread;
34 
35 import com.android.intentresolver.SimpleIconFactory;
36 import com.android.intentresolver.TargetPresentationGetter;
37 import com.android.intentresolver.chooser.SelectableTargetInfo;
38 import com.android.intentresolver.util.UriFilters;
39 
40 import java.util.function.Consumer;
41 
42 /**
43  * Loads direct share targets icons.
44  */
45 class LoadDirectShareIconTask extends BaseLoadIconTask {
46     private static final String TAG = "DirectShareIconTask";
47     private final SelectableTargetInfo mTargetInfo;
48 
LoadDirectShareIconTask( Context context, SelectableTargetInfo targetInfo, TargetPresentationGetter.Factory presentationFactory, Consumer<Drawable> callback)49     LoadDirectShareIconTask(
50             Context context,
51             SelectableTargetInfo targetInfo,
52             TargetPresentationGetter.Factory presentationFactory,
53             Consumer<Drawable> callback) {
54         super(context, presentationFactory, callback);
55         mTargetInfo = targetInfo;
56     }
57 
58     @Override
doInBackground(Void... voids)59     protected Drawable doInBackground(Void... voids) {
60         Drawable drawable;
61         Trace.beginSection("shortcut-icon");
62         try {
63             final Icon icon = mTargetInfo.getChooserTargetIcon();
64             if (icon == null || UriFilters.hasValidIcon(icon)) {
65                 drawable = getChooserTargetIconDrawable(
66                         mContext,
67                         icon,
68                         mTargetInfo.getChooserTargetComponentName(),
69                         mTargetInfo.getDirectShareShortcutInfo());
70             } else {
71                 Log.e(TAG, "Failed to load shortcut icon for "
72                         + mTargetInfo.getChooserTargetComponentName() + "; no access");
73                 drawable = loadIconPlaceholder();
74             }
75         } catch (Exception e) {
76             Log.e(
77                     TAG,
78                     "Failed to load shortcut icon for "
79                             + mTargetInfo.getChooserTargetComponentName(),
80                     e);
81             drawable = loadIconPlaceholder();
82         } finally {
83             Trace.endSection();
84         }
85         return drawable;
86     }
87 
88     @WorkerThread
getChooserTargetIconDrawable( Context context, @Nullable Icon icon, ComponentName targetComponentName, @Nullable ShortcutInfo shortcutInfo)89     private Drawable getChooserTargetIconDrawable(
90             Context context,
91             @Nullable Icon icon,
92             ComponentName targetComponentName,
93             @Nullable ShortcutInfo shortcutInfo) {
94         Drawable directShareIcon = null;
95 
96         // First get the target drawable and associated activity info
97         if (icon != null) {
98             directShareIcon = icon.loadDrawable(context);
99         } else if (shortcutInfo != null) {
100             LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
101             if (launcherApps != null) {
102                 directShareIcon = launcherApps.getShortcutIconDrawable(shortcutInfo, 0);
103             }
104         }
105 
106         if (directShareIcon == null) {
107             return null;
108         }
109 
110         ActivityInfo info = null;
111         try {
112             info = context.getPackageManager().getActivityInfo(targetComponentName, 0);
113         } catch (PackageManager.NameNotFoundException error) {
114             Log.e(TAG, "Could not find activity associated with ChooserTarget");
115         }
116 
117         if (info == null) {
118             return null;
119         }
120 
121         // Now fetch app icon and raster with no badging even in work profile
122         Bitmap appIcon = mPresentationFactory.makePresentationGetter(info).getIconBitmap(null);
123 
124         // Raster target drawable with appIcon as a badge
125         SimpleIconFactory sif = SimpleIconFactory.obtain(context);
126         Bitmap directShareBadgedIcon = sif.createAppBadgedIconBitmap(directShareIcon, appIcon);
127         sif.recycle();
128 
129         return new BitmapDrawable(context.getResources(), directShareBadgedIcon);
130     }
131 }
132