/*
 * Copyright (C) 2018 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.
 */

package com.android.providers.media;

import static com.android.providers.media.MediaProvider.AUDIO_MEDIA_ID;
import static com.android.providers.media.MediaProvider.IMAGES_MEDIA_ID;
import static com.android.providers.media.MediaProvider.VIDEO_MEDIA_ID;
import static com.android.providers.media.MediaProvider.collectUris;
import static com.android.providers.media.util.DatabaseUtils.getAsBoolean;
import static com.android.providers.media.util.Logging.TAG;
import static com.android.providers.media.util.PermissionUtils.checkPermissionAccessMediaLocation;
import static com.android.providers.media.util.PermissionUtils.checkPermissionManageMedia;
import static com.android.providers.media.util.PermissionUtils.checkPermissionManager;
import static com.android.providers.media.util.PermissionUtils.checkPermissionReadStorage;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.ImageDecoder;
import android.graphics.ImageDecoder.ImageInfo;
import android.graphics.ImageDecoder.Source;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;

import com.android.providers.media.MediaProvider.LocalUriMatcher;
import com.android.providers.media.util.Metrics;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;

/**
 * Permission dialog that asks for user confirmation before performing a
 * specific action, such as granting access for a narrow set of media files to
 * the calling app.
 *
 * @see MediaStore#createWriteRequest
 * @see MediaStore#createTrashRequest
 * @see MediaStore#createFavoriteRequest
 * @see MediaStore#createDeleteRequest
 */
public class PermissionActivity extends Activity {
    // TODO: narrow metrics to specific verb that was requested

    public static final int REQUEST_CODE = 42;

    private List<Uri> uris;
    private ContentValues values;

    private CharSequence label;
    private String verb;
    private String data;
    private String volumeName;
    private ApplicationInfo appInfo;

    private AlertDialog actionDialog;
    private AsyncTask<Void, Void, Void> positiveActionTask;
    private Dialog progressDialog;
    private TextView titleView;
    private Handler mHandler;
    private Runnable mShowProgressDialogRunnable = () -> {
        // We will show the progress dialog, add the dim effect back.
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        progressDialog.show();
    };

    private static final Long LEAST_SHOW_PROGRESS_TIME_MS = 300L;
    private static final Long BEFORE_SHOW_PROGRESS_TIME_MS = 300L;

    @VisibleForTesting
    static final String VERB_WRITE = "write";
    @VisibleForTesting
    static final String VERB_TRASH = "trash";
    @VisibleForTesting
    static final String VERB_FAVORITE = "favorite";
    @VisibleForTesting
    static final String VERB_UNFAVORITE = "unfavorite";

    private static final String VERB_UNTRASH = "untrash";
    private static final String VERB_DELETE = "delete";

    private static final String DATA_AUDIO = "audio";
    private static final String DATA_VIDEO = "video";
    private static final String DATA_IMAGE = "image";
    private static final String DATA_GENERIC = "generic";

    // Use to sort the thumbnails.
    private static final int ORDER_IMAGE = 1;
    private static final int ORDER_VIDEO = 2;
    private static final int ORDER_AUDIO = 3;
    private static final int ORDER_GENERIC = 4;

