diff options
| author | 2024-05-13 22:03:19 +0000 | |
|---|---|---|
| committer | 2024-05-14 02:22:18 +0000 | |
| commit | bcad6e2702219ea1f37854a081d03b2bc65359e2 (patch) | |
| tree | 6cf43adb6a9db1b2bed41d86e7da339bfd79a258 | |
| parent | a5b030c71a2baadf5b5ba76ae0a1b888895ea904 (diff) | |
Auto hide IllustrationPreference when lottie file is empty
Flag: com.android.settingslib.widget.flags.auto_hide_lottie_res
Bug: 337873972
Test: unit test
Test: manual: delete `lottie_adaptive_brightness.json` from overlay, navigate to Display > Adaptive Brightness -- verify no empty container
Change-Id: I873976d3e87b119a3ee690d95c68149f249fe7a9
5 files changed, 119 insertions, 5 deletions
diff --git a/packages/SettingsLib/IllustrationPreference/Android.bp b/packages/SettingsLib/IllustrationPreference/Android.bp index 6407810367cf..c3a91a20c339 100644 --- a/packages/SettingsLib/IllustrationPreference/Android.bp +++ b/packages/SettingsLib/IllustrationPreference/Android.bp @@ -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", + ], +} diff --git a/packages/SettingsLib/IllustrationPreference/aconfig/illustrationpreference.aconfig b/packages/SettingsLib/IllustrationPreference/aconfig/illustrationpreference.aconfig new file mode 100644 index 000000000000..e566d89facaf --- /dev/null +++ b/packages/SettingsLib/IllustrationPreference/aconfig/illustrationpreference.aconfig @@ -0,0 +1,12 @@ +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 diff --git a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java index 815a101957ad..bbf0315aa475 100644 --- a/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java +++ b/packages/SettingsLib/IllustrationPreference/src/com/android/settingslib/widget/IllustrationPreference.java @@ -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(); diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp index f4ddd0ac59df..f87b5190c7a1 100644 --- a/packages/SettingsLib/tests/robotests/Android.bp +++ b/packages/SettingsLib/tests/robotests/Android.bp @@ -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"], diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java index 6590bbdcdae6..ca53fc2ba47e 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/IllustrationPreferenceTest.java @@ -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); @@ -171,6 +184,50 @@ public class IllustrationPreferenceTest { } @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 = mContext.getResources().getDimensionPixelSize( |