Merge "Replace the AnimatedImagePreference with IllustrationPreference." into sc-dev
diff --git a/res/layout/preference_animated_image.xml b/res/layout/preference_animated_image.xml
deleted file mode 100644
index 64cfc98..0000000
--- a/res/layout/preference_animated_image.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright (C) 2019 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:layout_width="match_parent"
-    android:layout_height="@dimen/settingslib_illustration_height"
-    android:gravity="center"
-    android:padding="@dimen/settingslib_illustration_padding"
-    android:orientation="vertical"
-    android:importantForAccessibility="noHideDescendants">
-
-    <ImageView
-        android:id="@+id/animated_img"
-        android:maxWidth="@dimen/settingslib_illustration_width"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:background="@drawable/protection_background"
-        android:scaleType="fitCenter"
-        android:adjustViewBounds="true"/>
-
-    <com.airbnb.lottie.LottieAnimationView
-        android:id="@+id/lottie_view"
-        android:maxWidth="@dimen/settingslib_illustration_width"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:background="@drawable/protection_background"
-        android:scaleType="fitCenter"
-        android:adjustViewBounds="true"
-        android:clipToOutline="true"/>
-</LinearLayout>
\ No newline at end of file
diff --git a/src/com/android/settings/accessibility/AnimatedImagePreference.java b/src/com/android/settings/accessibility/AnimatedImagePreference.java
deleted file mode 100644
index c707e5c..0000000
--- a/src/com/android/settings/accessibility/AnimatedImagePreference.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2019 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.settings.accessibility;
-
-import android.content.Context;
-import android.graphics.drawable.Animatable;
-import android.graphics.drawable.Animatable2;
-import android.graphics.drawable.AnimationDrawable;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-
-import androidx.preference.Preference;
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-
-import com.airbnb.lottie.LottieAnimationView;
-import com.airbnb.lottie.LottieDrawable;
-
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.util.Objects;
-
-/**
- * A custom {@link ImageView} preference for showing animated or static image, such as <a
- * href="https://developers.google.com/speed/webp/">animated webp</a> and static png.
- */
-public class AnimatedImagePreference extends Preference {
-
-    private static final String TAG = "AnimatedImagePreference";
-    private Uri mImageUri;
-    private int mMaxHeight = -1;
-
-    private final Animatable2.AnimationCallback mAnimationCallback =
-            new Animatable2.AnimationCallback() {
-        @Override
-        public void onAnimationEnd(Drawable drawable) {
-            ((Animatable2) drawable).start();
-        }
-    };
-
-    AnimatedImagePreference(Context context) {
-        super(context);
-        setLayoutResource(R.layout.preference_animated_image);
-    }
-
-    @Override
-    public void onBindViewHolder(PreferenceViewHolder holder) {
-        super.onBindViewHolder(holder);
-
-        final ImageView imageView = holder.itemView.findViewById(R.id.animated_img);
-        final LottieAnimationView lottieView = holder.itemView.findViewById(R.id.lottie_view);
-        if (imageView == null || lottieView == null) {
-            return;
-        }
-
-        if (mImageUri != null) {
-            resetAnimations(imageView, lottieView);
-            hideAllChildViews(holder.itemView);
-
-            imageView.setImageURI(mImageUri);
-            if (imageView.getDrawable() != null) {
-                startAnimationWith(imageView);
-            } else {
-                // The lottie image from the raw folder also returns null.
-                startLottieAnimationWith(lottieView);
-            }
-        }
-
-        if (mMaxHeight > -1) {
-            imageView.setMaxHeight(mMaxHeight);
-            lottieView.setMaxHeight(mMaxHeight);
-        }
-    }
-
-    /**
-     * Sets image uri to display image in {@link ImageView}
-     *
-     * @param imageUri the Uri of an image
-     */
-    public void setImageUri(Uri imageUri) {
-        if (imageUri != null && !imageUri.equals(mImageUri)) {
-            mImageUri = imageUri;
-            notifyChanged();
-        }
-    }
-
-    /**
-     * Sets the maximum height of the view.
-     *
-     * @param maxHeight the maximum height of ImageView in terms of pixels.
-     */
-    public void setMaxHeight(int maxHeight) {
-        if (maxHeight != mMaxHeight) {
-            mMaxHeight = maxHeight;
-            notifyChanged();
-        }
-    }
-
-    private void startAnimationWith(ImageView imageView) {
-        startAnimation(imageView.getDrawable());
-
-        imageView.setVisibility(View.VISIBLE);
-    }
-
-    private void startLottieAnimationWith(LottieAnimationView lottieView) {
-        final InputStream inputStream = getInputStreamFromUri(mImageUri);
-        Objects.requireNonNull(inputStream, "Invalid resource.");
-        lottieView.setAnimation(inputStream, /* cacheKey= */ null);
-        lottieView.setRepeatCount(LottieDrawable.INFINITE);
-        lottieView.playAnimation();
-
-        lottieView.setVisibility(View.VISIBLE);
-    }
-
-    private void startAnimation(Drawable drawable) {
-        if (!(drawable instanceof Animatable)) {
-            return;
-        }
-
-        if (drawable instanceof Animatable2) {
-            ((Animatable2) drawable).registerAnimationCallback(mAnimationCallback);
-        } else if (drawable instanceof AnimationDrawable) {
-            ((AnimationDrawable) drawable).setOneShot(false);
-        }
-
-        ((Animatable) drawable).start();
-    }
-
-    private void resetAnimations(ImageView imageView, LottieAnimationView lottieView) {
-        resetAnimation(imageView.getDrawable());
-
-        lottieView.cancelAnimation();
-    }
-
-    private void resetAnimation(Drawable drawable) {
-        if (!(drawable instanceof Animatable)) {
-            return;
-        }
-
-        if (drawable instanceof Animatable2) {
-            ((Animatable2) drawable).clearAnimationCallbacks();
-        }
-
-        ((Animatable) drawable).stop();
-    }
-
-    private InputStream getInputStreamFromUri(Uri uri) {
-        try {
-            return getContext().getContentResolver().openInputStream(uri);
-        } catch (FileNotFoundException e) {
-            Log.w(TAG, "Cannot find content uri: " + uri, e);
-            return null;
-        }
-    }
-
-    private void hideAllChildViews(View itemView) {
-        final ViewGroup viewGroup = (ViewGroup) itemView;
-        for (int i = 0; i < viewGroup.getChildCount(); i++) {
-            viewGroup.getChildAt(i).setVisibility(View.GONE);
-        }
-    }
-}
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 640ae53..510f8d3 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -59,6 +59,7 @@
 import com.android.settings.widget.SettingsMainSwitchPreference;
 import com.android.settingslib.HelpUtils;
 import com.android.settingslib.accessibility.AccessibilityUtils;