    private static final int MAX_THUMBS = 3;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Strategy borrowed from PermissionController
        getWindow().addSystemFlags(
                WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
        setFinishOnTouchOutside(false);
        // remove the dim effect
        // We may not show the progress dialog, if we don't remove the dim effect,
        // it may have flicker.
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
        getWindow().setDimAmount(0.0f);


        // All untrusted input values here were validated when generating the
        // original PendingIntent
        try {
            uris = collectUris(getIntent().getExtras().getParcelable(MediaStore.EXTRA_CLIP_DATA));
            values = getIntent().getExtras().getParcelable(MediaStore.EXTRA_CONTENT_VALUES);

            appInfo = resolveCallingAppInfo();
            label = resolveAppLabel(appInfo);
            verb = resolveVerb();
            data = resolveData();
            volumeName = MediaStore.getVolumeName(uris.get(0));
        } catch (Exception e) {
            Log.w(TAG, e);
            finish();
            return;
        }

        mHandler = new Handler(getMainLooper());
        // Create Progress dialog
        createProgressDialog();

        if (!shouldShowActionDialog(this, -1 /* pid */, appInfo.uid, getCallingPackage(),
                null /* attributionTag */, verb)) {
            onPositiveAction(null, 0);
            return;
        }

        // Kick off async loading of description to show in dialog
        final View bodyView = getLayoutInflater().inflate(R.layout.permission_body, null, false);
        handleImageViewVisibility(bodyView, uris);
        new DescriptionTask(bodyView).execute(uris);

        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        // We set the title in message so that the text doesn't get truncated
        builder.setMessage(resolveTitleText());
        builder.setPositiveButton(R.string.allow, this::onPositiveAction);
        builder.setNegativeButton(R.string.deny, this::onNegativeAction);
        builder.setCancelable(false);
        builder.setView(bodyView);

        actionDialog = builder.show();

        // The title is being set as a message above.
        // We need to style it like the default AlertDialog title
        TextView dialogMessage = (TextView) actionDialog.findViewById(
                android.R.id.message);
        if (dialogMessage != null) {
            dialogMessage.setTextAppearance(R.style.PermissionAlertDialogTitle);
        } else {
            Log.w(TAG, "Couldn't find message element");
        }

        final WindowManager.LayoutParams params = actionDialog.getWindow().getAttributes();
        params.width = getResources().getDimensionPixelSize(R.dimen.permission_dialog_width);
        actionDialog.getWindow().setAttributes(params);

        // Hunt around to find the title of our newly created dialog so we can
        // adjust accessibility focus once descriptions have been loaded
        titleView = (TextView) findViewByPredicate(actionDialog.getWindow().getDecorView(),
                (view) -> {
                    return (view instanceof TextView) && view.isImportantForAccessibility();
                });
    }

    private void createProgressDialog() {
        final ProgressBar progressBar = new ProgressBar(this);
        final int padding = getResources().getDimensionPixelOffset(R.dimen.dialog_space);

        progressBar.setIndeterminate(true);
        progressBar.setPadding(0, padding / 2, 0, padding);
        progressDialog = new AlertDialog.Builder(this)
                .setTitle(resolveProgressMessageText())
                .setView(progressBar)
                .setCancelable(false)
                .create();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacks(mShowProgressDialogRunnable);
        // Cancel and interrupt the AsyncTask of the positive action. This avoids
        // calling the old activity during "onPostExecute", but the AsyncTask could
        // still finish its background task. For now we are ok with:
        // 1. the task potentially runs again after the configuration is changed
        // 2. the task completed successfully, but the activity doesn't return
        // the response.
        if (positiveActionTask != null) {
            positiveActionTask.cancel(true /* mayInterruptIfRunning */);
        }
        // Dismiss the dialogs to avoid the window is leaked
        if (actionDialog != null) {
            actionDialog.dismiss();
        }
        if (progressDialog != null) {
            progressDialog.dismiss();
        }
    }

    private void onPositiveAction(@Nullable DialogInterface dialog, int which) {
        // Disable the buttons
        if (dialog != null) {
            ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
            ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false);
        }

        final long startTime = System.currentTimeMillis();

        mHandler.postDelayed(mShowProgressDialogRunnable, BEFORE_SHOW_PROGRESS_TIME_MS);

