/*
 * 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 android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
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.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.text.format.DateUtils;
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.TextView;

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

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.List;
import java.util.Objects;
import java.util.function.Predicate;
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 ProgressDialog progressDialog;
    private TextView titleView;

    private static final Long LEAST_SHOW_PROGRESS_TIME_MS = 300L;

    private static final String VERB_WRITE = "write";
    private static final String VERB_TRASH = "trash";
    private static final String VERB_UNTRASH = "untrash";
    private static final String VERB_FAVORITE = "favorite";
    private static final String VERB_UNFAVORITE = "unfavorite";
    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";

    @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);

        // 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;
        }

        progressDialog = new ProgressDialog(this);

        // 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
        switch (verb) {
            case VERB_FAVORITE:
            case VERB_UNFAVORITE: {
                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);
        new DescriptionTask(bodyView).execute(uris);

        final CharSequence message = resolveMessageText();
        if (!TextUtils.isEmpty(message)) {
            final TextView messageView = bodyView.requireViewById(R.id.message);
            messageView.setVisibility(View.VISIBLE);
            messageView.setText(message);
        }

        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(resolveTitleText());
        builder.setPositiveButton(R.string.allow, this::onPositiveAction);
        builder.setNegativeButton(R.string.deny, this::onNegativeAction);
        builder.setCancelable(false);
        builder.setView(bodyView);

        final AlertDialog dialog = builder.show();
        final WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
        params.width = getResources().getDimensionPixelSize(R.dimen.permission_dialog_width);
        dialog.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(dialog.getWindow().getDecorView(), (view) -> {
            return (view instanceof TextView) && view.isImportantForAccessibility();
        });
    }

    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);
        }

        progressDialog.show();
        final long startTime = System.currentTimeMillis();
        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);
                // Don't dismiss the progress dialog too quick, it will cause bad UX.
                final long duration = System.currentTimeMillis() - startTime;
                if (duration > LEAST_SHOW_PROGRESS_TIME_MS) {
                    progressDialog.dismiss();
                    finish();
                } else {
                    Handler handler = new Handler(getMainLooper());
                    handler.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;
    }

    /**
     * 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 dialog message string to be displayed to the user, if any.
     * All arguments have been bound and this string is ready to be displayed.
     */
    private @Nullable CharSequence resolveMessageText() {
        final String resName = "permission_" + verb + "_" + data + "_info";
        final int resId = getResources().getIdentifier(resName, "plurals",
                getResources().getResourcePackageName(R.string.app_label));
        if (resId != 0) {
            final int count = uris.size();
            final long durationMillis = (values.getAsLong(MediaColumns.DATE_EXPIRES) * 1000)
                    - System.currentTimeMillis();
            final long durationDays = (durationMillis + DateUtils.DAY_IN_MILLIS)
                    / DateUtils.DAY_IN_MILLIS;
            final CharSequence text = getResources().getQuantityText(resId, count);
            return TextUtils.expandTemplate(text, label, String.valueOf(count),
                    String.valueOf(durationDays));
        } else {
            // Only some actions have a secondary message string; it's okay if
            // there isn't one defined
            return null;
        }
    }

    private @NonNull CharSequence resolvePositiveText() {
        final String resName = "permission_" + verb + "_grant";
        final int resId = getResources().getIdentifier(resName, "string",
                getResources().getResourcePackageName(R.string.app_label));
        return getResources().getText(resId);
    }

    private @NonNull CharSequence resolveNegativeText() {
        final String resName = "permission_" + verb + "_deny";
        final int resId = getResources().getIdentifier(resName, "string",
                getResources().getResourcePackageName(R.string.app_label));
        return getResources().getText(resId);
    }

    /**
     * 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 static final int MAX_THUMBS = 3;

        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) {
                // 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);
                loadFlags |= Description.LOAD_FULL;
            } 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);
                }
            }

            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.
         */
        private void bindAsFull(@NonNull Description result) {
            final ImageView thumbFull = bodyView.requireViewById(R.id.thumb_full);
            result.bindFull(thumbFull);
        }

        /**
         * Bind dialog as a list of multiple thumbnails.
         */
        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);

                // 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);
            }

            // 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);
                desc.bindThumbnail(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++) {
                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;
                }
            }

            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 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);
            }
        }

        public boolean isVisual() {
            return thumbnail != null || full != 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);
        }
    }

    /**
     * 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);
            }
        }
    }
}