+import com.android.settingslib.widget.IllustrationPreference;
 import com.android.settingslib.widget.OnMainSwitchChangeListener;
 
 import com.google.android.setupcompat.util.WizardManagerHelper;
@@ -398,15 +399,13 @@
             return;
         }
 
-        final int screenHalfHeight = AccessibilityUtil.getScreenHeightPixels(getPrefContext()) / 2;
-        final AnimatedImagePreference animatedImagePreference =
-                new AnimatedImagePreference(getPrefContext());
-        animatedImagePreference.setImageUri(mImageUri);
-        animatedImagePreference.setSelectable(false);
-        animatedImagePreference.setMaxHeight(screenHalfHeight);
-        animatedImagePreference.setKey(KEY_ANIMATED_IMAGE);
+        final IllustrationPreference illustrationPreference =
+                new IllustrationPreference(getPrefContext());
+        illustrationPreference.setImageUri(mImageUri);
+        illustrationPreference.setSelectable(false);
+        illustrationPreference.setKey(KEY_ANIMATED_IMAGE);
 
-        getPreferenceScreen().addPreference(animatedImagePreference);
+        getPreferenceScreen().addPreference(illustrationPreference);
     }
 
     private void initToggleServiceSwitchPreference() {
diff --git a/tests/robotests/src/com/android/settings/accessibility/AnimatedImagePreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/AnimatedImagePreferenceTest.java
deleted file mode 100644
index c7e5b13..0000000
--- a/tests/robotests/src/com/android/settings/accessibility/AnimatedImagePreferenceTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.settings.accessibility;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.graphics.drawable.AnimatedImageDrawable;
-import android.graphics.drawable.AnimatedVectorDrawable;
-import android.graphics.drawable.AnimationDrawable;
-import android.net.Uri;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-
-import androidx.preference.PreferenceViewHolder;
-
-import com.android.settings.R;
-
-import com.airbnb.lottie.LottieAnimationView;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-
-import java.io.InputStream;
-
-/** Tests for {@link AnimatedImagePreference}. */
-@RunWith(RobolectricTestRunner.class)
-public class AnimatedImagePreferenceTest {
-    private final Context mContext = RuntimeEnvironment.application;
-    private Uri mImageUri;
-    private PreferenceViewHolder mViewHolder;
-    private AnimatedImagePreference mAnimatedImagePreference;
-
-    @Mock
-    private ViewGroup mRootView;
-
-    @Spy
-    private ImageView mImageView;
-
-    @Before
-    public void init() {
-        MockitoAnnotations.initMocks(this);
-
-        mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(mRootView));
-        doReturn(new LottieAnimationView(mContext)).when(mRootView).findViewById(R.id.lottie_view);
-        mImageView = spy(new ImageView(mContext));
-
-        mAnimatedImagePreference = new AnimatedImagePreference(mContext);
-        mImageUri = new Uri.Builder().build();
-    }
-
-    @Test
-    public void playAnimation_animatedImageDrawable_success() {
-        final AnimatedImageDrawable drawable = mock(AnimatedImageDrawable.class);
-        doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
-        doReturn(drawable).when(mImageView).getDrawable();
-
-        mAnimatedImagePreference.setImageUri(mImageUri);
-        mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
-        verify(drawable).start();
-    }
-
-    @Test
-    public void playAnimation_animatedVectorDrawable_success() {
-        final AnimatedVectorDrawable drawable = mock(AnimatedVectorDrawable.class);
-        doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
-        doReturn(drawable).when(mImageView).getDrawable();
-
-        mAnimatedImagePreference.setImageUri(mImageUri);
-        mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
-        verify(drawable).start();
-    }
-
-    @Test
-    public void playAnimation_animationDrawable_success() {
-        final AnimationDrawable drawable = mock(AnimationDrawable.class);
-        doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
-        doReturn(drawable).when(mImageView).getDrawable();
-
-        mAnimatedImagePreference.setImageUri(mImageUri);
-        mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
-        verify(drawable).start();
-    }
-
-    @Test
-    public void setImageUri_viewNotExist_setFail() {
-        doReturn(null).when(mRootView).findViewById(R.id.animated_img);
-
-        mAnimatedImagePreference.setImageUri(mImageUri);
-        mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
-        verify(mImageView, never()).setImageURI(mImageUri);
-    }
-
-    @Test
-    public void setMaxHeight_success() {
-        final int maxHeight = 100;
-        doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
-
-        mAnimatedImagePreference.setMaxHeight(maxHeight);
-        mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
-        assertThat(mImageView.getMaxHeight()).isEqualTo(maxHeight);
-    }
-
-    @Test
-    public void setImageUriAndRebindViewHolder_lottieImageFromRawFolder_setAnimation() {
-        final int fakeLottieResId = 111111;
-        final Uri lottieImageUri =
-                new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
-                .authority(mContext.getPackageName())
-                .appendPath(String.valueOf(fakeLottieResId))
-                .build();
-        final LottieAnimationView lottieView = spy(new LottieAnimationView(mContext));
-        doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
-        doReturn(lottieView).when(mRootView).findViewById(R.id.lottie_view);
-
-        mAnimatedImagePreference.setImageUri(lottieImageUri);
-        mAnimatedImagePreference.onBindViewHolder(mViewHolder);
-
-        verify(lottieView).setAnimation(any(InputStream.class), eq(null));
-    }
-}