Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36dc1778 authored by Jeff DeCew's avatar Jeff DeCew Committed by Automerger Merge Worker
Browse files

Merge "Use ImageResolver for BigPictureStyle when using BigPicture" into sc-dev am: 7e702617

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

Change-Id: If64e99258f9507bf743458bded305ff24c1201d3
parents bd763ee8 7e702617
Loading
Loading
Loading
Loading
+105 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.internal.widget;

import android.annotation.AttrRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StyleRes;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
import android.widget.RemoteViews;

import java.io.IOException;

/**
 * An ImageView used by BigPicture Notifications to correctly resolve the Uri in an Icon using the
 * LocalImageResolver, allowing it to support animated drawables which are not supported by
 * Icon.loadDrawable().
 */
@RemoteViews.RemoteView
public class BigPictureNotificationImageView extends ImageView {

    private static final String TAG = BigPictureNotificationImageView.class.getSimpleName();

    public BigPictureNotificationImageView(@NonNull Context context) {
        super(context);
    }

    public BigPictureNotificationImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public BigPictureNotificationImageView(@NonNull Context context, @Nullable AttributeSet attrs,
            @AttrRes int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public BigPictureNotificationImageView(@NonNull Context context, @Nullable AttributeSet attrs,
            @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    @android.view.RemotableViewMethod(asyncImpl = "setImageURIAsync")
    public void setImageURI(@Nullable Uri uri) {
        setImageDrawable(loadImage(uri));
    }

    /** @hide **/
    public Runnable setImageURIAsync(@Nullable Uri uri) {
        final Drawable drawable = loadImage(uri);
        return () -> setImageDrawable(drawable);
    }

    @Override
    @android.view.RemotableViewMethod(asyncImpl = "setImageIconAsync")
    public void setImageIcon(@Nullable Icon icon) {
        setImageDrawable(loadImage(icon));
    }

    /** @hide **/
    public Runnable setImageIconAsync(@Nullable Icon icon) {
        final Drawable drawable = loadImage(icon);
        return () -> setImageDrawable(drawable);
    }

    private Drawable loadImage(Uri uri) {
        if (uri == null) return null;
        try {
            return LocalImageResolver.resolveImage(uri, mContext);
        } catch (IOException ex) {
            Log.d(TAG, "Resolve failed from " + uri, ex);
            return null;
        }
    }

    private Drawable loadImage(Icon icon) {
        if (icon == null) return null;
        try {
            return LocalImageResolver.resolveImage(icon, mContext);
        } catch (IOException ex) {
            Log.d(TAG, "Resolve failed from " + icon, ex);
            return null;
        }
    }
}
+36 −1
Original line number Diff line number Diff line
@@ -16,10 +16,11 @@

package com.android.internal.widget;

import android.annotation.Nullable;
import android.content.Context;
import android.graphics.ImageDecoder;
import android.graphics.drawable.AnimatedImageDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.util.Size;

@@ -31,6 +32,9 @@ public class LocalImageResolver {

    private static final int MAX_SAFE_ICON_SIZE_PX = 480;

    /**
     * Resolve an image from the given Uri using {@link ImageDecoder}
     */
    public static Drawable resolveImage(Uri uri, Context context) throws IOException {
        final ImageDecoder.Source source =
                ImageDecoder.createSource(context.getContentResolver(), uri);
@@ -39,6 +43,25 @@ public class LocalImageResolver {
        return drawable;
    }

    /**
     * Get the drawable from Icon using {@link ImageDecoder} if it contains a Uri, or
     * using {@link Icon#loadDrawable(Context)} otherwise.  This will correctly apply the Icon's,
     * tint, if present, to the drawable.
     */
    public static Drawable resolveImage(Icon icon, Context context) throws IOException {
        Uri uri = getResolvableUri(icon);
        if (uri != null) {
            Drawable result = resolveImage(uri, context);
            if (icon.hasTint()) {
                result.mutate();
                result.setTintList(icon.getTintList());
                result.setTintBlendMode(icon.getTintBlendMode());
            }
            return result;
        }
        return icon.loadDrawable(context);
    }

    public static Drawable resolveImage(Uri uri, Context context, int maxWidth, int maxHeight)
            throws IOException {
        final ImageDecoder.Source source =
@@ -73,4 +96,16 @@ public class LocalImageResolver {
                : 1.0;
        decoder.setTargetSampleSize(getPowerOfTwoForSampleRatio(ratio));
    }

    /**
     * Gets the Uri for this icon, assuming the icon can be treated as a pure Uri.  Null otherwise.
     */
    @Nullable
    public static Uri getResolvableUri(@Nullable Icon icon) {
        if (icon == null || (icon.getType() != Icon.TYPE_URI
                && icon.getType() != Icon.TYPE_URI_ADAPTIVE_BITMAP)) {
            return null;
        }
        return icon.getUri();
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@
            <include layout="@layout/notification_template_text_multiline" />
        </LinearLayout>

        <ImageView
        <com.android.internal.widget.BigPictureNotificationImageView
            android:id="@+id/big_picture"
            android:layout_width="match_parent"
            android:layout_height="0dp"
+12 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.annotation.ColorInt;
import android.annotation.DrawableRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
import android.content.Context;
@@ -336,7 +337,7 @@ public final class Icon implements Parcelable {
     */
    public Drawable loadDrawable(Context context) {
        final Drawable result = loadDrawableInner(context);
        if (result != null && (mTintList != null || mBlendMode != DEFAULT_BLEND_MODE)) {
        if (result != null && hasTint()) {
            result.mutate();
            result.setTintList(mTintList);
            result.setTintBlendMode(mBlendMode);
@@ -762,6 +763,11 @@ public final class Icon implements Parcelable {
        return this;
    }

    /** @hide */
    public @Nullable ColorStateList getTintList() {
        return mTintList;
    }

    /**
     * Store a blending mode to use whenever this Icon is drawn.
     *
@@ -784,6 +790,11 @@ public final class Icon implements Parcelable {
        return this;
    }

    /** @hide */
    public @NonNull BlendMode getTintBlendMode() {
        return mBlendMode;
    }

    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public boolean hasTint() {