From 779d03447e79bd3080d66f5a43849225326fa0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Go=CC=88llner?= Date: Fri, 17 Mar 2023 11:53:25 +0100 Subject: [PATCH] Step clock animation: Fix NPE when startValues or endValues are null By looking at parent class implementations of Transition, it seems that is a legit case, and that should be handled by returning a null Animator Test: SplitShadeTransitionAdapterTest.kt Fixes: 274002399 Change-Id: I07501eb4bbd001bdb6014a3644e41cd8b575ccee --- .../NotificationPanelViewController.java | 8 +- .../shade/SplitShadeTransitionAdapterTest.kt | 74 +++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/shade/SplitShadeTransitionAdapterTest.kt diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index ff523ad7fa0f3..c2738b285d1ce 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -5004,9 +5004,13 @@ public final class NotificationPanelViewController implements Dumpable { captureValues(transitionValues); } + @Nullable @Override - public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, - TransitionValues endValues) { + public Animator createAnimator(ViewGroup sceneRoot, @Nullable TransitionValues startValues, + @Nullable TransitionValues endValues) { + if (startValues == null || endValues == null) { + return null; + } ValueAnimator anim = ValueAnimator.ofFloat(0, 1); Rect from = (Rect) startValues.values.get(PROP_BOUNDS); diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/SplitShadeTransitionAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/SplitShadeTransitionAdapterTest.kt new file mode 100644 index 0000000000000..64fec5bfd4ede --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/SplitShadeTransitionAdapterTest.kt @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2023 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.systemui.shade + +import android.animation.Animator +import android.testing.AndroidTestingRunner +import android.transition.TransitionValues +import androidx.test.filters.SmallTest +import com.android.keyguard.KeyguardStatusViewController +import com.android.systemui.SysuiTestCase +import com.android.systemui.shade.NotificationPanelViewController.SplitShadeTransitionAdapter +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class SplitShadeTransitionAdapterTest : SysuiTestCase() { + + @Mock private lateinit var keyguardStatusViewController: KeyguardStatusViewController + + private lateinit var adapter: SplitShadeTransitionAdapter + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + adapter = SplitShadeTransitionAdapter(keyguardStatusViewController) + } + + @Test + fun createAnimator_nullStartValues_returnsNull() { + val animator = adapter.createAnimator(startValues = null, endValues = TransitionValues()) + + assertThat(animator).isNull() + } + + @Test + fun createAnimator_nullEndValues_returnsNull() { + val animator = adapter.createAnimator(startValues = TransitionValues(), endValues = null) + + assertThat(animator).isNull() + } + + @Test + fun createAnimator_nonNullStartAndEndValues_returnsAnimator() { + val animator = + adapter.createAnimator(startValues = TransitionValues(), endValues = TransitionValues()) + + assertThat(animator).isNotNull() + } +} + +private fun SplitShadeTransitionAdapter.createAnimator( + startValues: TransitionValues?, + endValues: TransitionValues? +): Animator? { + return createAnimator(/* sceneRoot= */ null, startValues, endValues) +}