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

Commit 8ef48169 authored by Chris Antol's avatar Chris Antol Committed by Android (Google) Code Review
Browse files

Merge "Auto hide IllustrationPreference when lottie file is empty" into main

parents da577887 bcad6e27
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ android_library {
        "SettingsLibColor",
        "androidx.preference_preference",
        "lottie",
        "settingslib_illustrationpreference_flags_lib",
    ],

    sdk_version: "system_current",
@@ -31,3 +32,24 @@ android_library {
        "com.android.permission",
    ],
}

aconfig_declarations {
    name: "settingslib_illustrationpreference_flags",
    package: "com.android.settingslib.widget.flags",
    container: "system",
    srcs: [
        "aconfig/illustrationpreference.aconfig",
    ],
}

java_aconfig_library {
    name: "settingslib_illustrationpreference_flags_lib",
    aconfig_declarations: "settingslib_illustrationpreference_flags",

    min_sdk_version: "30",

    apex_available: [
        "//apex_available:platform",
        "com.android.permission",
    ],
}
+12 −0
Original line number Diff line number Diff line
package: "com.android.settingslib.widget.flags"
container: "system"

flag {
    name: "auto_hide_empty_lottie_res"
    namespace: "android_settings"
    description: "Hides IllustrationPreference when Lottie resource is an empty file"
    bug: "337873972"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
 No newline at end of file
+24 −2
Original line number Diff line number Diff line
@@ -39,12 +39,14 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;

import com.android.settingslib.widget.flags.Flags;
import com.android.settingslib.widget.preference.illustration.R;

import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.LottieDrawable;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
@@ -142,7 +144,7 @@ public class IllustrationPreference extends Preference {
        illustrationFrame.setLayoutParams(lp);

        illustrationView.setCacheComposition(mCacheComposition);
        handleImageWithAnimation(illustrationView);
        handleImageWithAnimation(illustrationView, illustrationFrame);
        handleImageFrameMaxHeight(backgroundView, illustrationView);

        if (mIsAutoScale) {
@@ -332,7 +334,8 @@ public class IllustrationPreference extends Preference {
        }
    }

    private void handleImageWithAnimation(LottieAnimationView illustrationView) {
    private void handleImageWithAnimation(LottieAnimationView illustrationView,
            ViewGroup container) {
        if (mImageDrawable != null) {
            resetAnimations(illustrationView);
            illustrationView.setImageDrawable(mImageDrawable);
@@ -356,6 +359,25 @@ public class IllustrationPreference extends Preference {
        }

        if (mImageResId > 0) {
            if (Flags.autoHideEmptyLottieRes()) {
                // Check if resource is empty
                try (InputStream is = illustrationView.getResources()
                        .openRawResource(mImageResId)) {
                    int check = is.read();
                    // -1 = end of stream. if first read is end of stream, then file is empty
                    if (check == -1) {
                        illustrationView.setVisibility(View.GONE);
                        container.setVisibility(View.GONE);
                        return;
                    }
                } catch (IOException e) {
                    Log.w(TAG, "Unable to open Lottie raw resource", e);
                }

                illustrationView.setVisibility(View.VISIBLE);
                container.setVisibility(View.VISIBLE);
            }

            resetAnimations(illustrationView);
            illustrationView.setImageResource(mImageResId);
            final Drawable drawable = illustrationView.getDrawable();
+1 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ android_robolectric_test {
        "androidx.core_core",
        "flag-junit",
        "settingslib_media_flags_lib",
        "settingslib_illustrationpreference_flags_lib",
        "testng", // TODO: remove once JUnit on Android provides assertThrows
    ],
    java_resource_dirs: ["config"],
+60 −3
Original line number Diff line number Diff line
@@ -26,10 +26,14 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.AnimatedImageDrawable;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.AnimationDrawable;
import android.net.Uri;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
@@ -39,11 +43,13 @@ import android.widget.ImageView;
import androidx.preference.PreferenceViewHolder;
import androidx.test.core.app.ApplicationProvider;

import com.android.settingslib.widget.flags.Flags;
import com.android.settingslib.widget.preference.illustration.R;

import com.airbnb.lottie.LottieAnimationView;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -51,10 +57,14 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;

import java.io.ByteArrayInputStream;


@RunWith(RobolectricTestRunner.class)
public class IllustrationPreferenceTest {

    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    @Mock
    private ViewGroup mRootView;
    private Uri mImageUri;
@@ -66,6 +76,7 @@ public class IllustrationPreferenceTest {
    private final Context mContext = ApplicationProvider.getApplicationContext();
    private IllustrationPreference.OnBindListener mOnBindListener;
    private LottieAnimationView mOnBindListenerAnimationView;
    private FrameLayout mIllustrationFrame;

    @Before
    public void setUp() {
@@ -75,14 +86,14 @@ public class IllustrationPreferenceTest {
        mBackgroundView = new ImageView(mContext);
        mAnimationView = spy(new LottieAnimationView(mContext));
        mMiddleGroundLayout = new FrameLayout(mContext);
        final FrameLayout illustrationFrame = new FrameLayout(mContext);
        illustrationFrame.setLayoutParams(
        mIllustrationFrame = new FrameLayout(mContext);
        mIllustrationFrame.setLayoutParams(
                new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT));
        doReturn(mMiddleGroundLayout).when(mRootView).findViewById(R.id.middleground_layout);
        doReturn(mBackgroundView).when(mRootView).findViewById(R.id.background_view);
        doReturn(mAnimationView).when(mRootView).findViewById(R.id.lottie_view);
        doReturn(illustrationFrame).when(mRootView).findViewById(R.id.illustration_frame);
        doReturn(mIllustrationFrame).when(mRootView).findViewById(R.id.illustration_frame);
        mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(mRootView));

        final AttributeSet attributeSet = Robolectric.buildAttributeSet().build();
@@ -158,11 +169,13 @@ public class IllustrationPreferenceTest {
    }

    @Test
    @DisableFlags(Flags.FLAG_AUTO_HIDE_EMPTY_LOTTIE_RES)
    public void playLottieAnimationWithResource_verifyFailureListener() {
        // fake the valid lottie image
        final int fakeValidResId = 111;
        doNothing().when(mAnimationView).setImageResource(fakeValidResId);
        doReturn(null).when(mAnimationView).getDrawable();
        doNothing().when(mAnimationView).setAnimation(fakeValidResId);

        mPreference.setLottieAnimationResId(fakeValidResId);
        mPreference.onBindViewHolder(mViewHolder);
@@ -170,6 +183,50 @@ public class IllustrationPreferenceTest {
        verify(mAnimationView).setFailureListener(any());
    }

    @Test
    @DisableFlags(Flags.FLAG_AUTO_HIDE_EMPTY_LOTTIE_RES)
    public void handleImageWithAnimation_emptyInputStreamDisabledFlag_verifyContainerVisible() {
        doNothing().when(mAnimationView).setImageResource(111);
        doReturn(null).when(mAnimationView).getDrawable();

        mPreference.setLottieAnimationResId(111);
        mPreference.onBindViewHolder(mViewHolder);

        assertThat(mAnimationView.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mIllustrationFrame.getVisibility()).isEqualTo(View.VISIBLE);
    }

    @Test
    @EnableFlags(Flags.FLAG_AUTO_HIDE_EMPTY_LOTTIE_RES)
    public void handleImageWithAnimation_emptyInputStreamEnabledFlag_verifyContainerHidden() {
        Resources res = spy(mContext.getResources());
        doReturn(res).when(mAnimationView).getResources();
        doReturn(new ByteArrayInputStream(new byte[] {})).when(res).openRawResource(111);

        mPreference.setLottieAnimationResId(111);
        mPreference.onBindViewHolder(mViewHolder);

        assertThat(mAnimationView.getVisibility()).isEqualTo(View.GONE);
        assertThat(mIllustrationFrame.getVisibility()).isEqualTo(View.GONE);
    }

    @Test
    @EnableFlags(Flags.FLAG_AUTO_HIDE_EMPTY_LOTTIE_RES)
    public void handleImageWithAnimation_nonEmptyInputStreamEnabledFlag_verifyContainerVisible() {
        Resources res = spy(mContext.getResources());
        doReturn(res).when(mAnimationView).getResources();
        doReturn(new ByteArrayInputStream(new byte[] { 1, 2, 3 })).when(res).openRawResource(111);
        doNothing().when(mAnimationView).setImageResource(111);
        doNothing().when(mAnimationView).setAnimation(111);
        doReturn(null).when(mAnimationView).getDrawable();

        mPreference.setLottieAnimationResId(111);
        mPreference.onBindViewHolder(mViewHolder);

        assertThat(mAnimationView.getVisibility()).isEqualTo(View.VISIBLE);
        assertThat(mIllustrationFrame.getVisibility()).isEqualTo(View.VISIBLE);
    }

    @Test
    public void setMaxHeight_smallerThanRestrictedHeight_matchResult() {
        final int restrictedHeight =