diff --git a/res/layout/preference_animated_image.xml b/res/layout/preference_animated_image.xml deleted file mode 100644 index 64cfc982ef7..00000000000 --- a/res/layout/preference_animated_image.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - \ 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 c707e5cc0a7..00000000000 --- 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 animated webp 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 640ae532161..510f8d3484a 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.SettingsMainSwitchBar; 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 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference 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 c7e5b13be83..00000000000 --- 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)); - } -}