        positiveActionTask = new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                Log.d(TAG, "User allowed grant for " + uris);
                Metrics.logPermissionGranted(volumeName, appInfo.uid,
                        getCallingPackage(), uris.size());
                try {
                    switch (getIntent().getAction()) {
                        case MediaStore.CREATE_WRITE_REQUEST_CALL: {
                            for (Uri uri : uris) {
                                grantUriPermission(getCallingPackage(), uri,
                                        Intent.FLAG_GRANT_READ_URI_PERMISSION
                                                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                            }
                            break;
                        }
                        case MediaStore.CREATE_TRASH_REQUEST_CALL:
                        case MediaStore.CREATE_FAVORITE_REQUEST_CALL: {
                            final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
                            for (Uri uri : uris) {
                                ops.add(ContentProviderOperation.newUpdate(uri)
                                        .withValues(values)
                                        .withExtra(MediaStore.QUERY_ARG_ALLOW_MOVEMENT, true)
                                        .withExceptionAllowed(true)
                                        .build());
                            }
                            getContentResolver().applyBatch(MediaStore.AUTHORITY, ops);
                            break;
                        }
                        case MediaStore.CREATE_DELETE_REQUEST_CALL: {
                            final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
                            for (Uri uri : uris) {
                                ops.add(ContentProviderOperation.newDelete(uri)
                                        .withExceptionAllowed(true)
                                        .build());
                            }
                            getContentResolver().applyBatch(MediaStore.AUTHORITY, ops);
                            break;
                        }
                    }
                } catch (Exception e) {
                    Log.w(TAG, e);
                }

                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                setResult(Activity.RESULT_OK);
                mHandler.removeCallbacks(mShowProgressDialogRunnable);

                if (!progressDialog.isShowing()) {
                    finish();
                } else {
                    // Don't dismiss the progress dialog too quick, it will cause bad UX.
                    final long duration =
                            System.currentTimeMillis() - startTime - BEFORE_SHOW_PROGRESS_TIME_MS;
                    if (duration > LEAST_SHOW_PROGRESS_TIME_MS) {
                        progressDialog.dismiss();
                        finish();
                    } else {
                        mHandler.postDelayed(() -> {
                            progressDialog.dismiss();
                            finish();
                        }, LEAST_SHOW_PROGRESS_TIME_MS - duration);
                    }
                }
            }
        }.execute();
    }

    private void onNegativeAction(DialogInterface dialog, int which) {
        new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                Log.d(TAG, "User declined request for " + uris);
                Metrics.logPermissionDenied(volumeName, appInfo.uid, getCallingPackage(),
                        1);
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                setResult(Activity.RESULT_CANCELED);
                finish();
            }
        }.execute();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // Strategy borrowed from PermissionController
        return keyCode == KeyEvent.KEYCODE_BACK;
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        // Strategy borrowed from PermissionController
        return keyCode == KeyEvent.KEYCODE_BACK;
    }

    @VisibleForTesting
    static boolean shouldShowActionDialog(@NonNull Context context, int pid, int uid,
            @NonNull String packageName, @Nullable String attributionTag, @NonNull String verb) {
        // Favorite-related requests are automatically granted for now; we still
        // make developers go through this no-op dialog flow to preserve our
        // ability to start prompting in the future
        if (TextUtils.equals(VERB_FAVORITE, verb) || TextUtils.equals(VERB_UNFAVORITE, verb)) {
            return false;
        }

        // check READ_EXTERNAL_STORAGE and MANAGE_EXTERNAL_STORAGE permissions
        if (!checkPermissionReadStorage(context, pid, uid, packageName, attributionTag)
                && !checkPermissionManager(context, pid, uid, packageName, attributionTag)) {
            Log.d(TAG, "No permission READ_EXTERNAL_STORAGE or MANAGE_EXTERNAL_STORAGE");
            return true;
        }
        // check MANAGE_MEDIA permission
        if (!checkPermissionManageMedia(context, pid, uid, packageName, attributionTag)) {
            Log.d(TAG, "No permission MANAGE_MEDIA");
            return true;
        }

        // if verb is write, check ACCESS_MEDIA_LOCATION permission
        if (TextUtils.equals(verb, VERB_WRITE) && !checkPermissionAccessMediaLocation(context, pid,
                uid, packageName, attributionTag)) {
            Log.d(TAG, "No permission ACCESS_MEDIA_LOCATION");
            return true;
        }
        return false;
    }

    private void handleImageViewVisibility(View bodyView, List<Uri> uris) {
        if (uris.isEmpty()) {
            return;
        }
        if (uris.size() == 1) {
            // Set visible to the thumb_full to avoid the size
            // changed of the dialog in full decoding.
            final ImageView thumbFull = bodyView.requireViewById(R.id.thumb_full);
            thumbFull.setVisibility(View.VISIBLE);
        } else {
            // If the size equals 2, we will remove thumb1 later.
            // Set visible to the thumb2 and thumb3 first to avoid
            // the size changed of the dialog.
            ImageView thumb = bodyView.requireViewById(R.id.thumb2);
            thumb.setVisibility(View.VISIBLE);
            thumb = bodyView.requireViewById(R.id.thumb3);
            thumb.setVisibility(View.VISIBLE);
            // If the count of thumbs equals to MAX_THUMBS, set visible to thumb1.
            if (uris.size() == MAX_THUMBS) {
                thumb = bodyView.requireViewById(R.id.thumb1);
                thumb.setVisibility(View.VISIBLE);
            } else if (uris.size() > MAX_THUMBS) {
                // If the count is larger than MAX_THUMBS, set visible to
                // thumb_more_container.
                final View container = bodyView.requireViewById(R.id.thumb_more_container);
                container.setVisibility(View.VISIBLE);
            }
        }
    }

    /**
     * Resolve a label that represents the app denoted by given {@link ApplicationInfo}.
     */
    private @NonNull CharSequence resolveAppLabel(final ApplicationInfo ai)
            throws NameNotFoundException {
        final PackageManager pm = getPackageManager();
        final CharSequence callingLabel = pm.getApplicationLabel(ai);
        if (TextUtils.isEmpty(callingLabel)) {
            throw new NameNotFoundException("Missing calling package");
        }

        return callingLabel;
    }

    /**
     * Resolve the application info of the calling app.
     */
    private @NonNull ApplicationInfo resolveCallingAppInfo() throws NameNotFoundException {
        final String callingPackage = getCallingPackage();
        if (TextUtils.isEmpty(callingPackage)) {
            throw new NameNotFoundException("Missing calling package");
        }

        return getPackageManager().getApplicationInfo(callingPackage, 0);
    }

    private @NonNull String resolveVerb() {
        switch (getIntent().getAction()) {
            case MediaStore.CREATE_WRITE_REQUEST_CALL:
                return VERB_WRITE;
            case MediaStore.CREATE_TRASH_REQUEST_CALL:
                return getAsBoolean(values, MediaColumns.IS_TRASHED, false)
                        ? VERB_TRASH : VERB_UNTRASH;
            case MediaStore.CREATE_FAVORITE_REQUEST_CALL:
                return getAsBoolean(values, MediaColumns.IS_FAVORITE, false)
                        ? VERB_FAVORITE : VERB_UNFAVORITE;
            case MediaStore.CREATE_DELETE_REQUEST_CALL:
                return VERB_DELETE;
            default:
                throw new IllegalArgumentException("Invalid action: " + getIntent().getAction());
        }
    }

    /**
     * Resolve what kind of data this permission request is asking about. If the
     * requested data is of mixed types, this returns {@link #DATA_GENERIC}.
     */
    private @NonNull String resolveData() {
        final LocalUriMatcher matcher = new LocalUriMatcher(MediaStore.AUTHORITY);
        final int firstMatch = matcher.matchUri(uris.get(0), false);
        for (int i = 1; i < uris.size(); i++) {
            final int match = matcher.matchUri(uris.get(i), false);
            if (match != firstMatch) {
                // Any mismatch means we need to use generic strings
                return DATA_GENERIC;
            }
        }
        switch (firstMatch) {
            case AUDIO_MEDIA_ID: return DATA_AUDIO;
            case VIDEO_MEDIA_ID: return DATA_VIDEO;
            case IMAGES_MEDIA_ID: return DATA_IMAGE;
            default: return DATA_GENERIC;
        }
    }

    /**
     * Resolve the dialog title string to be displayed to the user. All
     * arguments have been bound and this string is ready to be displayed.
     */
    private @Nullable CharSequence resolveTitleText() {
        final String resName = "permission_" + verb + "_" + data;
        final int resId = getResources().getIdentifier(resName, "plurals",
                getResources().getResourcePackageName(R.string.app_label));
        if (resId != 0) {
            final int count = uris.size();
            final CharSequence text = getResources().getQuantityText(resId, count);
            return TextUtils.expandTemplate(text, label, String.valueOf(count));
        } else {
            // We always need a string to prompt the user with
            throw new IllegalStateException("Invalid resource: " + resName);
        }
    }

    /**
     * Resolve the progress message string to be displayed to the user. All
     * arguments have been bound and this string is ready to be displayed.
     */
    private @Nullable CharSequence resolveProgressMessageText() {
        final String resName = "permission_progress_" + verb + "_" + data;
        final int resId = getResources().getIdentifier(resName, "plurals",
                getResources().getResourcePackageName(R.string.app_label));
        if (resId != 0) {
            final int count = uris.size();
            final CharSequence text = getResources().getQuantityText(resId, count);
            return TextUtils.expandTemplate(text, String.valueOf(count));
        } else {
            // Only some actions have a progress message string; it's okay if
            // there isn't one defined
            return null;
        }
    }

    /**
     * Recursively walk the given view hierarchy looking for the first
     * {@link View} which matches the given predicate.
     */
    private static @Nullable View findViewByPredicate(@NonNull View root,
            @NonNull Predicate<View> predicate) {
        if (predicate.test(root)) {
            return root;
        }
        if (root instanceof ViewGroup) {
            final ViewGroup group = (ViewGroup) root;
            for (int i = 0; i < group.getChildCount(); i++) {
                final View res = findViewByPredicate(group.getChildAt(i), predicate);
                if (res != null) {
                    return res;
                }
            }
        }
        return null;
    }

    /**
     * Task that will load a set of {@link Description} to be eventually
     * displayed in the body of the dialog.
     */
    private class DescriptionTask extends AsyncTask<List<Uri>, Void, List<Description>> {
        private View bodyView;
        private Resources res;

        public DescriptionTask(@NonNull View bodyView) {
            this.bodyView = bodyView;
            this.res = bodyView.getContext().getResources();
        }

        @Override
        protected List<Description> doInBackground(List<Uri>... params) {
            final List<Uri> uris = params[0];
            final List<Description> res = new ArrayList<>();

            // If the size is zero, return the res directly.
            if (uris.isEmpty()) {
                return res;
            }

            // Default information that we'll load for each item
            int loadFlags = Description.LOAD_THUMBNAIL | Description.LOAD_CONTENT_DESCRIPTION;
            int neededThumbs = MAX_THUMBS;

            // If we're only asking for single item, load the full image
            if (uris.size() == 1) {
                loadFlags |= Description.LOAD_FULL;
            }

            // Sort the uris in DATA_GENERIC case (Image, Video, Audio, Others)
            if (TextUtils.equals(data, DATA_GENERIC) && uris.size() > 1) {
                final ToIntFunction<Uri> score = (uri) -> {
                    final LocalUriMatcher matcher = new LocalUriMatcher(MediaStore.AUTHORITY);
                    final int match = matcher.matchUri(uri, false);

                    switch (match) {
                        case AUDIO_MEDIA_ID: return ORDER_AUDIO;
                        case VIDEO_MEDIA_ID: return ORDER_VIDEO;
                        case IMAGES_MEDIA_ID: return ORDER_IMAGE;
                        default: return ORDER_GENERIC;
                    }
                };
                final Comparator<Uri> bestScore = (a, b) ->
                        score.applyAsInt(a) - score.applyAsInt(b);

                uris.sort(bestScore);
            }

            for (Uri uri : uris) {
                try {
                    final Description desc = new Description(bodyView.getContext(), uri, loadFlags);
                    res.add(desc);

                    // Once we've loaded enough information to bind our UI, we
                    // can skip loading data for remaining requested items, but
                    // we still need to create them to show the correct counts
                    if (desc.isVisual()) {
                        neededThumbs--;
                    }
                    if (neededThumbs == 0) {
                        loadFlags = 0;
                    }
                } catch (Exception e) {
                    // Keep rolling forward to try getting enough descriptions
                    Log.w(TAG, e);
                }
            }
            return res;
        }

        @Override
        protected void onPostExecute(List<Description> results) {
            // Decide how to bind results based on how many are visual
            final List<Description> visualResults = results.stream().filter(Description::isVisual)
                    .collect(Collectors.toList());
            if (results.size() == 1 && visualResults.size() == 1) {
                bindAsFull(results.get(0));
            } else if (!visualResults.isEmpty()) {
                bindAsThumbs(results, visualResults);
            } else {
                bindAsText(results);
            }

            // This is pretty hacky, but somehow our dynamic loading of content
            // can confuse accessibility focus, so refocus on the actual dialog
            // title to announce ourselves properly
            titleView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
        }

        /**
         * Bind dialog as a single full-bleed image. If there is no image, use
         * the icon of Mime type instead.
         */
        private void bindAsFull(@NonNull Description result) {
            final ImageView thumbFull = bodyView.requireViewById(R.id.thumb_full);
            if (result.full != null) {
                result.bindFull(thumbFull);
            } else {
                thumbFull.setScaleType(ImageView.ScaleType.FIT_CENTER);
                thumbFull.setBackground(new ColorDrawable(getColor(R.color.thumb_gray_color)));
                result.bindMimeIcon(thumbFull);
            }
        }

        /**
         * Bind dialog as a list of multiple thumbnails. If there is no thumbnail for some
         * items, use the icons of the MIME type instead.
         */
        private void bindAsThumbs(@NonNull List<Description> results,
                @NonNull List<Description> visualResults) {
            final List<ImageView> thumbs = new ArrayList<>();
            thumbs.add(bodyView.requireViewById(R.id.thumb1));
            thumbs.add(bodyView.requireViewById(R.id.thumb2));
            thumbs.add(bodyView.requireViewById(R.id.thumb3));

            // We're going to show the "more" tile when we can't display
            // everything requested, but we have at least one visual item
            final boolean showMore = (visualResults.size() != results.size())
                    || (visualResults.size() > MAX_THUMBS);
            if (showMore) {
                final View thumbMoreContainer = bodyView.requireViewById(R.id.thumb_more_container);
                final ImageView thumbMore = bodyView.requireViewById(R.id.thumb_more);
                final TextView thumbMoreText = bodyView.requireViewById(R.id.thumb_more_text);
                final View gradientView = bodyView.requireViewById(R.id.thumb_more_gradient);

                // Since we only want three tiles displayed maximum, swap out
                // the first tile for our "more" tile
                thumbs.remove(0);
                thumbs.add(thumbMore);

                final int shownCount = Math.min(visualResults.size(), MAX_THUMBS - 1);
                final int moreCount = results.size() - shownCount;
                final CharSequence moreText = TextUtils.expandTemplate(res.getQuantityText(
                        R.plurals.permission_more_thumb, moreCount), String.valueOf(moreCount));

                thumbMoreText.setText(moreText);
                thumbMoreContainer.setVisibility(View.VISIBLE);
                gradientView.setVisibility(View.VISIBLE);
            }

            // Trim off extra thumbnails from the front of our list, so that we
            // always bind any "more" item last
            while (thumbs.size() > visualResults.size()) {
                thumbs.remove(0);
            }

            // Finally we can bind all our thumbnails into place
            for (int i = 0; i < thumbs.size(); i++) {
                final Description desc = visualResults.get(i);
                final ImageView imageView = thumbs.get(i);
                if (desc.thumbnail != null) {
                    desc.bindThumbnail(imageView);
                } else {
                    desc.bindMimeIcon(imageView);
                }
            }
        }

        /**
         * Bind dialog as a list of text descriptions, typically when there's no
         * visual representation of the items.
         */
        private void bindAsText(@NonNull List<Description> results) {
            final List<CharSequence> list = new ArrayList<>();
            for (int i = 0; i < results.size(); i++) {
                if (TextUtils.isEmpty(results.get(i).contentDescription)) {
                    continue;
                }
                list.add(results.get(i).contentDescription);

                if (list.size() >= MAX_THUMBS && results.size() > list.size()) {
                    final int moreCount = results.size() - list.size();
                    final CharSequence moreText = TextUtils.expandTemplate(res.getQuantityText(
                            R.plurals.permission_more_text, moreCount), String.valueOf(moreCount));
                    list.add(moreText);
                    break;
                }
            }
            if (!list.isEmpty()) {
                final TextView text = bodyView.requireViewById(R.id.list);
                text.setText(TextUtils.join("\n", list));
                text.setVisibility(View.VISIBLE);
            }
        }
    }

    /**
     * Description of a single media item.
     */
    private static class Description {
        public @Nullable CharSequence contentDescription;
        public @Nullable Bitmap thumbnail;
        public @Nullable Bitmap full;
        public @Nullable Icon mimeIcon;

        public static final int LOAD_CONTENT_DESCRIPTION = 1 << 0;
        public static final int LOAD_THUMBNAIL = 1 << 1;
        public static final int LOAD_FULL = 1 << 2;

        public Description(Context context, Uri uri, int loadFlags) {
            final Resources res = context.getResources();
            final ContentResolver resolver = context.getContentResolver();

            try {
                // Load description first so that we'll always have something
                // textual to display in case we have image trouble below
                if ((loadFlags & LOAD_CONTENT_DESCRIPTION) != 0) {
                    try (Cursor c = resolver.query(uri,
                            new String[] { MediaColumns.DISPLAY_NAME }, null, null)) {
                        if (c.moveToFirst()) {
                            contentDescription = c.getString(0);
                        }
                    }
                }
                if ((loadFlags & LOAD_THUMBNAIL) != 0) {
                    final Size size = new Size(res.getDisplayMetrics().widthPixels,
                            res.getDisplayMetrics().widthPixels);
                    thumbnail = resolver.loadThumbnail(uri, size, null);
                }
                if ((loadFlags & LOAD_FULL) != 0) {
                    // Only offer full decodes when a supported file type;
                    // otherwise fall back to using thumbnail
                    final String mimeType = resolver.getType(uri);
                    if (ImageDecoder.isMimeTypeSupported(mimeType)) {
                        full = ImageDecoder.decodeBitmap(ImageDecoder.createSource(resolver, uri),
                                new Resizer(context.getResources().getDisplayMetrics()));
                    } else {
                        full = thumbnail;
                    }
                }
            } catch (IOException e) {
                Log.w(TAG, e);
                if (thumbnail == null && full == null) {
                    final String mimeType = resolver.getType(uri);
                    if (mimeType != null) {
                        mimeIcon = resolver.getTypeInfo(mimeType).getIcon();
                    }
                }
            }
        }

        public boolean isVisual() {
            return thumbnail != null || full != null || mimeIcon != null;
        }

        public void bindThumbnail(ImageView imageView) {
            Objects.requireNonNull(thumbnail);
            imageView.setImageBitmap(thumbnail);
            imageView.setContentDescription(contentDescription);
            imageView.setVisibility(View.VISIBLE);
            imageView.setClipToOutline(true);
        }

        public void bindFull(ImageView imageView) {
            Objects.requireNonNull(full);
            imageView.setImageBitmap(full);
            imageView.setContentDescription(contentDescription);
            imageView.setVisibility(View.VISIBLE);
        }

        public void bindMimeIcon(ImageView imageView) {
            Objects.requireNonNull(mimeIcon);
            imageView.setImageIcon(mimeIcon);
            imageView.setContentDescription(contentDescription);
            imageView.setVisibility(View.VISIBLE);
            imageView.setClipToOutline(true);
        }
    }

    /**
     * Utility that will speed up decoding of large images, since we never need
     * them to be larger than the screen dimensions.
     */
    private static class Resizer implements ImageDecoder.OnHeaderDecodedListener {
        private final int maxSize;

        public Resizer(DisplayMetrics metrics) {
            this.maxSize = Math.max(metrics.widthPixels, metrics.heightPixels);
        }

        @Override
        public void onHeaderDecoded(ImageDecoder decoder, ImageInfo info, Source source) {
            // We requested a rough thumbnail size, but the remote size may have
            // returned something giant, so defensively scale down as needed.
            final int widthSample = info.getSize().getWidth() / maxSize;
            final int heightSample = info.getSize().getHeight() / maxSize;
            final int sample = Math.max(widthSample, heightSample);
            if (sample > 1) {
                decoder.setTargetSampleSize(sample);
            }
        }
    }
}
