Loading core/java/com/android/internal/app/ChooserActivity.java +19 −26 Original line number Diff line number Diff line Loading @@ -1614,7 +1614,7 @@ public class ChooserActivity extends ResolverActivity implements targetList = Collections.singletonList(ti); } ResolverTargetActionsDialogFragment f = new ResolverTargetActionsDialogFragment( ChooserTargetActionsDialogFragment f = new ChooserTargetActionsDialogFragment( targetList, mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG); Loading Loading @@ -1674,15 +1674,9 @@ public class ChooserActivity extends ResolverActivity implements if (targetInfo instanceof MultiDisplayResolveInfo) { MultiDisplayResolveInfo mti = (MultiDisplayResolveInfo) targetInfo; if (!mti.hasSelected()) { // Stacked apps get a disambiguation first CharSequence[] labels = new CharSequence[mti.getTargets().size()]; int i = 0; for (TargetInfo ti : mti.getTargets()) { labels[i++] = ti.getResolveInfo().loadLabel(getPackageManager()); } ChooserStackedAppDialogFragment f = new ChooserStackedAppDialogFragment( targetInfo.getDisplayLabel(), ((MultiDisplayResolveInfo) targetInfo), labels, which); mti, which, mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG); return; Loading Loading @@ -2973,19 +2967,19 @@ public class ChooserActivity extends ResolverActivity implements itemView.setOnClickListener(v -> startSelected(mListPosition, false/* always */, true/* filterd */)); TargetInfo ti = mChooserMultiProfilePagerAdapter.getActiveListAdapter() itemView.setOnLongClickListener(v -> { final TargetInfo ti = mChooserMultiProfilePagerAdapter.getActiveListAdapter() .targetInfoForPosition(mListPosition, /* filtered */ true); // This should always be the case for ItemViewHolder, check for sanity if (ti instanceof DisplayResolveInfo) { itemView.setOnLongClickListener(v -> { showTargetDetails((DisplayResolveInfo) ti); } return true; }); } } } } /** * Add a footer to the list, to support scrolling behavior below the navbar. Loading Loading @@ -3310,17 +3304,16 @@ public class ChooserActivity extends ResolverActivity implements // Direct Share targets should not show any menu if (!isDirectShare) { v.setOnLongClickListener(v1 -> { final TargetInfo ti = mChooserListAdapter.targetInfoForPosition( holder.getItemIndex(column), true); // This should always be the case for non-DS targets, check for sanity if (ti instanceof DisplayResolveInfo) { v.setOnLongClickListener(v1 -> { showTargetDetails((DisplayResolveInfo) ti); } return true; }); } } holder.addView(i, v); Loading core/java/com/android/internal/app/ChooserStackedAppDialogFragment.java +19 −33 Original line number Diff line number Diff line Loading @@ -17,64 +17,50 @@ package com.android.internal.app; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; import android.content.DialogInterface; import android.content.res.Configuration; import android.os.Bundle; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.UserHandle; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.MultiDisplayResolveInfo; /** * Shows individual actions for a "stacked" app target - such as an app with multiple posting * streams represented in the Sharesheet. */ public class ChooserStackedAppDialogFragment extends DialogFragment public class ChooserStackedAppDialogFragment extends ChooserTargetActionsDialogFragment implements DialogInterface.OnClickListener { private static final String TITLE_KEY = "title"; private static final String PINNED_KEY = "pinned"; private MultiDisplayResolveInfo mTargetInfos; private CharSequence[] mLabels; private MultiDisplayResolveInfo mMultiDisplayResolveInfo; private int mParentWhich; public ChooserStackedAppDialogFragment() { } public ChooserStackedAppDialogFragment(CharSequence title, MultiDisplayResolveInfo targets, CharSequence[] labels, int parentWhich) { Bundle args = new Bundle(); args.putCharSequence(TITLE_KEY, title); mTargetInfos = targets; mLabels = labels; public ChooserStackedAppDialogFragment(MultiDisplayResolveInfo targets, int parentWhich, UserHandle userHandle) { super(targets.getTargets(), userHandle); mMultiDisplayResolveInfo = targets; mParentWhich = parentWhich; setArguments(args); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Bundle args = getArguments(); return new Builder(getContext()) .setCancelable(true) .setItems(mLabels, this) .setTitle(args.getCharSequence(TITLE_KEY)) .create(); protected CharSequence getItemLabel(DisplayResolveInfo dri) { final PackageManager pm = getContext().getPackageManager(); return dri.getResolveInfo().loadLabel(pm); } @Override public void onClick(DialogInterface dialog, int which) { final Bundle args = getArguments(); mTargetInfos.setSelected(which); ((ChooserActivity) getActivity()).startSelected(mParentWhich, false, true); dismiss(); protected Drawable getItemIcon(DisplayResolveInfo dri) { // Show no icon for the group disambig dialog, null hides the imageview return null; } @Override public void onConfigurationChanged(Configuration newConfig) { // Dismiss on config changed (eg: rotation) // TODO: Maintain state on config change super.onConfigurationChanged(newConfig); public void onClick(DialogInterface dialog, int which) { mMultiDisplayResolveInfo.setSelected(which); ((ChooserActivity) getActivity()).startSelected(mParentWhich, false, true); dismiss(); } } core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java→core/java/com/android/internal/app/ChooserTargetActionsDialogFragment.java +173 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,10 @@ import static android.content.Context.ACTIVITY_SERVICE; import static com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; import static java.util.stream.Collectors.toList; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AlertDialog.Builder; import android.app.Dialog; Loading @@ -30,12 +34,18 @@ import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.util.Pair; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.R; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.TargetInfo; import java.util.ArrayList; import java.util.List; Loading @@ -43,16 +53,16 @@ import java.util.List; /** * Shows a dialog with actions to take on a chooser target. */ public class ResolverTargetActionsDialogFragment extends DialogFragment public class ChooserTargetActionsDialogFragment extends DialogFragment implements DialogInterface.OnClickListener { private List<DisplayResolveInfo> mTargetInfos = new ArrayList<>(); private UserHandle mUserHandle; protected List<DisplayResolveInfo> mTargetInfos = new ArrayList<>(); protected UserHandle mUserHandle; public ResolverTargetActionsDialogFragment() { public ChooserTargetActionsDialogFragment() { } public ResolverTargetActionsDialogFragment(List<DisplayResolveInfo> targets, public ChooserTargetActionsDialogFragment(List<DisplayResolveInfo> targets, UserHandle userHandle) { mUserHandle = userHandle; mTargetInfos = targets; Loading @@ -60,34 +70,47 @@ public class ResolverTargetActionsDialogFragment extends DialogFragment @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Bundle args = getArguments(); final PackageManager pm = getContext().getPackageManager(); // Pin item for each sub-item CharSequence[] items = new CharSequence[mTargetInfos.size()]; for (int i = 0; i < mTargetInfos.size(); i++) { final TargetInfo ti = mTargetInfos.get(i); final CharSequence label = ti.getResolveInfo().loadLabel(pm); items[i] = ti.isPinned() ? getResources().getString(R.string.unpin_specific_target, label) : getResources().getString(R.string.pin_specific_target, label); } // Use the matching application icon and label for the title, any TargetInfo will do final ActivityManager am = (ActivityManager) getContext() .getSystemService(ACTIVITY_SERVICE); final int iconDpi = am.getLauncherLargeIconDensity(); final ResolveInfoPresentationGetter pg = new ResolveInfoPresentationGetter(getContext(), iconDpi, mTargetInfos.get(0).getResolveInfo()); // Fetch UI details from target info List<Pair<CharSequence, Drawable>> items = mTargetInfos.stream().map(dri -> { return new Pair<>(getItemLabel(dri), getItemIcon(dri)); }).collect(toList()); final ResolveInfoPresentationGetter pg = getProvidingAppPresentationGetter(); return new Builder(getContext()) .setTitle(pg.getLabel()) .setIcon(pg.getIcon(mUserHandle)) .setCancelable(true) .setItems(items, this) .setAdapter(getAdapterForContent(items), this) .create(); } protected ArrayAdapter<Pair<CharSequence, Drawable>> getAdapterForContent( List<Pair<CharSequence, Drawable>> items) { return new ArrayAdapter<Pair<CharSequence, Drawable>>(getContext(), R.layout.chooser_dialog_item, R.id.text, items) { @Override public View getView(int position, View convertView, ViewGroup parent) { View v = super.getView(position, convertView, parent); // super recycles views TextView label = v.findViewById(R.id.text); ImageView icon = v.findViewById(R.id.icon); Pair<CharSequence, Drawable> pair = getItem(position); label.setText(pair.first); // Hide icon view if one isn't available if (pair.second == null) { icon.setVisibility(View.GONE); } else { icon.setImageDrawable(pair.second); icon.setVisibility(View.VISIBLE); } return v; } }; } @Override public void onClick(DialogInterface dialog, int which) { pinComponent(mTargetInfos.get(which).getResolvedComponentName()); Loading @@ -106,6 +129,39 @@ public class ResolverTargetActionsDialogFragment extends DialogFragment } } private Drawable getPinIcon(boolean isPinned) { return isPinned ? getContext().getDrawable(R.drawable.ic_close) : getContext().getDrawable(R.drawable.ic_chooser_pin_dialog); } private CharSequence getPinLabel(boolean isPinned, CharSequence targetLabel) { return isPinned ? getResources().getString(R.string.unpin_specific_target, targetLabel) : getResources().getString(R.string.pin_specific_target, targetLabel); } @NonNull protected CharSequence getItemLabel(DisplayResolveInfo dri) { final PackageManager pm = getContext().getPackageManager(); return getPinLabel(dri.isPinned(), dri.getResolveInfo().loadLabel(pm)); } @Nullable protected Drawable getItemIcon(DisplayResolveInfo dri) { return getPinIcon(dri.isPinned()); } private ResolveInfoPresentationGetter getProvidingAppPresentationGetter() { final ActivityManager am = (ActivityManager) getContext() .getSystemService(ACTIVITY_SERVICE); final int iconDpi = am.getLauncherLargeIconDensity(); // Use the matching application icon and label for the title, any TargetInfo will do return new ResolveInfoPresentationGetter(getContext(), iconDpi, mTargetInfos.get(0).getResolveInfo()); } @Override public void onConfigurationChanged(Configuration newConfig) { // Dismiss on config changed (eg: rotation) Loading core/res/res/drawable/ic_chooser_pin_dialog.xml 0 → 100644 +25 −0 Original line number Diff line number Diff line <!-- ~ Copyright (C) 2020 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:pathData="M14,4v5c0,1.12 0.37,2.16 1,3H9c0.65,-0.86 1,-1.9 1,-3V4H14M17,2H7C6.45,2 6,2.45 6,3c0,0.55 0.45,1 1,1c0,0 0,0 0,0l1,0v5c0,1.66 -1.34,3 -3,3v2h5.97v7l1,1l1,-1v-7H19v-2c0,0 0,0 0,0c-1.66,0 -3,-1.34 -3,-3V4l1,0c0,0 0,0 0,0c0.55,0 1,-0.45 1,-1C18,2.45 17.55,2 17,2L17,2z" android:fillColor="#FF000000"/> </vector> core/res/res/layout/chooser_dialog_item.xml 0 → 100644 +44 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2020 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:gravity="start|center_vertical" android:paddingStart="?attr/dialogPreferredPadding" android:paddingEnd="?attr/dialogPreferredPadding" android:minHeight="48dp" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Icon and text aligns with aligns with alert_dialog_title_material --> <ImageView android:id="@+id/icon" android:tint="?android:attr/textColorAlertDialogListItem" android:padding="4dp" android:layout_marginEnd="8dp" android:layout_width="32dp" android:layout_height="32dp"/> <!-- Using text style from select_dialog_item_material --> <TextView android:id="@+id/text" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:textColor="?android:attr/textColorAlertDialogListItem" android:lines="1" android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> No newline at end of file Loading
core/java/com/android/internal/app/ChooserActivity.java +19 −26 Original line number Diff line number Diff line Loading @@ -1614,7 +1614,7 @@ public class ChooserActivity extends ResolverActivity implements targetList = Collections.singletonList(ti); } ResolverTargetActionsDialogFragment f = new ResolverTargetActionsDialogFragment( ChooserTargetActionsDialogFragment f = new ChooserTargetActionsDialogFragment( targetList, mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG); Loading Loading @@ -1674,15 +1674,9 @@ public class ChooserActivity extends ResolverActivity implements if (targetInfo instanceof MultiDisplayResolveInfo) { MultiDisplayResolveInfo mti = (MultiDisplayResolveInfo) targetInfo; if (!mti.hasSelected()) { // Stacked apps get a disambiguation first CharSequence[] labels = new CharSequence[mti.getTargets().size()]; int i = 0; for (TargetInfo ti : mti.getTargets()) { labels[i++] = ti.getResolveInfo().loadLabel(getPackageManager()); } ChooserStackedAppDialogFragment f = new ChooserStackedAppDialogFragment( targetInfo.getDisplayLabel(), ((MultiDisplayResolveInfo) targetInfo), labels, which); mti, which, mChooserMultiProfilePagerAdapter.getCurrentUserHandle()); f.show(getFragmentManager(), TARGET_DETAILS_FRAGMENT_TAG); return; Loading Loading @@ -2973,19 +2967,19 @@ public class ChooserActivity extends ResolverActivity implements itemView.setOnClickListener(v -> startSelected(mListPosition, false/* always */, true/* filterd */)); TargetInfo ti = mChooserMultiProfilePagerAdapter.getActiveListAdapter() itemView.setOnLongClickListener(v -> { final TargetInfo ti = mChooserMultiProfilePagerAdapter.getActiveListAdapter() .targetInfoForPosition(mListPosition, /* filtered */ true); // This should always be the case for ItemViewHolder, check for sanity if (ti instanceof DisplayResolveInfo) { itemView.setOnLongClickListener(v -> { showTargetDetails((DisplayResolveInfo) ti); } return true; }); } } } } /** * Add a footer to the list, to support scrolling behavior below the navbar. Loading Loading @@ -3310,17 +3304,16 @@ public class ChooserActivity extends ResolverActivity implements // Direct Share targets should not show any menu if (!isDirectShare) { v.setOnLongClickListener(v1 -> { final TargetInfo ti = mChooserListAdapter.targetInfoForPosition( holder.getItemIndex(column), true); // This should always be the case for non-DS targets, check for sanity if (ti instanceof DisplayResolveInfo) { v.setOnLongClickListener(v1 -> { showTargetDetails((DisplayResolveInfo) ti); } return true; }); } } holder.addView(i, v); Loading
core/java/com/android/internal/app/ChooserStackedAppDialogFragment.java +19 −33 Original line number Diff line number Diff line Loading @@ -17,64 +17,50 @@ package com.android.internal.app; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.DialogFragment; import android.content.DialogInterface; import android.content.res.Configuration; import android.os.Bundle; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; import android.os.UserHandle; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.MultiDisplayResolveInfo; /** * Shows individual actions for a "stacked" app target - such as an app with multiple posting * streams represented in the Sharesheet. */ public class ChooserStackedAppDialogFragment extends DialogFragment public class ChooserStackedAppDialogFragment extends ChooserTargetActionsDialogFragment implements DialogInterface.OnClickListener { private static final String TITLE_KEY = "title"; private static final String PINNED_KEY = "pinned"; private MultiDisplayResolveInfo mTargetInfos; private CharSequence[] mLabels; private MultiDisplayResolveInfo mMultiDisplayResolveInfo; private int mParentWhich; public ChooserStackedAppDialogFragment() { } public ChooserStackedAppDialogFragment(CharSequence title, MultiDisplayResolveInfo targets, CharSequence[] labels, int parentWhich) { Bundle args = new Bundle(); args.putCharSequence(TITLE_KEY, title); mTargetInfos = targets; mLabels = labels; public ChooserStackedAppDialogFragment(MultiDisplayResolveInfo targets, int parentWhich, UserHandle userHandle) { super(targets.getTargets(), userHandle); mMultiDisplayResolveInfo = targets; mParentWhich = parentWhich; setArguments(args); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Bundle args = getArguments(); return new Builder(getContext()) .setCancelable(true) .setItems(mLabels, this) .setTitle(args.getCharSequence(TITLE_KEY)) .create(); protected CharSequence getItemLabel(DisplayResolveInfo dri) { final PackageManager pm = getContext().getPackageManager(); return dri.getResolveInfo().loadLabel(pm); } @Override public void onClick(DialogInterface dialog, int which) { final Bundle args = getArguments(); mTargetInfos.setSelected(which); ((ChooserActivity) getActivity()).startSelected(mParentWhich, false, true); dismiss(); protected Drawable getItemIcon(DisplayResolveInfo dri) { // Show no icon for the group disambig dialog, null hides the imageview return null; } @Override public void onConfigurationChanged(Configuration newConfig) { // Dismiss on config changed (eg: rotation) // TODO: Maintain state on config change super.onConfigurationChanged(newConfig); public void onClick(DialogInterface dialog, int which) { mMultiDisplayResolveInfo.setSelected(which); ((ChooserActivity) getActivity()).startSelected(mParentWhich, false, true); dismiss(); } }
core/java/com/android/internal/app/ResolverTargetActionsDialogFragment.java→core/java/com/android/internal/app/ChooserTargetActionsDialogFragment.java +173 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,10 @@ import static android.content.Context.ACTIVITY_SERVICE; import static com.android.internal.app.ResolverListAdapter.ResolveInfoPresentationGetter; import static java.util.stream.Collectors.toList; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AlertDialog.Builder; import android.app.Dialog; Loading @@ -30,12 +34,18 @@ import android.content.DialogInterface; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.util.Pair; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.R; import com.android.internal.app.chooser.DisplayResolveInfo; import com.android.internal.app.chooser.TargetInfo; import java.util.ArrayList; import java.util.List; Loading @@ -43,16 +53,16 @@ import java.util.List; /** * Shows a dialog with actions to take on a chooser target. */ public class ResolverTargetActionsDialogFragment extends DialogFragment public class ChooserTargetActionsDialogFragment extends DialogFragment implements DialogInterface.OnClickListener { private List<DisplayResolveInfo> mTargetInfos = new ArrayList<>(); private UserHandle mUserHandle; protected List<DisplayResolveInfo> mTargetInfos = new ArrayList<>(); protected UserHandle mUserHandle; public ResolverTargetActionsDialogFragment() { public ChooserTargetActionsDialogFragment() { } public ResolverTargetActionsDialogFragment(List<DisplayResolveInfo> targets, public ChooserTargetActionsDialogFragment(List<DisplayResolveInfo> targets, UserHandle userHandle) { mUserHandle = userHandle; mTargetInfos = targets; Loading @@ -60,34 +70,47 @@ public class ResolverTargetActionsDialogFragment extends DialogFragment @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final Bundle args = getArguments(); final PackageManager pm = getContext().getPackageManager(); // Pin item for each sub-item CharSequence[] items = new CharSequence[mTargetInfos.size()]; for (int i = 0; i < mTargetInfos.size(); i++) { final TargetInfo ti = mTargetInfos.get(i); final CharSequence label = ti.getResolveInfo().loadLabel(pm); items[i] = ti.isPinned() ? getResources().getString(R.string.unpin_specific_target, label) : getResources().getString(R.string.pin_specific_target, label); } // Use the matching application icon and label for the title, any TargetInfo will do final ActivityManager am = (ActivityManager) getContext() .getSystemService(ACTIVITY_SERVICE); final int iconDpi = am.getLauncherLargeIconDensity(); final ResolveInfoPresentationGetter pg = new ResolveInfoPresentationGetter(getContext(), iconDpi, mTargetInfos.get(0).getResolveInfo()); // Fetch UI details from target info List<Pair<CharSequence, Drawable>> items = mTargetInfos.stream().map(dri -> { return new Pair<>(getItemLabel(dri), getItemIcon(dri)); }).collect(toList()); final ResolveInfoPresentationGetter pg = getProvidingAppPresentationGetter(); return new Builder(getContext()) .setTitle(pg.getLabel()) .setIcon(pg.getIcon(mUserHandle)) .setCancelable(true) .setItems(items, this) .setAdapter(getAdapterForContent(items), this) .create(); } protected ArrayAdapter<Pair<CharSequence, Drawable>> getAdapterForContent( List<Pair<CharSequence, Drawable>> items) { return new ArrayAdapter<Pair<CharSequence, Drawable>>(getContext(), R.layout.chooser_dialog_item, R.id.text, items) { @Override public View getView(int position, View convertView, ViewGroup parent) { View v = super.getView(position, convertView, parent); // super recycles views TextView label = v.findViewById(R.id.text); ImageView icon = v.findViewById(R.id.icon); Pair<CharSequence, Drawable> pair = getItem(position); label.setText(pair.first); // Hide icon view if one isn't available if (pair.second == null) { icon.setVisibility(View.GONE); } else { icon.setImageDrawable(pair.second); icon.setVisibility(View.VISIBLE); } return v; } }; } @Override public void onClick(DialogInterface dialog, int which) { pinComponent(mTargetInfos.get(which).getResolvedComponentName()); Loading @@ -106,6 +129,39 @@ public class ResolverTargetActionsDialogFragment extends DialogFragment } } private Drawable getPinIcon(boolean isPinned) { return isPinned ? getContext().getDrawable(R.drawable.ic_close) : getContext().getDrawable(R.drawable.ic_chooser_pin_dialog); } private CharSequence getPinLabel(boolean isPinned, CharSequence targetLabel) { return isPinned ? getResources().getString(R.string.unpin_specific_target, targetLabel) : getResources().getString(R.string.pin_specific_target, targetLabel); } @NonNull protected CharSequence getItemLabel(DisplayResolveInfo dri) { final PackageManager pm = getContext().getPackageManager(); return getPinLabel(dri.isPinned(), dri.getResolveInfo().loadLabel(pm)); } @Nullable protected Drawable getItemIcon(DisplayResolveInfo dri) { return getPinIcon(dri.isPinned()); } private ResolveInfoPresentationGetter getProvidingAppPresentationGetter() { final ActivityManager am = (ActivityManager) getContext() .getSystemService(ACTIVITY_SERVICE); final int iconDpi = am.getLauncherLargeIconDensity(); // Use the matching application icon and label for the title, any TargetInfo will do return new ResolveInfoPresentationGetter(getContext(), iconDpi, mTargetInfos.get(0).getResolveInfo()); } @Override public void onConfigurationChanged(Configuration newConfig) { // Dismiss on config changed (eg: rotation) Loading
core/res/res/drawable/ic_chooser_pin_dialog.xml 0 → 100644 +25 −0 Original line number Diff line number Diff line <!-- ~ Copyright (C) 2020 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:pathData="M14,4v5c0,1.12 0.37,2.16 1,3H9c0.65,-0.86 1,-1.9 1,-3V4H14M17,2H7C6.45,2 6,2.45 6,3c0,0.55 0.45,1 1,1c0,0 0,0 0,0l1,0v5c0,1.66 -1.34,3 -3,3v2h5.97v7l1,1l1,-1v-7H19v-2c0,0 0,0 0,0c-1.66,0 -3,-1.34 -3,-3V4l1,0c0,0 0,0 0,0c0.55,0 1,-0.45 1,-1C18,2.45 17.55,2 17,2L17,2z" android:fillColor="#FF000000"/> </vector>
core/res/res/layout/chooser_dialog_item.xml 0 → 100644 +44 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- ~ Copyright (C) 2020 The Android Open Source Project ~ ~ Licensed under the Apache License, Version 2.0 (the "License"); ~ you may not use this file except in compliance with the License. ~ You may obtain a copy of the License at ~ ~ http://www.apache.org/licenses/LICENSE-2.0 ~ ~ Unless required by applicable law or agreed to in writing, software ~ distributed under the License is distributed on an "AS IS" BASIS, ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ~ See the License for the specific language governing permissions and ~ limitations under the License. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:gravity="start|center_vertical" android:paddingStart="?attr/dialogPreferredPadding" android:paddingEnd="?attr/dialogPreferredPadding" android:minHeight="48dp" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- Icon and text aligns with aligns with alert_dialog_title_material --> <ImageView android:id="@+id/icon" android:tint="?android:attr/textColorAlertDialogListItem" android:padding="4dp" android:layout_marginEnd="8dp" android:layout_width="32dp" android:layout_height="32dp"/> <!-- Using text style from select_dialog_item_material --> <TextView android:id="@+id/text" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:textColor="?android:attr/textColorAlertDialogListItem" android:lines="1" android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> No newline at end of file