Merge "Load icons and labels only once" into tm-qpr-dev am: 3002386445

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19961127

Change-Id: I79d2abc85622e57dbb004a4df7cd73635fd1f5d6
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Andrey Epin
2022-10-04 21:06:26 +00:00
committed by Automerger Merge Worker
4 changed files with 85 additions and 62 deletions

View File

@@ -86,7 +86,6 @@ public class ChooserListAdapter extends ResolverListAdapter {
private final ChooserActivityLogger mChooserActivityLogger;
private int mNumShortcutResults = 0;
private Map<DisplayResolveInfo, LoadIconTask> mIconLoaders = new HashMap<>();
private boolean mApplySharingAppLimits;
// Reserve spots for incoming direct share targets by adding placeholders
@@ -265,31 +264,20 @@ public class ChooserListAdapter extends ResolverListAdapter {
return;
}
if (!(info instanceof DisplayResolveInfo)) {
holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo(), alwaysShowSubLabel());
holder.bindIcon(info);
if (info instanceof SelectableTargetInfo) {
// direct share targets should append the application name for a better readout
DisplayResolveInfo rInfo = ((SelectableTargetInfo) info).getDisplayResolveInfo();
CharSequence appName = rInfo != null ? rInfo.getDisplayLabel() : "";
CharSequence extendedInfo = info.getExtendedInfo();
String contentDescription = String.join(" ", info.getDisplayLabel(),
extendedInfo != null ? extendedInfo : "", appName);
holder.updateContentDescription(contentDescription);
}
} else {
holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo(), alwaysShowSubLabel());
holder.bindIcon(info);
if (info instanceof SelectableTargetInfo) {
// direct share targets should append the application name for a better readout
DisplayResolveInfo rInfo = ((SelectableTargetInfo) info).getDisplayResolveInfo();
CharSequence appName = rInfo != null ? rInfo.getDisplayLabel() : "";
CharSequence extendedInfo = info.getExtendedInfo();
String contentDescription = String.join(" ", info.getDisplayLabel(),
extendedInfo != null ? extendedInfo : "", appName);
holder.updateContentDescription(contentDescription);
} else if (info instanceof DisplayResolveInfo) {
DisplayResolveInfo dri = (DisplayResolveInfo) info;
holder.bindLabel(dri.getDisplayLabel(), dri.getExtendedInfo(), alwaysShowSubLabel());
LoadIconTask task = mIconLoaders.get(dri);
if (task == null) {
task = new LoadIconTask(dri, holder);
mIconLoaders.put(dri, task);
task.execute();
} else {
// The holder was potentially changed as the underlying items were
// reshuffled, so reset the target holder
task.setViewHolder(holder);
if (!dri.hasDisplayIcon()) {
loadIcon(dri);
}
}

View File

@@ -55,6 +55,7 @@ import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Insets;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -1475,14 +1476,21 @@ public class ResolverActivity extends Activity implements
mMultiProfilePagerAdapter.getActiveListAdapter().mDisplayList.get(0);
boolean inWorkProfile = getCurrentProfile() == PROFILE_WORK;
ResolverListAdapter inactiveAdapter = mMultiProfilePagerAdapter.getInactiveListAdapter();
DisplayResolveInfo otherProfileResolveInfo = inactiveAdapter.mDisplayList.get(0);
final ResolverListAdapter inactiveAdapter =
mMultiProfilePagerAdapter.getInactiveListAdapter();
final DisplayResolveInfo otherProfileResolveInfo = inactiveAdapter.mDisplayList.get(0);
// Load the icon asynchronously
ImageView icon = findViewById(R.id.icon);
ResolverListAdapter.LoadIconTask iconTask = inactiveAdapter.new LoadIconTask(
otherProfileResolveInfo, new ResolverListAdapter.ViewHolder(icon));
iconTask.execute();
inactiveAdapter.new LoadIconTask(otherProfileResolveInfo) {
@Override
protected void onPostExecute(Drawable drawable) {
if (!isDestroyed()) {
otherProfileResolveInfo.setDisplayIcon(drawable);
new ResolverListAdapter.ViewHolder(icon).bindIcon(otherProfileResolveInfo);
}
}
}.execute();
((TextView) findViewById(R.id.open_cross_profile)).setText(
getResources().getString(

View File

@@ -58,7 +58,10 @@ import com.android.internal.app.chooser.DisplayResolveInfo;
import com.android.internal.app.chooser.TargetInfo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ResolverListAdapter extends BaseAdapter {
private static final String TAG = "ResolverListAdapter";
@@ -87,6 +90,8 @@ public class ResolverListAdapter extends BaseAdapter {
private Runnable mPostListReadyRunnable;
private final boolean mIsAudioCaptureDevice;
private boolean mIsTabLoaded;
private final Map<DisplayResolveInfo, LoadIconTask> mIconLoaders = new HashMap<>();
private final Map<DisplayResolveInfo, LoadLabelTask> mLabelLoaders = new HashMap<>();
public ResolverListAdapter(Context context, List<Intent> payloadIntents,
Intent[] initialIntents, List<ResolveInfo> rList,
@@ -636,26 +641,47 @@ public class ResolverListAdapter extends BaseAdapter {
if (info == null) {
holder.icon.setImageDrawable(
mContext.getDrawable(R.drawable.resolver_icon_placeholder));
holder.bindLabel("", "", false);
return;
}
if (info instanceof DisplayResolveInfo
&& !((DisplayResolveInfo) info).hasDisplayLabel()) {
getLoadLabelTask((DisplayResolveInfo) info, holder).execute();
} else {
holder.bindLabel(info.getDisplayLabel(), info.getExtendedInfo(), alwaysShowSubLabel());
}
if (info instanceof DisplayResolveInfo
&& !((DisplayResolveInfo) info).hasDisplayIcon()) {
new LoadIconTask((DisplayResolveInfo) info, holder).execute();
} else {
if (info instanceof DisplayResolveInfo) {
DisplayResolveInfo dri = (DisplayResolveInfo) info;
boolean hasLabel = dri.hasDisplayLabel();
holder.bindLabel(
dri.getDisplayLabel(),
dri.getExtendedInfo(),
hasLabel && alwaysShowSubLabel());
holder.bindIcon(info);
if (!hasLabel) {
loadLabel(dri);
}
if (!dri.hasDisplayIcon()) {
loadIcon(dri);
}
}
}
protected LoadLabelTask getLoadLabelTask(DisplayResolveInfo info, ViewHolder holder) {
return new LoadLabelTask(info, holder);
protected final void loadIcon(DisplayResolveInfo info) {
LoadIconTask task = mIconLoaders.get(info);
if (task == null) {
task = new LoadIconTask((DisplayResolveInfo) info);
mIconLoaders.put(info, task);
task.execute();
}
}
private void loadLabel(DisplayResolveInfo info) {
LoadLabelTask task = mLabelLoaders.get(info);
if (task == null) {
task = createLoadLabelTask(info);
mLabelLoaders.put(info, task);
task.execute();
}
}
protected LoadLabelTask createLoadLabelTask(DisplayResolveInfo info) {
return new LoadLabelTask(info);
}
public void onDestroy() {
@@ -666,6 +692,16 @@ public class ResolverListAdapter extends BaseAdapter {
if (mResolverListController != null) {
mResolverListController.destroy();
}
cancelTasks(mIconLoaders.values());
cancelTasks(mLabelLoaders.values());
mIconLoaders.clear();
mLabelLoaders.clear();
}
private <T extends AsyncTask> void cancelTasks(Collection<T> tasks) {
for (T task: tasks) {
task.cancel(false);
}
}
private static ColorMatrixColorFilter getSuspendedColorMatrix() {
@@ -883,11 +919,9 @@ public class ResolverListAdapter extends BaseAdapter {
protected class LoadLabelTask extends AsyncTask<Void, Void, CharSequence[]> {
private final DisplayResolveInfo mDisplayResolveInfo;
private final ViewHolder mHolder;
protected LoadLabelTask(DisplayResolveInfo dri, ViewHolder holder) {
protected LoadLabelTask(DisplayResolveInfo dri) {
mDisplayResolveInfo = dri;
mHolder = holder;
}
@Override
@@ -925,21 +959,22 @@ public class ResolverListAdapter extends BaseAdapter {
@Override
protected void onPostExecute(CharSequence[] result) {
if (mDisplayResolveInfo.hasDisplayLabel()) {
return;
}
mDisplayResolveInfo.setDisplayLabel(result[0]);
mDisplayResolveInfo.setExtendedInfo(result[1]);
mHolder.bindLabel(result[0], result[1], alwaysShowSubLabel());
notifyDataSetChanged();
}
}
class LoadIconTask extends AsyncTask<Void, Void, Drawable> {
protected final DisplayResolveInfo mDisplayResolveInfo;
private final ResolveInfo mResolveInfo;
private ViewHolder mHolder;
LoadIconTask(DisplayResolveInfo dri, ViewHolder holder) {
LoadIconTask(DisplayResolveInfo dri) {
mDisplayResolveInfo = dri;
mResolveInfo = dri.getResolveInfo();
mHolder = holder;
}
@Override
@@ -953,17 +988,9 @@ public class ResolverListAdapter extends BaseAdapter {
mResolverListCommunicator.updateProfileViewButton();
} else if (!mDisplayResolveInfo.hasDisplayIcon()) {
mDisplayResolveInfo.setDisplayIcon(d);
mHolder.bindIcon(mDisplayResolveInfo);
// Notify in case view is already bound to resolve the race conditions on
// low end devices
notifyDataSetChanged();
}
}
public void setViewHolder(ViewHolder holder) {
mHolder = holder;
mHolder.bindIcon(mDisplayResolveInfo);
}
}
/**

View File

@@ -46,14 +46,14 @@ public class ResolverWrapperAdapter extends ResolverListAdapter {
}
@Override
protected LoadLabelTask getLoadLabelTask(DisplayResolveInfo info, ViewHolder holder) {
return new LoadLabelWrapperTask(info, holder);
protected LoadLabelTask createLoadLabelTask(DisplayResolveInfo info) {
return new LoadLabelWrapperTask(info);
}
class LoadLabelWrapperTask extends LoadLabelTask {
protected LoadLabelWrapperTask(DisplayResolveInfo dri, ViewHolder holder) {
super(dri, holder);
protected LoadLabelWrapperTask(DisplayResolveInfo dri) {
super(dri);
}
@Override