summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dave Mankoff <mankoff@google.com> 2021-05-26 16:03:52 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-05-26 16:03:52 +0000
commitf7e815dd30292b9370f44201253abbd064f59332 (patch)
tree7408597517d39fb95d7649bfe2be40cb5b7713b7
parenta63e111574f9348150d4a150cf2cc2923fdcb7d2 (diff)
parent46121d2f9c982bb35a868a62e9c5bc8e105dc43c (diff)
Merge "Show a small toast when a double tap is needed." into sc-dev
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml16
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java111
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java96
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java60
9 files changed, 319 insertions, 13 deletions
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index c16f13ef5ae6..09d46856dec8 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -129,7 +129,21 @@
android:layout_marginTop="@dimen/status_bar_header_height_keyguard"
android:text="@string/report_rejected_touch"
android:visibility="gone" />
-
+ <com.android.systemui.statusbar.phone.TapAgainView
+ android:id="@+id/shade_falsing_tap_again"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ systemui:layout_constraintLeft_toLeftOf="parent"
+ systemui:layout_constraintRight_toRightOf="parent"
+ systemui:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginBottom="20dp"
+ android:paddingLeft="20dp"
+ android:paddingRight="20dp"
+ android:paddingTop="10dp"
+ android:paddingBottom="10dp"
+ android:elevation="10dp"
+ android:visibility="gone"
+ />
</com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer>
<FrameLayout
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
index ee69e277cc46..dba530edc27f 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
@@ -40,6 +40,7 @@ public class FalsingManagerFake implements FalsingManager {
private boolean mIsFalseRobustTap;
private final List<FalsingBeliefListener> mFalsingBeliefListeners = new ArrayList<>();
+ private final List<FalsingTapListener> mTapListeners = new ArrayList<>();
@Override
public void onSuccessfulUnlock() {
@@ -148,11 +149,15 @@ public class FalsingManagerFake implements FalsingManager {
@Override
public void addTapListener(FalsingTapListener falsingTapListener) {
-
+ mTapListeners.add(falsingTapListener);
}
@Override
public void removeTapListener(FalsingTapListener falsingTapListener) {
+ mTapListeners.remove(falsingTapListener);
+ }
+ public List<FalsingTapListener> getTapListeners() {
+ return mTapListeners;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
index d84bb908fe69..68e20705fbeb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
@@ -142,7 +142,6 @@ public class KeyguardIndicationTextView extends TextView {
Animator yTranslate =
ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, 0, -getYTranslationPixels());
yTranslate.setDuration(getFadeOutDuration());
- fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
animatorSet.playTogether(fadeOut, yTranslate);
return animatorSet;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 0f3af095f7be..d9ba494a4d63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -24,6 +24,8 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
+import com.android.systemui.R;
+
public class NotificationPanelView extends PanelView {
private static final boolean DEBUG = false;
@@ -92,6 +94,10 @@ public class NotificationPanelView extends PanelView {
mRtlChangeListener = listener;
}
+ public TapAgainView getTapAgainView() {
+ return findViewById(R.id.shade_falsing_tap_again);
+ }
+
interface RtlChangeListener {
void onRtlPropertielsChanged(int layoutDirection);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 1263b104b6a5..def9092e4171 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -97,8 +97,8 @@ import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeLog;
-import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
+import com.android.systemui.fragments.FragmentService;
import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
@@ -306,6 +306,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
private final KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
private final QSDetailDisplayer mQSDetailDisplayer;
+ private final FragmentService mFragmentService;
private final FeatureFlags mFeatureFlags;
private final ScrimController mScrimController;
private final PrivacyDotViewController mPrivacyDotViewController;
@@ -314,6 +315,7 @@ public class NotificationPanelViewController extends PanelViewController {
// If there are exactly 1 + mMaxKeyguardNotifications, then still shows all notifications
private final int mMaxKeyguardNotifications;
private final LockscreenShadeTransitionController mLockscreenShadeTransitionController;
+ private final TapAgainViewController mTapAgainViewController;
private boolean mShouldUseSplitNotificationShade;
// Current max allowed keyguard notifications determined by measuring the panel
private int mMaxAllowedKeyguardNotifications;
@@ -604,7 +606,12 @@ public class NotificationPanelViewController extends PanelViewController {
private final FalsingTapListener mFalsingTapListener = new FalsingTapListener() {
@Override
public void onDoubleTapRequired() {
- showTransientIndication(R.string.notification_tap_again);
+ if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED) {
+ mTapAgainViewController.show();
+ } else {
+ mKeyguardIndicationController.showTransientIndication(
+ R.string.notification_tap_again);
+ }
mVibratorHelper.vibrate(VibrationEffect.EFFECT_STRENGTH_MEDIUM);
}
};
@@ -653,6 +660,8 @@ public class NotificationPanelViewController extends PanelViewController {
QuickAccessWalletClient quickAccessWalletClient,
KeyguardMediaController keyguardMediaController,
PrivacyDotViewController privacyDotViewController,
+ TapAgainViewController tapAgainViewController,
+ FragmentService fragmentService,
@Main Executor uiExecutor,
SecureSettings secureSettings) {
super(view, falsingManager, dozeLog, keyguardStateController,
@@ -679,6 +688,7 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory;
mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory;
mQSDetailDisplayer = qsDetailDisplayer;
+ mFragmentService = fragmentService;
mKeyguardUserSwitcherEnabled = mResources.getBoolean(
com.android.internal.R.bool.config_keyguardUserSwitcher);
mKeyguardQsUserSwitchEnabled =
@@ -705,6 +715,7 @@ public class NotificationPanelViewController extends PanelViewController {
mUserManager = userManager;
mMediaDataManager = mediaDataManager;
mQuickAccessWalletClient = quickAccessWalletClient;
+ mTapAgainViewController = tapAgainViewController;
mUiExecutor = uiExecutor;
mSecureSettings = secureSettings;
pulseExpansionHandler.setPulseExpandAbortListener(() -> {
@@ -843,6 +854,8 @@ public class NotificationPanelViewController extends PanelViewController {
if (mShouldUseSplitNotificationShade) {
updateResources();
}
+
+ mTapAgainViewController.init();
}
@Override
@@ -3675,10 +3688,6 @@ public class NotificationPanelViewController extends PanelViewController {
updateMaxDisplayedNotifications(true);
}
- public void showTransientIndication(int id) {
- mKeyguardIndicationController.showTransientIndication(id);
- }
-
public void setAlpha(float alpha) {
mView.setAlpha(alpha);
}
@@ -4264,7 +4273,8 @@ public class NotificationPanelViewController extends PanelViewController {
private class OnAttachStateChangeListener implements View.OnAttachStateChangeListener {
@Override
public void onViewAttachedToWindow(View v) {
- FragmentHostManager.get(mView).addTagListener(QS.TAG, mFragmentListener);
+ mFragmentService.getFragmentHostManager(mView)
+ .addTagListener(QS.TAG, mFragmentListener);
mStatusBarStateController.addCallback(mStatusBarStateListener);
mConfigurationController.addCallback(mConfigurationListener);
mUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
@@ -4278,7 +4288,8 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
public void onViewDetachedFromWindow(View v) {
- FragmentHostManager.get(mView).removeTagListener(QS.TAG, mFragmentListener);
+ mFragmentService.getFragmentHostManager(mView)
+ .removeTagListener(QS.TAG, mFragmentListener);
mStatusBarStateController.removeCallback(mStatusBarStateListener);
mConfigurationController.removeCallback(mConfigurationListener);
mUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
new file mode 100644
index 000000000000..9856795c8903
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainView.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2021 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.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.systemui.R;
+import com.android.wm.shell.animation.Interpolators;
+
+/**
+ * View to show a toast-like popup on the notification shade and quick settings.
+ */
+public class TapAgainView extends FrameLayout {
+ public TapAgainView(
+ @NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ updateBgColor();
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ TextView text = new TextView(mContext);
+ text.setText(R.string.notification_tap_again);
+ addView(text);
+ }
+
+ void updateBgColor() {
+ setBackgroundResource(R.drawable.rounded_bg_full);
+ }
+
+ /** Make the view visible. */
+ public void animateIn() {
+ int yTranslation = mContext.getResources().getDimensionPixelSize(
+ R.dimen.keyguard_indication_y_translation);
+
+ AnimatorSet animatorSet = new AnimatorSet();
+ ObjectAnimator fadeIn = ObjectAnimator.ofFloat(this, View.ALPHA, 1f);
+ fadeIn.setStartDelay(150); // From KeyguardIndicationTextView#getFadeInDelay
+ fadeIn.setDuration(317); // From KeyguardIndicationTextView#getFadeInDuration
+ fadeIn.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+
+ Animator yTranslate =
+ ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, yTranslation, 0);
+ yTranslate.setDuration(600); // From KeyguardIndicationTextView#getYInDuration
+ yTranslate.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ setTranslationY(0);
+ }
+ });
+ animatorSet.playTogether(yTranslate, fadeIn);
+ animatorSet.start();
+ setVisibility(View.VISIBLE);
+ }
+
+ /** Make the view gone. */
+ public void animateOut() {
+ long fadeOutDuration = 167L; // From KeyguardIndicationTextView#getFadeOutDuration
+ int yTranslation = mContext.getResources().getDimensionPixelSize(
+ com.android.systemui.R.dimen.keyguard_indication_y_translation);
+
+ AnimatorSet animatorSet = new AnimatorSet();
+ ObjectAnimator fadeOut = ObjectAnimator.ofFloat(this, View.ALPHA, 0f);
+ fadeOut.setDuration(fadeOutDuration);
+ fadeOut.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
+
+ Animator yTranslate =
+ ObjectAnimator.ofFloat(this, View.TRANSLATION_Y, 0, -yTranslation);
+ yTranslate.setDuration(fadeOutDuration);
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ setVisibility(GONE);
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ setVisibility(GONE);
+ }
+ });
+ animatorSet.playTogether(yTranslate, fadeOut);
+ animatorSet.start();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
new file mode 100644
index 000000000000..bb53bad7df70
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TapAgainViewController.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021 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.statusbar.phone;
+
+import static com.android.systemui.classifier.FalsingModule.DOUBLE_TAP_TIMEOUT_MS;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
+import com.android.systemui.util.ViewController;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * Controller for {@link TapAgainView}.
+ */
+@StatusBarComponent.StatusBarScope
+public class TapAgainViewController extends ViewController<TapAgainView> {
+ private final DelayableExecutor mDelayableExecutor;
+ private final ConfigurationController mConfigurationController;
+ private final long mDoubleTapTimeMs;
+
+ private Runnable mHideCanceler;
+
+ @VisibleForTesting
+ final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+ @Override
+ public void onOverlayChanged() {
+ mView.updateBgColor();
+ }
+
+ @Override
+ public void onUiModeChanged() {
+ mView.updateBgColor();
+ }
+
+ @Override
+ public void onThemeChanged() {
+ mView.updateBgColor();
+ }
+ };
+
+ @Inject
+ protected TapAgainViewController(TapAgainView view,
+ @Main DelayableExecutor delayableExecutor,
+ ConfigurationController configurationController,
+ @Named(DOUBLE_TAP_TIMEOUT_MS) long doubleTapTimeMs) {
+ super(view);
+ mDelayableExecutor = delayableExecutor;
+ mConfigurationController = configurationController;
+ mDoubleTapTimeMs = doubleTapTimeMs;
+ }
+
+ @Override
+ protected void onViewAttached() {
+ mConfigurationController.addCallback(mConfigurationListener);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mConfigurationController.removeCallback(mConfigurationListener);
+ }
+
+ /** Shows the associated view, possibly animating it. */
+ public void show() {
+ if (mHideCanceler != null) {
+ mHideCanceler.run();
+ }
+ mView.animateIn();
+ mHideCanceler = mDelayableExecutor.executeDelayed(this::hide, mDoubleTapTimeMs);
+ }
+
+ /** Hides the associated view, possibly animating it. */
+ public void hide() {
+ mHideCanceler = null;
+ mView.animateOut();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
index 008c0aea7ce9..27d71edd5e8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java
@@ -23,6 +23,7 @@ import com.android.systemui.R;
import com.android.systemui.biometrics.AuthRippleView;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
+import com.android.systemui.statusbar.phone.TapAgainView;
import dagger.Module;
import dagger.Provides;
@@ -53,4 +54,11 @@ public abstract class StatusBarViewModule {
NotificationShadeWindowView notificationShadeWindowView) {
return notificationShadeWindowView.findViewById(R.id.auth_ripple);
}
+
+ /** */
+ @Provides
+ @StatusBarComponent.StatusBarScope
+ public static TapAgainView getTapAgainView(NotificationPanelView npv) {
+ return npv.getTapAgainView();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 6b4797fc5723..83a1872a0a45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -20,12 +20,15 @@ import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.StatusBarState.SHADE;
+import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
+import static com.android.systemui.statusbar.notification.ViewGroupFadeHelper.reset;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -75,13 +78,17 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.doze.DozeLog;
+import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.fragments.FragmentService;
import com.android.systemui.media.KeyguardMediaController;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.qs.QSDetailDisplayer;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShadeDepthController;
@@ -252,11 +259,21 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private PrivacyDotViewController mPrivacyDotViewController;
@Mock
private SecureSettings mSecureSettings;
+ @Mock
+ private TapAgainViewController mTapAgainViewController;
+ @Mock
+ private KeyguardIndicationController mKeyguardIndicationController;
+ @Mock
+ private FragmentService mFragmentService;
+ @Mock
+ private FragmentHostManager mFragmentHostManager;
private SysuiStatusBarStateController mStatusBarStateController;
private NotificationPanelViewController mNotificationPanelViewController;
private View.AccessibilityDelegate mAccessibiltyDelegate;
private NotificationsQuickSettingsContainer mNotificationContainerParent;
+ private List<View.OnAttachStateChangeListener> mOnAttachStateChangeListeners;
+ private FalsingManagerFake mFalsingManager = new FalsingManagerFake();
@Before
public void setup() {
@@ -297,6 +314,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mNotificationContainerParent.addView(newViewWithId(R.id.keyguard_status_view));
when(mView.findViewById(R.id.notification_container_parent))
.thenReturn(mNotificationContainerParent);
+ when(mFragmentService.getFragmentHostManager(mView)).thenReturn(mFragmentHostManager);
FlingAnimationUtils.Builder flingAnimationUtilsBuilder = new FlingAnimationUtils.Builder(
mDisplayMetrics);
@@ -317,7 +335,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mKeyguardBypassController, mHeadsUpManager,
mock(NotificationRoundnessManager.class),
mStatusBarStateController,
- new FalsingManagerFake(),
+ mFalsingManager,
mLockscreenShadeTransitionController,
new FalsingCollectorFake());
when(mKeyguardStatusViewComponentFactory.build(any()))
@@ -331,11 +349,12 @@ public class NotificationPanelViewTest extends SysuiTestCase {
when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
.thenReturn(mKeyguardStatusBarViewController);
+ reset(mView);
mNotificationPanelViewController = new NotificationPanelViewController(mView,
mResources,
mLayoutInflater,
coordinator, expansionHandler, mDynamicPrivacyController, mKeyguardBypassController,
- new FalsingManagerFake(), new FalsingCollectorFake(),
+ mFalsingManager, new FalsingCollectorFake(),
mNotificationLockscreenUserManager, mNotificationEntryManager,
mKeyguardStateController, mStatusBarStateController, mDozeLog,
mDozeParameters, mCommandQueue, mVibratorHelper,
@@ -364,6 +383,8 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mQuickAccessWalletClient,
mKeyguardMediaController,
mPrivacyDotViewController,
+ mTapAgainViewController,
+ mFragmentService,
new FakeExecutor(new FakeSystemClock()),
mSecureSettings);
mNotificationPanelViewController.initDependencies(
@@ -371,6 +392,13 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mNotificationShelfController);
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
mNotificationPanelViewController.setBar(mPanelBar);
+ mNotificationPanelViewController.setKeyguardIndicationController(
+ mKeyguardIndicationController);
+ ArgumentCaptor<View.OnAttachStateChangeListener> onAttachStateChangeListenerArgumentCaptor =
+ ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
+ verify(mView, atLeast(1)).addOnAttachStateChangeListener(
+ onAttachStateChangeListenerArgumentCaptor.capture());
+ mOnAttachStateChangeListeners = onAttachStateChangeListenerArgumentCaptor.getAllValues();
ArgumentCaptor<View.AccessibilityDelegate> accessibilityDelegateArgumentCaptor =
ArgumentCaptor.forClass(View.AccessibilityDelegate.class);
@@ -616,6 +644,34 @@ public class NotificationPanelViewTest extends SysuiTestCase {
verify(mKeyguardStateController).notifyPanelFlingEnd();
}
+ @Test
+ public void testDoubleTapRequired_Keyguard() {
+ FalsingManager.FalsingTapListener listener = getFalsingTapListener();
+ mStatusBarStateController.setState(KEYGUARD);
+
+ listener.onDoubleTapRequired();
+
+ verify(mKeyguardIndicationController).showTransientIndication(anyInt());
+ }
+
+ @Test
+ public void testDoubleTapRequired_ShadeLocked() {
+ FalsingManager.FalsingTapListener listener = getFalsingTapListener();
+ mStatusBarStateController.setState(SHADE_LOCKED);
+
+ listener.onDoubleTapRequired();
+
+ verify(mTapAgainViewController).show();
+ }
+
+ private FalsingManager.FalsingTapListener getFalsingTapListener() {
+ for (View.OnAttachStateChangeListener listener : mOnAttachStateChangeListeners) {
+ listener.onViewAttachedToWindow(mView);
+ }
+ assertThat(mFalsingManager.getTapListeners().size()).isEqualTo(1);
+ return mFalsingManager.getTapListeners().get(0);
+ }
+
private View newViewWithId(int id) {
View view = new View(mContext);
view.setId(id);