Merge changes from topics "shelf-refactor-anv", "shelf-refactor-click" into udc-dev am: 0948e76a59 am: 873550b4e9
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/22575210 Change-Id: Ib30deac91c943fed9d0cbacdf105b0faa4105e09 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.accessibility.data.repository
|
||||
|
||||
import android.view.accessibility.AccessibilityManager
|
||||
import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener
|
||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
|
||||
/** Exposes accessibility-related state. */
|
||||
interface AccessibilityRepository {
|
||||
/** @see [AccessibilityManager.isTouchExplorationEnabled] */
|
||||
val isTouchExplorationEnabled: Flow<Boolean>
|
||||
|
||||
companion object {
|
||||
operator fun invoke(a11yManager: AccessibilityManager): AccessibilityRepository =
|
||||
AccessibilityRepositoryImpl(a11yManager)
|
||||
}
|
||||
}
|
||||
|
||||
private class AccessibilityRepositoryImpl(
|
||||
manager: AccessibilityManager,
|
||||
) : AccessibilityRepository {
|
||||
override val isTouchExplorationEnabled: Flow<Boolean> =
|
||||
conflatedCallbackFlow {
|
||||
val listener = TouchExplorationStateChangeListener(::trySend)
|
||||
manager.addTouchExplorationStateChangeListener(listener)
|
||||
trySend(manager.isTouchExplorationEnabled)
|
||||
awaitClose { manager.removeTouchExplorationStateChangeListener(listener) }
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
|
||||
@Module
|
||||
object AccessibilityRepositoryModule {
|
||||
@Provides fun provideRepo(manager: AccessibilityManager) = AccessibilityRepository(manager)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.accessibility.domain.interactor
|
||||
|
||||
import com.android.systemui.accessibility.data.repository.AccessibilityRepository
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@SysUISingleton
|
||||
class AccessibilityInteractor
|
||||
@Inject
|
||||
constructor(
|
||||
private val a11yRepo: AccessibilityRepository,
|
||||
) {
|
||||
/** @see [android.view.accessibility.AccessibilityManager.isTouchExplorationEnabled] */
|
||||
val isTouchExplorationEnabled: Flow<Boolean>
|
||||
get() = a11yRepo.isTouchExplorationEnabled
|
||||
}
|
||||
@@ -25,9 +25,6 @@ public interface FalsingCollector {
|
||||
/** */
|
||||
void onSuccessfulUnlock();
|
||||
|
||||
/** */
|
||||
void onNotificationActive();
|
||||
|
||||
/** */
|
||||
void setShowingAod(boolean showingAod);
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@ public class FalsingCollectorFake implements FalsingCollector {
|
||||
public void onSuccessfulUnlock() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotificationActive() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowingAod(boolean showingAod) {
|
||||
}
|
||||
|
||||
@@ -173,10 +173,6 @@ class FalsingCollectorImpl implements FalsingCollector {
|
||||
sessionEnd();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNotificationActive() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShowingAod(boolean showingAod) {
|
||||
mShowingAod = showingAod;
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.android.keyguard.dagger.KeyguardBouncerComponent;
|
||||
import com.android.systemui.BootCompleteCache;
|
||||
import com.android.systemui.BootCompleteCacheImpl;
|
||||
import com.android.systemui.accessibility.AccessibilityModule;
|
||||
import com.android.systemui.accessibility.data.repository.AccessibilityRepositoryModule;
|
||||
import com.android.systemui.appops.dagger.AppOpsModule;
|
||||
import com.android.systemui.assist.AssistModule;
|
||||
import com.android.systemui.biometrics.AlternateUdfpsTouchProvider;
|
||||
@@ -140,6 +141,7 @@ import javax.inject.Named;
|
||||
*/
|
||||
@Module(includes = {
|
||||
AccessibilityModule.class,
|
||||
AccessibilityRepositoryModule.class,
|
||||
AppOpsModule.class,
|
||||
AssistModule.class,
|
||||
BiometricsModule.class,
|
||||
|
||||
@@ -178,7 +178,6 @@ import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
|
||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||
import com.android.systemui.statusbar.notification.ViewGroupFadeHelper;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
|
||||
@@ -225,8 +224,6 @@ import com.android.systemui.util.Utils;
|
||||
import com.android.systemui.util.time.SystemClock;
|
||||
import com.android.wm.shell.animation.FlingAnimationUtils;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -237,6 +234,7 @@ import java.util.function.Consumer;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import kotlin.Unit;
|
||||
import kotlinx.coroutines.CoroutineDispatcher;
|
||||
|
||||
@CentralSurfacesComponent.CentralSurfacesScope
|
||||
@@ -1709,8 +1707,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
|
||||
final float extraSpaceForShelf = lockIconPadding - noShelfOverlapBottomPadding;
|
||||
|
||||
if (extraSpaceForShelf > 0f) {
|
||||
return Math.min(mNotificationShelfController.getIntrinsicHeight(),
|
||||
extraSpaceForShelf);
|
||||
return Math.min(getShelfHeight(), extraSpaceForShelf);
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
@@ -1732,10 +1729,18 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
|
||||
mNotificationStackScrollLayoutController.getView(),
|
||||
getVerticalSpaceForLockscreenNotifications(),
|
||||
getVerticalSpaceForLockscreenShelf(),
|
||||
mNotificationShelfController.getIntrinsicHeight()
|
||||
getShelfHeight()
|
||||
);
|
||||
}
|
||||
|
||||
private int getShelfHeight() {
|
||||
if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR)) {
|
||||
return mNotificationStackScrollLayoutController.getShelfHeight();
|
||||
} else {
|
||||
return mNotificationShelfController.getIntrinsicHeight();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateClock() {
|
||||
if (mIsOcclusionTransitionRunning) {
|
||||
return;
|
||||
@@ -3308,16 +3313,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
|
||||
public boolean hasPulsingNotifications() {
|
||||
return mNotificationListContainer.hasPulsingNotifications();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActivatableNotificationView getActivatedChild() {
|
||||
return mNotificationStackScrollLayoutController.getActivatedChild();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setActivatedChild(ActivatableNotificationView o) {
|
||||
mNotificationStackScrollLayoutController.setActivatedChild(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3338,12 +3333,12 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
|
||||
|
||||
mGestureRecorder = recorder;
|
||||
mHideExpandedRunnable = hideExpandedRunnable;
|
||||
mNotificationShelfController = notificationShelfController;
|
||||
if (!mFeatureFlags.isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR)) {
|
||||
mNotificationStackScrollLayoutController.setShelfController(
|
||||
notificationShelfController);
|
||||
mLockscreenShadeTransitionController.bindController(notificationShelfController);
|
||||
}
|
||||
mNotificationShelfController = notificationShelfController;
|
||||
mLockscreenShadeTransitionController.bindController(notificationShelfController);
|
||||
updateMaxDisplayedNotifications(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -288,7 +288,6 @@ public class NotificationShadeWindowViewController {
|
||||
mService.userActivity();
|
||||
mService.wakeUpIfDozing(
|
||||
mClock.uptimeMillis(),
|
||||
mView,
|
||||
"LOCK_ICON_TOUCH",
|
||||
PowerManager.WAKE_REASON_GESTURE);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,6 @@ class PulsingGestureListener @Inject constructor(
|
||||
shadeLogger.d("Single tap handled, requesting centralSurfaces.wakeUpIfDozing")
|
||||
centralSurfaces.wakeUpIfDozing(
|
||||
SystemClock.uptimeMillis(),
|
||||
notificationShadeWindowView,
|
||||
"PULSING_SINGLE_TAP",
|
||||
PowerManager.WAKE_REASON_TAP
|
||||
)
|
||||
@@ -116,7 +115,6 @@ class PulsingGestureListener @Inject constructor(
|
||||
) {
|
||||
centralSurfaces.wakeUpIfDozing(
|
||||
SystemClock.uptimeMillis(),
|
||||
notificationShadeWindowView,
|
||||
"PULSING_DOUBLE_TAP",
|
||||
PowerManager.WAKE_REASON_TAP
|
||||
)
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.systemui.shade
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
import com.android.systemui.statusbar.RemoteInputController
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
|
||||
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController
|
||||
@@ -254,7 +253,4 @@ interface ShadeNotificationPresenter {
|
||||
|
||||
/** Returns whether the screen has temporarily woken up to display notifications. */
|
||||
fun hasPulsingNotifications(): Boolean
|
||||
|
||||
/** The current activated notification. */
|
||||
var activatedChild: ActivatableNotificationView?
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.view.View;
|
||||
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
|
||||
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
|
||||
import com.android.systemui.statusbar.notification.stack.AmbientState;
|
||||
@@ -106,11 +105,6 @@ public class LegacyNotificationShelfControllerImpl implements NotificationShelfC
|
||||
return mView.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnActivatedListener(ActivatableNotificationView.OnActivatedListener listener) {
|
||||
mView.setOnActivatedListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnClickListener(View.OnClickListener onClickListener) {
|
||||
mView.setOnClickListener(onClickListener);
|
||||
|
||||
@@ -276,7 +276,6 @@ class LockscreenShadeTransitionController @Inject constructor(
|
||||
if (statusBarStateController.state == StatusBarState.KEYGUARD) {
|
||||
centralSurfaces.wakeUpIfDozing(
|
||||
SystemClock.uptimeMillis(),
|
||||
it,
|
||||
"SHADE_CLICK",
|
||||
PowerManager.WAKE_REASON_GESTURE,
|
||||
)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
|
||||
/**
|
||||
@@ -25,8 +24,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
||||
* for affecting the state of the system (e.g. starting an intent, given that the presenter may
|
||||
* want to perform some action before doing so).
|
||||
*/
|
||||
public interface NotificationPresenter extends ExpandableNotificationRow.OnExpandClickListener,
|
||||
ActivatableNotificationView.OnActivatedListener {
|
||||
public interface NotificationPresenter extends ExpandableNotificationRow.OnExpandClickListener {
|
||||
/**
|
||||
* Returns true if the presenter is not visible. For example, it may not be necessary to do
|
||||
* animations if this returns true.
|
||||
|
||||
@@ -124,7 +124,7 @@ public class NotificationRemoteInputManager implements Dumpable {
|
||||
View view, PendingIntent pendingIntent, RemoteViews.RemoteResponse response) {
|
||||
mCentralSurfacesOptionalLazy.get().ifPresent(
|
||||
centralSurfaces -> centralSurfaces.wakeUpIfDozing(
|
||||
SystemClock.uptimeMillis(), view, "NOTIFICATION_CLICK",
|
||||
SystemClock.uptimeMillis(), "NOTIFICATION_CLICK",
|
||||
PowerManager.WAKE_REASON_GESTURE));
|
||||
|
||||
final NotificationEntry entry = getNotificationForParent(view.getParent());
|
||||
|
||||
@@ -21,8 +21,6 @@ import android.view.View
|
||||
import android.view.View.OnClickListener
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView.OnActivatedListener
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableView
|
||||
import com.android.systemui.statusbar.notification.stack.AmbientState
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
|
||||
@@ -43,9 +41,6 @@ interface NotificationShelfController {
|
||||
/** Whether or not the shelf can modify the color of notifications in the shade. */
|
||||
fun canModifyColorOfNotifications(): Boolean
|
||||
|
||||
/** @see ActivatableNotificationView.setOnActivatedListener */
|
||||
fun setOnActivatedListener(listener: OnActivatedListener)
|
||||
|
||||
/** Binds the shelf to the host [NotificationStackScrollLayout], via its Controller. */
|
||||
fun bind(
|
||||
ambientState: AmbientState,
|
||||
|
||||
@@ -71,7 +71,7 @@ public final class NotificationClicker implements View.OnClickListener {
|
||||
}
|
||||
|
||||
mCentralSurfacesOptional.ifPresent(centralSurfaces -> centralSurfaces.wakeUpIfDozing(
|
||||
SystemClock.uptimeMillis(), v, "NOTIFICATION_CLICK",
|
||||
SystemClock.uptimeMillis(), "NOTIFICATION_CLICK",
|
||||
PowerManager.WAKE_REASON_GESTURE));
|
||||
|
||||
final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
|
||||
|
||||
@@ -177,7 +177,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
|
||||
private void bindRow(NotificationEntry entry, ExpandableNotificationRow row) {
|
||||
mListContainer.bindRow(row);
|
||||
mNotificationRemoteInputManager.bindRow(row);
|
||||
row.setOnActivatedListener(mPresenter);
|
||||
entry.setRow(row);
|
||||
mNotifBindPipeline.manageRow(entry, row);
|
||||
mBindRowCallback.onBindRow(row);
|
||||
|
||||
@@ -28,7 +28,6 @@ import android.util.MathUtils;
|
||||
import android.view.Choreographer;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.PathInterpolator;
|
||||
|
||||
@@ -56,30 +55,6 @@ import java.util.Set;
|
||||
*/
|
||||
public abstract class ActivatableNotificationView extends ExpandableOutlineView {
|
||||
|
||||
/**
|
||||
* The amount of width, which is kept in the end when performing a disappear animation (also
|
||||
* the amount from which the horizontal appearing begins)
|
||||
*/
|
||||
private static final float HORIZONTAL_COLLAPSED_REST_PARTIAL = 0.05f;
|
||||
|
||||
/**
|
||||
* At which point from [0,1] does the horizontal collapse animation end (or start when
|
||||
* expanding)? 1.0 meaning that it ends immediately and 0.0 that it is continuously animated.
|
||||
*/
|
||||
private static final float HORIZONTAL_ANIMATION_END = 0.2f;
|
||||
|
||||
/**
|
||||
* At which point from [0,1] does the horizontal collapse animation start (or start when
|
||||
* expanding)? 1.0 meaning that it starts immediately and 0.0 that it is animated at all.
|
||||
*/
|
||||
private static final float HORIZONTAL_ANIMATION_START = 1.0f;
|
||||
|
||||
/**
|
||||
* At which point from [0,1] does the vertical collapse animation start (or end when
|
||||
* expanding) 1.0 meaning that it starts immediately and 0.0 that it is animated at all.
|
||||
*/
|
||||
private static final float VERTICAL_ANIMATION_START = 1.0f;
|
||||
|
||||
/**
|
||||
* A sentinel value when no color should be used. Can be used with {@link #setTintColor(int)}
|
||||
* or {@link #setOverrideTintColor(int, float)}.
|
||||
@@ -95,10 +70,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
* The start of the animation is at #ALPHA_APPEAR_START_FRACTION
|
||||
*/
|
||||
private static final float ALPHA_APPEAR_END_FRACTION = 1;
|
||||
private static final Interpolator ACTIVATE_INVERSE_INTERPOLATOR
|
||||
= new PathInterpolator(0.6f, 0, 0.5f, 1);
|
||||
private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
|
||||
= new PathInterpolator(0, 0, 0.5f, 1);
|
||||
private final Set<SourceType> mOnDetachResetRoundness = new HashSet<>();
|
||||
private int mTintedRippleColor;
|
||||
private int mNormalRippleColor;
|
||||
@@ -112,10 +83,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
*/
|
||||
private boolean mActivated;
|
||||
|
||||
private OnActivatedListener mOnActivatedListener;
|
||||
|
||||
private final Interpolator mSlowOutFastInInterpolator;
|
||||
private final Interpolator mSlowOutLinearInInterpolator;
|
||||
private Interpolator mCurrentAppearInterpolator;
|
||||
|
||||
NotificationBackgroundView mBackgroundNormal;
|
||||
@@ -142,13 +110,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
protected Point mTargetPoint;
|
||||
private boolean mDismissed;
|
||||
private boolean mRefocusOnDismiss;
|
||||
private AccessibilityManager mAccessibilityManager;
|
||||
protected boolean mUseRoundnessSourceTypes;
|
||||
|
||||
public ActivatableNotificationView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mSlowOutFastInInterpolator = new PathInterpolator(0.8f, 0.0f, 0.6f, 1.0f);
|
||||
mSlowOutLinearInInterpolator = new PathInterpolator(0.8f, 0.0f, 1.0f, 1.0f);
|
||||
setClipChildren(false);
|
||||
setClipToPadding(false);
|
||||
updateColors();
|
||||
@@ -230,7 +196,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
public void onTap() {}
|
||||
|
||||
/** Sets the last action up time this view was touched. */
|
||||
void setLastActionUpTime(long eventTime) {
|
||||
public void setLastActionUpTime(long eventTime) {
|
||||
mLastActionUpTime = eventTime;
|
||||
}
|
||||
|
||||
@@ -249,10 +215,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean handleSlideBack() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this view is interactive and can be double tapped
|
||||
*/
|
||||
@@ -270,40 +232,12 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
mBackgroundNormal.setPressedAllowed(allowed);
|
||||
}
|
||||
|
||||
void makeActive() {
|
||||
mActivated = true;
|
||||
if (mOnActivatedListener != null) {
|
||||
mOnActivatedListener.onActivated(this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return mActivated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels the hotspot and makes the notification inactive.
|
||||
*/
|
||||
public void makeInactive(boolean animate) {
|
||||
if (mActivated) {
|
||||
mActivated = false;
|
||||
}
|
||||
if (mOnActivatedListener != null) {
|
||||
mOnActivatedListener.onActivationReset(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOutlineAlpha() {
|
||||
float alpha = NotificationStackScrollLayout.BACKGROUND_ALPHA_DIMMED;
|
||||
alpha = (alpha + (1.0f - alpha) * mNormalBackgroundVisibilityAmount);
|
||||
setOutlineAlpha(alpha);
|
||||
}
|
||||
|
||||
private void setNormalBackgroundVisibilityAmount(float normalBackgroundVisibilityAmount) {
|
||||
mNormalBackgroundVisibilityAmount = normalBackgroundVisibilityAmount;
|
||||
updateOutlineAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBelowSpeedBump(boolean below) {
|
||||
super.setBelowSpeedBump(below);
|
||||
@@ -317,13 +251,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
protected void onBelowSpeedBumpChanged() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether we are below the speed bump
|
||||
*/
|
||||
public boolean isBelowSpeedBump() {
|
||||
return mIsBelowSpeedBump;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tint color of the background
|
||||
*/
|
||||
@@ -728,10 +655,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
}
|
||||
}
|
||||
|
||||
public void setOnActivatedListener(OnActivatedListener onActivatedListener) {
|
||||
mOnActivatedListener = onActivatedListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFakeShadowIntensity(float shadowIntensity, float outlineAlpha, int shadowYEnd,
|
||||
int outlineTranslation) {
|
||||
@@ -782,14 +705,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
return mRefocusOnDismiss || isAccessibilityFocused();
|
||||
}
|
||||
|
||||
void setTouchHandler(Gefingerpoken touchHandler) {
|
||||
public void setTouchHandler(Gefingerpoken touchHandler) {
|
||||
mTouchHandler = touchHandler;
|
||||
}
|
||||
|
||||
public void setAccessibilityManager(AccessibilityManager accessibilityManager) {
|
||||
mAccessibilityManager = accessibilityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the support for rounded corner based on the SourceType
|
||||
* @param enabled true if is supported
|
||||
@@ -832,9 +751,4 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnActivatedListener {
|
||||
void onActivated(ActivatableNotificationView view);
|
||||
void onActivationReset(ActivatableNotificationView view);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,12 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.row;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import com.android.systemui.Gefingerpoken;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.statusbar.phone.NotificationTapHelper;
|
||||
import com.android.systemui.util.ViewController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -37,44 +34,16 @@ public class ActivatableNotificationViewController
|
||||
private final ExpandableOutlineViewController mExpandableOutlineViewController;
|
||||
private final AccessibilityManager mAccessibilityManager;
|
||||
private final FalsingManager mFalsingManager;
|
||||
private final FalsingCollector mFalsingCollector;
|
||||
private final NotificationTapHelper mNotificationTapHelper;
|
||||
private final TouchHandler mTouchHandler = new TouchHandler();
|
||||
|
||||
private boolean mNeedsDimming;
|
||||
|
||||
@Inject
|
||||
public ActivatableNotificationViewController(ActivatableNotificationView view,
|
||||
NotificationTapHelper.Factory notificationTapHelpFactory,
|
||||
ExpandableOutlineViewController expandableOutlineViewController,
|
||||
AccessibilityManager accessibilityManager, FalsingManager falsingManager,
|
||||
FalsingCollector falsingCollector) {
|
||||
AccessibilityManager accessibilityManager, FalsingManager falsingManager) {
|
||||
super(view);
|
||||
mExpandableOutlineViewController = expandableOutlineViewController;
|
||||
mAccessibilityManager = accessibilityManager;
|
||||
mFalsingManager = falsingManager;
|
||||
mFalsingCollector = falsingCollector;
|
||||
|
||||
mNotificationTapHelper = notificationTapHelpFactory.create(
|
||||
(active) -> {
|
||||
if (active) {
|
||||
mView.makeActive();
|
||||
mFalsingCollector.onNotificationActive();
|
||||
} else {
|
||||
mView.makeInactive(true /* animate */);
|
||||
}
|
||||
}, mView::performClick, mView::handleSlideBack);
|
||||
|
||||
mView.setOnActivatedListener(new ActivatableNotificationView.OnActivatedListener() {
|
||||
@Override
|
||||
public void onActivated(ActivatableNotificationView view) {
|
||||
mFalsingCollector.onNotificationActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivationReset(ActivatableNotificationView view) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +54,6 @@ public class ActivatableNotificationViewController
|
||||
mExpandableOutlineViewController.init();
|
||||
mView.setOnTouchListener(mTouchHandler);
|
||||
mView.setTouchHandler(mTouchHandler);
|
||||
mView.setAccessibilityManager(mAccessibilityManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,15 +67,9 @@ public class ActivatableNotificationViewController
|
||||
}
|
||||
|
||||
class TouchHandler implements Gefingerpoken, View.OnTouchListener {
|
||||
private boolean mBlockNextTouch;
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent ev) {
|
||||
boolean result = false;
|
||||
if (mBlockNextTouch) {
|
||||
mBlockNextTouch = false;
|
||||
return true;
|
||||
}
|
||||
if (ev.getAction() == MotionEvent.ACTION_UP) {
|
||||
mView.setLastActionUpTime(ev.getEventTime());
|
||||
}
|
||||
|
||||
@@ -968,15 +968,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean handleSlideBack() {
|
||||
if (mMenuRow != null && mMenuRow.isMenuVisible()) {
|
||||
animateResetTranslation();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSummaryWithChildren() {
|
||||
return mIsSummaryWithChildren;
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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.statusbar.notification.row.ui.viewbinder
|
||||
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.View.OnTouchListener
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.android.systemui.Gefingerpoken
|
||||
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||
import com.android.systemui.plugins.FalsingManager
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView
|
||||
import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModel
|
||||
import kotlinx.coroutines.awaitCancellation
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/** Binds an [ActivatableNotificationView] to its [view model][ActivatableNotificationViewModel]. */
|
||||
object ActivatableNotificationViewBinder {
|
||||
|
||||
fun bind(
|
||||
viewModel: ActivatableNotificationViewModel,
|
||||
view: ActivatableNotificationView,
|
||||
falsingManager: FalsingManager,
|
||||
) {
|
||||
ExpandableOutlineViewBinder.bind(viewModel, view)
|
||||
val touchHandler = TouchHandler(view, falsingManager)
|
||||
view.repeatWhenAttached {
|
||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
launch {
|
||||
viewModel.isTouchable.collect { isTouchable ->
|
||||
touchHandler.isTouchEnabled = isTouchable
|
||||
}
|
||||
}
|
||||
view.registerListenersWhileAttached(touchHandler)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun ActivatableNotificationView.registerListenersWhileAttached(
|
||||
touchHandler: TouchHandler,
|
||||
): Unit =
|
||||
try {
|
||||
setOnTouchListener(touchHandler)
|
||||
setTouchHandler(touchHandler)
|
||||
awaitCancellation()
|
||||
} finally {
|
||||
setTouchHandler(null)
|
||||
setOnTouchListener(null)
|
||||
}
|
||||
}
|
||||
|
||||
private class TouchHandler(
|
||||
private val view: ActivatableNotificationView,
|
||||
private val falsingManager: FalsingManager,
|
||||
) : Gefingerpoken, OnTouchListener {
|
||||
|
||||
var isTouchEnabled = false
|
||||
|
||||
override fun onTouch(v: View, ev: MotionEvent): Boolean {
|
||||
val result = false
|
||||
if (ev.action == MotionEvent.ACTION_UP) {
|
||||
view.setLastActionUpTime(ev.eventTime)
|
||||
}
|
||||
// With a11y, just do nothing.
|
||||
if (!isTouchEnabled) {
|
||||
return false
|
||||
}
|
||||
if (ev.action == MotionEvent.ACTION_UP) {
|
||||
// If this is a false tap, capture the even so it doesn't result in a click.
|
||||
val falseTap: Boolean = falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)
|
||||
if (!falseTap && v is ActivatableNotificationView) {
|
||||
v.onTap()
|
||||
}
|
||||
return falseTap
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean = false
|
||||
|
||||
/** Use [onTouch] instead. */
|
||||
override fun onTouchEvent(ev: MotionEvent): Boolean = false
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.android.systemui.statusbar.notification.row.ui.viewbinder
|
||||
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableOutlineView
|
||||
import com.android.systemui.statusbar.notification.row.ui.viewmodel.ExpandableOutlineViewModel as ViewModel
|
||||
|
||||
object ExpandableOutlineViewBinder {
|
||||
fun bind(
|
||||
viewModel: ViewModel,
|
||||
view: ExpandableOutlineView,
|
||||
) {
|
||||
ExpandableViewBinder.bind(viewModel, view)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.android.systemui.statusbar.notification.row.ui.viewbinder
|
||||
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableView
|
||||
import com.android.systemui.statusbar.notification.row.ui.viewmodel.ExpandableViewModel as ViewModel
|
||||
|
||||
object ExpandableViewBinder {
|
||||
fun bind(viewModel: ViewModel, view: ExpandableView) {}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.statusbar.notification.row.ui.viewmodel
|
||||
|
||||
import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
/** ViewModel for [com.android.systemui.statusbar.notification.row.ActivatableNotificationView]. */
|
||||
interface ActivatableNotificationViewModel : ExpandableOutlineViewModel {
|
||||
/** Does the view react to touches? */
|
||||
val isTouchable: Flow<Boolean>
|
||||
|
||||
companion object {
|
||||
operator fun invoke(
|
||||
a11yInteractor: AccessibilityInteractor,
|
||||
): ActivatableNotificationViewModel = ActivatableNotificationViewModelImpl(a11yInteractor)
|
||||
}
|
||||
}
|
||||
|
||||
private class ActivatableNotificationViewModelImpl(
|
||||
a11yInteractor: AccessibilityInteractor,
|
||||
) : ActivatableNotificationViewModel {
|
||||
override val isTouchable: Flow<Boolean> =
|
||||
// If a11y touch exploration is enabled, then the activatable view should ignore touches
|
||||
a11yInteractor.isTouchExplorationEnabled.map { !it }
|
||||
}
|
||||
|
||||
@Module
|
||||
object ActivatableNotificationViewModelModule {
|
||||
@Provides
|
||||
fun provideViewModel(interactor: AccessibilityInteractor) =
|
||||
ActivatableNotificationViewModel(interactor)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.android.systemui.statusbar.notification.row.ui.viewmodel
|
||||
|
||||
/** ViewModel for [com.android.systemui.statusbar.notification.row.ExpandableOutlineView]. */
|
||||
interface ExpandableOutlineViewModel : ExpandableViewModel
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.android.systemui.statusbar.notification.row.ui.viewmodel
|
||||
|
||||
/** ViewModel for [com.android.systemui.statusbar.notification.row.ExpandableView]. */
|
||||
interface ExpandableViewModel
|
||||
@@ -16,10 +16,14 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.shelf.domain.interactor
|
||||
|
||||
import android.os.PowerManager
|
||||
import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController
|
||||
import com.android.systemui.statusbar.NotificationShelf
|
||||
import com.android.systemui.statusbar.phone.CentralSurfaces
|
||||
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
|
||||
import com.android.systemui.util.time.SystemClock
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -31,6 +35,9 @@ class NotificationShelfInteractor
|
||||
constructor(
|
||||
private val keyguardRepository: KeyguardRepository,
|
||||
private val deviceEntryFaceAuthRepository: DeviceEntryFaceAuthRepository,
|
||||
private val centralSurfaces: CentralSurfaces,
|
||||
private val systemClock: SystemClock,
|
||||
private val keyguardTransitionController: LockscreenShadeTransitionController,
|
||||
) {
|
||||
/** Is the shelf showing on the keyguard? */
|
||||
val isShowingOnKeyguard: Flow<Boolean>
|
||||
@@ -45,4 +52,14 @@ constructor(
|
||||
) { isKeyguardShowing, isBypassEnabled ->
|
||||
isKeyguardShowing && isBypassEnabled
|
||||
}
|
||||
|
||||
/** Transition keyguard to the locked shade, triggered by the shelf. */
|
||||
fun goToLockedShadeFromShelf() {
|
||||
centralSurfaces.wakeUpIfDozing(
|
||||
systemClock.uptimeMillis(),
|
||||
"SHADE_CLICK",
|
||||
PowerManager.WAKE_REASON_GESTURE,
|
||||
)
|
||||
keyguardTransitionController.goToLockedShade(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
package com.android.systemui.statusbar.notification.shelf.ui.viewbinder
|
||||
|
||||
import android.view.View
|
||||
import android.view.accessibility.AccessibilityManager
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.android.systemui.classifier.FalsingCollector
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||
@@ -28,19 +26,17 @@ import com.android.systemui.plugins.FalsingManager
|
||||
import com.android.systemui.statusbar.LegacyNotificationShelfControllerImpl
|
||||
import com.android.systemui.statusbar.NotificationShelf
|
||||
import com.android.systemui.statusbar.NotificationShelfController
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableOutlineViewController
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableViewController
|
||||
import com.android.systemui.statusbar.notification.row.ui.viewbinder.ActivatableNotificationViewBinder
|
||||
import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.NotificationShelfViewModel
|
||||
import com.android.systemui.statusbar.notification.stack.AmbientState
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
|
||||
import com.android.systemui.statusbar.phone.NotificationIconAreaController
|
||||
import com.android.systemui.statusbar.phone.NotificationIconContainer
|
||||
import com.android.systemui.statusbar.phone.NotificationTapHelper
|
||||
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
|
||||
import com.android.systemui.util.kotlin.getValue
|
||||
import dagger.Lazy
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.awaitCancellation
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
@@ -57,11 +53,9 @@ constructor(
|
||||
private val shelf: NotificationShelf,
|
||||
private val viewModel: NotificationShelfViewModel,
|
||||
featureFlags: FeatureFlags,
|
||||
private val notifTapHelperFactory: NotificationTapHelper.Factory,
|
||||
private val a11yManager: AccessibilityManager,
|
||||
private val falsingManager: FalsingManager,
|
||||
private val falsingCollector: FalsingCollector,
|
||||
hostControllerLazy: Lazy<NotificationStackScrollLayoutController>,
|
||||
private val notificationIconAreaController: NotificationIconAreaController,
|
||||
) : NotificationShelfController {
|
||||
|
||||
private val hostController: NotificationStackScrollLayoutController by hostControllerLazy
|
||||
@@ -78,43 +72,28 @@ constructor(
|
||||
}
|
||||
|
||||
fun init() {
|
||||
NotificationShelfViewBinder.bind(viewModel, shelf)
|
||||
|
||||
ActivatableNotificationViewController(
|
||||
shelf,
|
||||
notifTapHelperFactory,
|
||||
ExpandableOutlineViewController(shelf, ExpandableViewController(shelf)),
|
||||
a11yManager,
|
||||
falsingManager,
|
||||
falsingCollector,
|
||||
)
|
||||
.init()
|
||||
NotificationShelfViewBinder.bind(viewModel, shelf, falsingManager)
|
||||
hostController.setShelf(shelf)
|
||||
hostController.setOnNotificationRemovedListener { child, _ ->
|
||||
view.requestRoundnessResetFor(child)
|
||||
}
|
||||
notificationIconAreaController.setShelfIcons(shelf.shelfIcons)
|
||||
}
|
||||
|
||||
override val intrinsicHeight: Int
|
||||
get() = shelf.intrinsicHeight
|
||||
get() = unsupported
|
||||
|
||||
override val shelfIcons: NotificationIconContainer
|
||||
get() = shelf.shelfIcons
|
||||
get() = unsupported
|
||||
|
||||
override fun canModifyColorOfNotifications(): Boolean = unsupported
|
||||
|
||||
override fun setOnActivatedListener(listener: ActivatableNotificationView.OnActivatedListener) {
|
||||
shelf.setOnActivatedListener(listener)
|
||||
}
|
||||
|
||||
override fun bind(
|
||||
ambientState: AmbientState,
|
||||
notificationStackScrollLayoutController: NotificationStackScrollLayoutController,
|
||||
) = unsupported
|
||||
|
||||
override fun setOnClickListener(listener: View.OnClickListener) {
|
||||
shelf.setOnClickListener(listener)
|
||||
}
|
||||
override fun setOnClickListener(listener: View.OnClickListener) = unsupported
|
||||
|
||||
private val unsupported: Nothing
|
||||
get() = NotificationShelfController.throwIllegalFlagStateError(expected = true)
|
||||
@@ -122,14 +101,32 @@ constructor(
|
||||
|
||||
/** Binds a [NotificationShelf] to its backend. */
|
||||
object NotificationShelfViewBinder {
|
||||
fun bind(viewModel: NotificationShelfViewModel, shelf: NotificationShelf) {
|
||||
fun bind(
|
||||
viewModel: NotificationShelfViewModel,
|
||||
shelf: NotificationShelf,
|
||||
falsingManager: FalsingManager,
|
||||
) {
|
||||
ActivatableNotificationViewBinder.bind(viewModel, shelf, falsingManager)
|
||||
shelf.repeatWhenAttached {
|
||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
viewModel.canModifyColorOfNotifications
|
||||
.onEach(shelf::setCanModifyColorOfNotifications)
|
||||
.launchIn(this)
|
||||
viewModel.isClickable.onEach(shelf::setCanInteract).launchIn(this)
|
||||
registerViewListenersWhileAttached(shelf, viewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun registerViewListenersWhileAttached(
|
||||
shelf: NotificationShelf,
|
||||
viewModel: NotificationShelfViewModel,
|
||||
) {
|
||||
try {
|
||||
shelf.setOnClickListener { viewModel.onShelfClicked() }
|
||||
awaitCancellation()
|
||||
} finally {
|
||||
shelf.setOnClickListener(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.systemui.statusbar.notification.shelf.ui.viewmodel
|
||||
|
||||
import com.android.systemui.statusbar.NotificationShelf
|
||||
import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModel
|
||||
import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor
|
||||
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
|
||||
import javax.inject.Inject
|
||||
@@ -29,7 +30,8 @@ class NotificationShelfViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val interactor: NotificationShelfInteractor,
|
||||
) {
|
||||
activatableViewModel: ActivatableNotificationViewModel,
|
||||
) : ActivatableNotificationViewModel by activatableViewModel {
|
||||
/** Is the shelf allowed to be clickable when it has content? */
|
||||
val isClickable: Flow<Boolean>
|
||||
get() = interactor.isShowingOnKeyguard
|
||||
@@ -37,4 +39,9 @@ constructor(
|
||||
/** Is the shelf allowed to modify the color of notifications in the host layout? */
|
||||
val canModifyColorOfNotifications: Flow<Boolean>
|
||||
get() = interactor.isShelfStatic.map { static -> !static }
|
||||
|
||||
/** Notifies that the user has clicked the shelf. */
|
||||
fun onShelfClicked() {
|
||||
interactor.goToLockedShadeFromShelf()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.android.systemui.shade.transition.LargeScreenShadeInterpolator;
|
||||
import com.android.systemui.statusbar.NotificationShelf;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
||||
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController;
|
||||
@@ -65,7 +64,6 @@ public class AmbientState implements Dumpable {
|
||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
private int mScrollY;
|
||||
private boolean mDimmed;
|
||||
private ActivatableNotificationView mActivatedChild;
|
||||
private float mOverScrollTopAmount;
|
||||
private float mOverScrollBottomAmount;
|
||||
private boolean mDozing;
|
||||
@@ -360,14 +358,6 @@ public class AmbientState implements Dumpable {
|
||||
mHideSensitive = hideSensitive;
|
||||
}
|
||||
|
||||
/**
|
||||
* In dimmed mode, a child can be activated, which happens on the first tap of the double-tap
|
||||
* interaction. This child is then scaled normally and its background is fully opaque.
|
||||
*/
|
||||
public void setActivatedChild(ActivatableNotificationView activatedChild) {
|
||||
mActivatedChild = activatedChild;
|
||||
}
|
||||
|
||||
public boolean isDimmed() {
|
||||
// While we are expanding from pulse, we want the notifications not to be dimmed, otherwise
|
||||
// you'd see the difference to the pulsing notification
|
||||
@@ -382,10 +372,6 @@ public class AmbientState implements Dumpable {
|
||||
return mHideSensitive;
|
||||
}
|
||||
|
||||
public ActivatableNotificationView getActivatedChild() {
|
||||
return mActivatedChild;
|
||||
}
|
||||
|
||||
public void setOverScrollAmount(float amount, boolean onTop) {
|
||||
if (onTop) {
|
||||
mOverScrollTopAmount = amount;
|
||||
|
||||
@@ -4469,24 +4469,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link AmbientState#setActivatedChild}.
|
||||
*/
|
||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||
void setActivatedChild(ActivatableNotificationView activatedChild) {
|
||||
mAmbientState.setActivatedChild(activatedChild);
|
||||
if (mAnimationsEnabled) {
|
||||
mActivateNeedsAnimation = true;
|
||||
mNeedsAnimation = true;
|
||||
}
|
||||
requestChildrenUpdate();
|
||||
}
|
||||
|
||||
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
|
||||
public ActivatableNotificationView getActivatedChild() {
|
||||
return mAmbientState.getActivatedChild();
|
||||
}
|
||||
|
||||
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
|
||||
private void applyCurrentState() {
|
||||
int numChildren = getChildCount();
|
||||
@@ -5137,6 +5119,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
requestChildrenUpdate();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ExpandableView getShelf() {
|
||||
if (NotificationShelfController.checkRefactorFlagEnabled(mAmbientState.getFeatureFlags())) {
|
||||
return mShelf;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setShelf(NotificationShelf shelf) {
|
||||
if (!NotificationShelfController.checkRefactorFlagEnabled(
|
||||
mAmbientState.getFeatureFlags())) {
|
||||
@@ -5236,7 +5227,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
void onStatePostChange(boolean fromShadeLocked) {
|
||||
boolean onKeyguard = onKeyguard();
|
||||
|
||||
mAmbientState.setActivatedChild(null);
|
||||
mAmbientState.setDimmed(onKeyguard);
|
||||
|
||||
if (mHeadsUpAppearanceController != null) {
|
||||
@@ -5245,11 +5235,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
|
||||
|
||||
setDimmed(onKeyguard, fromShadeLocked);
|
||||
setExpandingEnabled(!onKeyguard);
|
||||
ActivatableNotificationView activatedChild = getActivatedChild();
|
||||
setActivatedChild(null);
|
||||
if (activatedChild != null) {
|
||||
activatedChild.makeInactive(false /* animate */);
|
||||
}
|
||||
updateFooter();
|
||||
requestChildrenUpdate();
|
||||
onUpdateRowStates();
|
||||
|
||||
@@ -1370,14 +1370,6 @@ public class NotificationStackScrollLayoutController {
|
||||
mView.onUpdateRowStates();
|
||||
}
|
||||
|
||||
public ActivatableNotificationView getActivatedChild() {
|
||||
return mView.getActivatedChild();
|
||||
}
|
||||
|
||||
public void setActivatedChild(ActivatableNotificationView view) {
|
||||
mView.setActivatedChild(view);
|
||||
}
|
||||
|
||||
public void runAfterAnimationFinished(Runnable r) {
|
||||
mView.runAfterAnimationFinished(r);
|
||||
}
|
||||
@@ -1600,6 +1592,14 @@ public class NotificationStackScrollLayoutController {
|
||||
mView.setShelf(shelf);
|
||||
}
|
||||
|
||||
public int getShelfHeight() {
|
||||
if (!NotificationShelfController.checkRefactorFlagEnabled(mFeatureFlags)) {
|
||||
return 0;
|
||||
}
|
||||
ExpandableView shelf = mView.getShelf();
|
||||
return shelf == null ? 0 : shelf.getIntrinsicHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum for UiEvent logged from this class
|
||||
*/
|
||||
|
||||
@@ -126,7 +126,7 @@ public class StackScrollAlgorithm {
|
||||
updateHeadsUpStates(algorithmState, ambientState);
|
||||
updatePulsingStates(algorithmState, ambientState);
|
||||
|
||||
updateDimmedActivatedHideSensitive(ambientState, algorithmState);
|
||||
updateDimmedAndHideSensitive(ambientState, algorithmState);
|
||||
updateClipping(algorithmState, ambientState);
|
||||
updateSpeedBumpState(algorithmState, speedBumpIndex);
|
||||
updateShelfState(algorithmState, ambientState);
|
||||
@@ -341,25 +341,17 @@ public class StackScrollAlgorithm {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the dimmed, activated and hiding sensitive states of the children.
|
||||
*/
|
||||
private void updateDimmedActivatedHideSensitive(AmbientState ambientState,
|
||||
StackScrollAlgorithmState algorithmState) {
|
||||
/** Updates the dimmed and hiding sensitive states of the children. */
|
||||
private void updateDimmedAndHideSensitive(AmbientState ambientState,
|
||||
StackScrollAlgorithmState algorithmState) {
|
||||
boolean dimmed = ambientState.isDimmed();
|
||||
boolean hideSensitive = ambientState.isHideSensitive();
|
||||
View activatedChild = ambientState.getActivatedChild();
|
||||
int childCount = algorithmState.visibleChildren.size();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
ExpandableView child = algorithmState.visibleChildren.get(i);
|
||||
ExpandableViewState childViewState = child.getViewState();
|
||||
childViewState.dimmed = dimmed;
|
||||
childViewState.hideSensitive = hideSensitive;
|
||||
boolean isActivatedChild = activatedChild == child;
|
||||
if (dimmed && isActivatedChild) {
|
||||
childViewState.setZTranslation(childViewState.getZTranslation()
|
||||
+ 2.0f * ambientState.getZDistanceBetweenElements());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn
|
||||
/**
|
||||
* Wakes up the device if the device was dozing.
|
||||
*/
|
||||
void wakeUpIfDozing(long time, View where, String why, @PowerManager.WakeReason int wakeReason);
|
||||
void wakeUpIfDozing(long time, String why, @PowerManager.WakeReason int wakeReason);
|
||||
|
||||
NotificationShadeWindowView getNotificationShadeWindowView();
|
||||
|
||||
|
||||
@@ -1255,7 +1255,9 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
|
||||
// TODO: Deal with the ugliness that comes from having some of the status bar broken out
|
||||
// into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
|
||||
mNotificationIconAreaController.setupShelf(mNotificationShelfController);
|
||||
if (!mFeatureFlags.isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR)) {
|
||||
mNotificationIconAreaController.setupShelf(mNotificationShelfController);
|
||||
}
|
||||
mShadeExpansionStateManager.addExpansionListener(mWakeUpCoordinator);
|
||||
|
||||
// Allow plugins to reference DarkIconDispatcher and StatusBarStateController
|
||||
@@ -1565,7 +1567,6 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
mNotifListContainer,
|
||||
mHeadsUpManager,
|
||||
mJankMonitor);
|
||||
mNotificationShelfController.setOnActivatedListener(mPresenter);
|
||||
mRemoteInputManager.addControllerCallback(mNotificationShadeWindowController);
|
||||
mStackScrollerController.setNotificationActivityStarter(mNotificationActivityStarter);
|
||||
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
|
||||
@@ -1592,12 +1593,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
* Ask the display to wake up if currently dozing, else do nothing
|
||||
*
|
||||
* @param time when to wake up
|
||||
* @param where the view requesting the wakeup
|
||||
* @param why the reason for the wake up
|
||||
*/
|
||||
@Override
|
||||
public void wakeUpIfDozing(long time, View where, String why,
|
||||
@PowerManager.WakeReason int wakeReason) {
|
||||
public void wakeUpIfDozing(long time, String why, @PowerManager.WakeReason int wakeReason) {
|
||||
if (mDozing && mScreenOffAnimationController.allowWakeUpIfDozing()) {
|
||||
mPowerManager.wakeUp(
|
||||
time, wakeReason, "com.android.systemui:" + why);
|
||||
@@ -3485,7 +3484,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
|
||||
mStatusBarHideIconsForBouncerManager.setBouncerShowingAndTriggerUpdate(bouncerShowing);
|
||||
mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
|
||||
if (mBouncerShowing) {
|
||||
wakeUpIfDozing(SystemClock.uptimeMillis(), null, "BOUNCER_VISIBLE",
|
||||
wakeUpIfDozing(SystemClock.uptimeMillis(), "BOUNCER_VISIBLE",
|
||||
PowerManager.WAKE_REASON_GESTURE);
|
||||
}
|
||||
updateScrimController();
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.android.systemui.animation.Interpolators;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.demomode.DemoMode;
|
||||
import com.android.systemui.demomode.DemoModeController;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.plugins.DarkIconDispatcher;
|
||||
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
@@ -92,6 +93,8 @@ public class NotificationIconAreaController implements
|
||||
|
||||
private final DemoModeController mDemoModeController;
|
||||
|
||||
private final FeatureFlags mFeatureFlags;
|
||||
|
||||
private int mAodIconAppearTranslation;
|
||||
|
||||
private boolean mAnimationsEnabled;
|
||||
@@ -122,11 +125,12 @@ public class NotificationIconAreaController implements
|
||||
Optional<Bubbles> bubblesOptional,
|
||||
DemoModeController demoModeController,
|
||||
DarkIconDispatcher darkIconDispatcher,
|
||||
StatusBarWindowController statusBarWindowController,
|
||||
FeatureFlags featureFlags, StatusBarWindowController statusBarWindowController,
|
||||
ScreenOffAnimationController screenOffAnimationController) {
|
||||
mContrastColorUtil = ContrastColorUtil.getInstance(context);
|
||||
mContext = context;
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mFeatureFlags = featureFlags;
|
||||
mStatusBarStateController.addCallback(this);
|
||||
mMediaManager = notificationMediaManager;
|
||||
mDozeParameters = dozeParameters;
|
||||
@@ -192,9 +196,16 @@ public class NotificationIconAreaController implements
|
||||
}
|
||||
|
||||
public void setupShelf(NotificationShelfController notificationShelfController) {
|
||||
NotificationShelfController.assertRefactorFlagDisabled(mFeatureFlags);
|
||||
mShelfIcons = notificationShelfController.getShelfIcons();
|
||||
}
|
||||
|
||||
public void setShelfIcons(NotificationIconContainer icons) {
|
||||
if (NotificationShelfController.checkRefactorFlagEnabled(mFeatureFlags)) {
|
||||
mShelfIcons = icons;
|
||||
}
|
||||
}
|
||||
|
||||
public void onDensityOrFontScaleChanged(Context context) {
|
||||
updateIconLayoutParams(context);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import android.util.Slog;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.systemui.InitController;
|
||||
import com.android.systemui.R;
|
||||
@@ -58,14 +57,12 @@ import com.android.systemui.statusbar.notification.collection.inflation.Notifica
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
|
||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
|
||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
|
||||
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
|
||||
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
|
||||
@@ -84,7 +81,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
||||
private final NotifShadeEventSource mNotifShadeEventSource;
|
||||
private final NotificationMediaManager mMediaManager;
|
||||
private final NotificationGutsManager mGutsManager;
|
||||
private final LockscreenGestureLogger mLockscreenGestureLogger;
|
||||
|
||||
private final NotificationPanelViewController mNotificationPanel;
|
||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||
@@ -151,7 +147,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
||||
mNotifShadeEventSource = notifShadeEventSource;
|
||||
mMediaManager = notificationMediaManager;
|
||||
mGutsManager = notificationGutsManager;
|
||||
mLockscreenGestureLogger = lockscreenGestureLogger;
|
||||
mAboveShelfObserver = new AboveShelfObserver(stackScrollerController.getView());
|
||||
mNotificationShadeWindowController = notificationShadeWindowController;
|
||||
mNotifPipelineFlags = notifPipelineFlags;
|
||||
@@ -238,34 +233,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
||||
return mNotificationPanel.isFullyCollapsed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivated(ActivatableNotificationView view) {
|
||||
onActivated();
|
||||
if (view != null) {
|
||||
mNotificationPanel.getShadeNotificationPresenter().setActivatedChild(view);
|
||||
}
|
||||
}
|
||||
|
||||
public void onActivated() {
|
||||
mLockscreenGestureLogger.write(
|
||||
MetricsEvent.ACTION_LS_NOTE,
|
||||
0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
|
||||
mLockscreenGestureLogger.log(LockscreenUiEvent.LOCKSCREEN_NOTIFICATION_FALSE_TOUCH);
|
||||
ActivatableNotificationView previousView =
|
||||
mNotificationPanel.getShadeNotificationPresenter().getActivatedChild();
|
||||
if (previousView != null) {
|
||||
previousView.makeInactive(true /* animate */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivationReset(ActivatableNotificationView view) {
|
||||
if (view == mNotificationPanel.getShadeNotificationPresenter().getActivatedChild()) {
|
||||
mNotificationPanel.getShadeNotificationPresenter().setActivatedChild(null);
|
||||
mKeyguardIndicationController.hideTransientIndication();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
|
||||
mMediaManager.updateMediaMetaData(metaDataChanged, allowEnterAnimation);
|
||||
@@ -276,7 +243,7 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
|
||||
boolean nowExpanded) {
|
||||
mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
|
||||
mCentralSurfaces.wakeUpIfDozing(
|
||||
SystemClock.uptimeMillis(), clickedView, "NOTIFICATION_CLICK",
|
||||
SystemClock.uptimeMillis(), "NOTIFICATION_CLICK",
|
||||
PowerManager.WAKE_REASON_GESTURE);
|
||||
if (nowExpanded) {
|
||||
if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
|
||||
|
||||
@@ -21,9 +21,7 @@ import android.content.ContentResolver;
|
||||
import android.os.Handler;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewStub;
|
||||
|
||||
import androidx.constraintlayout.motion.widget.MotionLayout;
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.LockIconView;
|
||||
import com.android.systemui.R;
|
||||
@@ -52,6 +50,7 @@ import com.android.systemui.statusbar.OperatorNameViewController;
|
||||
import com.android.systemui.statusbar.core.StatusBarInitializer.OnStatusBarViewInitializedListener;
|
||||
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
|
||||
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
|
||||
import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModelModule;
|
||||
import com.android.systemui.statusbar.notification.shelf.ui.viewbinder.NotificationShelfViewBinderWrapperControllerImpl;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
|
||||
@@ -75,18 +74,16 @@ import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.util.CarrierConfigTracker;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.IntoSet;
|
||||
import java.util.concurrent.Executor;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
|
||||
@Module(subcomponents = StatusBarFragmentComponent.class)
|
||||
@Module(subcomponents = StatusBarFragmentComponent.class,
|
||||
includes = { ActivatableNotificationViewModelModule.class })
|
||||
public abstract class StatusBarViewModule {
|
||||
|
||||
public static final String SHADE_HEADER = "large_screen_shade_header";
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
||||
package com.android.systemui.accessibility.data.repository
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.view.accessibility.AccessibilityManager
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.android.systemui.util.mockito.withArgCaptor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoRule
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
class AccessibilityRepositoryTest : SysuiTestCase() {
|
||||
|
||||
@Rule @JvmField val mockitoRule: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
// mocks
|
||||
@Mock private lateinit var a11yManager: AccessibilityManager
|
||||
|
||||
// real impls
|
||||
private val underTest by lazy { AccessibilityRepository(a11yManager) }
|
||||
|
||||
@Test
|
||||
fun isTouchExplorationEnabled_reflectsA11yManager_initFalse() = runTest {
|
||||
whenever(a11yManager.isTouchExplorationEnabled).thenReturn(false)
|
||||
val isTouchExplorationEnabled by collectLastValue(underTest.isTouchExplorationEnabled)
|
||||
assertThat(isTouchExplorationEnabled).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isTouchExplorationEnabled_reflectsA11yManager_initTrue() = runTest {
|
||||
whenever(a11yManager.isTouchExplorationEnabled).thenReturn(true)
|
||||
val isTouchExplorationEnabled by collectLastValue(underTest.isTouchExplorationEnabled)
|
||||
assertThat(isTouchExplorationEnabled).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isTouchExplorationEnabled_reflectsA11yManager_changeTrue() = runTest {
|
||||
whenever(a11yManager.isTouchExplorationEnabled).thenReturn(false)
|
||||
val isTouchExplorationEnabled by collectLastValue(underTest.isTouchExplorationEnabled)
|
||||
runCurrent()
|
||||
withArgCaptor { verify(a11yManager).addTouchExplorationStateChangeListener(capture()) }
|
||||
.onTouchExplorationStateChanged(/* enabled = */ true)
|
||||
assertThat(isTouchExplorationEnabled).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isTouchExplorationEnabled_reflectsA11yManager_changeFalse() = runTest {
|
||||
whenever(a11yManager.isTouchExplorationEnabled).thenReturn(true)
|
||||
val isTouchExplorationEnabled by collectLastValue(underTest.isTouchExplorationEnabled)
|
||||
runCurrent()
|
||||
withArgCaptor { verify(a11yManager).addTouchExplorationStateChangeListener(capture()) }
|
||||
.onTouchExplorationStateChanged(/* enabled = */ false)
|
||||
assertThat(isTouchExplorationEnabled).isFalse()
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,11 @@
|
||||
package com.android.systemui.shade
|
||||
|
||||
import android.hardware.display.AmbientDisplayConfiguration
|
||||
import android.os.PowerManager
|
||||
import android.provider.Settings.Secure.DOZE_DOUBLE_TAP_GESTURE
|
||||
import android.provider.Settings.Secure.DOZE_TAP_SCREEN_GESTURE
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper.RunWithLooper
|
||||
import android.os.PowerManager
|
||||
import android.view.MotionEvent
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
@@ -38,15 +38,14 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.ArgumentMatchers.anyLong
|
||||
import org.mockito.ArgumentMatchers.anyString
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@RunWithLooper(setAsMainLooper = true)
|
||||
@@ -112,7 +111,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
// THEN wake up device if dozing
|
||||
verify(centralSurfaces).wakeUpIfDozing(
|
||||
anyLong(), any(), anyString(), eq(PowerManager.WAKE_REASON_TAP))
|
||||
anyLong(), anyString(), eq(PowerManager.WAKE_REASON_TAP))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -132,7 +131,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
// THEN wake up device if dozing
|
||||
verify(centralSurfaces).wakeUpIfDozing(
|
||||
anyLong(), any(), anyString(), eq(PowerManager.WAKE_REASON_TAP))
|
||||
anyLong(), anyString(), eq(PowerManager.WAKE_REASON_TAP))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -164,7 +163,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
// THEN the device doesn't wake up
|
||||
verify(centralSurfaces, never()).wakeUpIfDozing(
|
||||
anyLong(), any(), anyString(), anyInt())
|
||||
anyLong(), anyString(), anyInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -212,7 +211,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
// THEN the device doesn't wake up
|
||||
verify(centralSurfaces, never()).wakeUpIfDozing(
|
||||
anyLong(), any(), anyString(), anyInt())
|
||||
anyLong(), anyString(), anyInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -232,7 +231,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
// THEN the device doesn't wake up
|
||||
verify(centralSurfaces, never()).wakeUpIfDozing(
|
||||
anyLong(), any(), anyString(), anyInt())
|
||||
anyLong(), anyString(), anyInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -252,7 +251,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
// THEN the device doesn't wake up
|
||||
verify(centralSurfaces, never()).wakeUpIfDozing(
|
||||
anyLong(), any(), anyString(), anyInt())
|
||||
anyLong(), anyString(), anyInt())
|
||||
}
|
||||
|
||||
fun updateSettings() {
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
||||
package com.android.systemui.statusbar.notification.row.ui.viewmodel
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.accessibility.data.repository.FakeAccessibilityRepository
|
||||
import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
class ActivatableNotificationViewModelTest : SysuiTestCase() {
|
||||
|
||||
// fakes
|
||||
private val a11yRepo = FakeAccessibilityRepository()
|
||||
|
||||
// real impls
|
||||
private val a11yInteractor = AccessibilityInteractor(a11yRepo)
|
||||
private val underTest = ActivatableNotificationViewModel(a11yInteractor)
|
||||
|
||||
@Test
|
||||
fun isTouchable_whenA11yTouchExplorationDisabled() = runTest {
|
||||
a11yRepo.isTouchExplorationEnabled.value = false
|
||||
val isTouchable: Boolean? by collectLastValue(underTest.isTouchable)
|
||||
assertThat(isTouchable).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isNotTouchable_whenA11yTouchExplorationEnabled() = runTest {
|
||||
a11yRepo.isTouchExplorationEnabled.value = true
|
||||
val isTouchable: Boolean? by collectLastValue(underTest.isTouchable)
|
||||
assertThat(isTouchable).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isTouchable_whenA11yTouchExplorationChangesToDisabled() = runTest {
|
||||
a11yRepo.isTouchExplorationEnabled.value = true
|
||||
val isTouchable: Boolean? by collectLastValue(underTest.isTouchable)
|
||||
runCurrent()
|
||||
a11yRepo.isTouchExplorationEnabled.value = false
|
||||
assertThat(isTouchable).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isNotTouchable_whenA11yTouchExplorationChangesToEnabled() = runTest {
|
||||
a11yRepo.isTouchExplorationEnabled.value = false
|
||||
val isTouchable: Boolean? by collectLastValue(underTest.isTouchable)
|
||||
runCurrent()
|
||||
a11yRepo.isTouchExplorationEnabled.value = true
|
||||
assertThat(isTouchable).isFalse()
|
||||
}
|
||||
}
|
||||
@@ -18,17 +18,27 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.shelf.domain.interactor
|
||||
|
||||
import android.os.PowerManager
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController
|
||||
import com.android.systemui.statusbar.phone.CentralSurfaces
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.anyLong
|
||||
import org.mockito.Mockito.isNull
|
||||
import org.mockito.Mockito.verify
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
@@ -36,8 +46,17 @@ class NotificationShelfInteractorTest : SysuiTestCase() {
|
||||
|
||||
private val keyguardRepository = FakeKeyguardRepository()
|
||||
private val deviceEntryFaceAuthRepository = FakeDeviceEntryFaceAuthRepository()
|
||||
private val centralSurfaces: CentralSurfaces = mock()
|
||||
private val systemClock = FakeSystemClock()
|
||||
private val keyguardTransitionController: LockscreenShadeTransitionController = mock()
|
||||
private val underTest =
|
||||
NotificationShelfInteractor(keyguardRepository, deviceEntryFaceAuthRepository)
|
||||
NotificationShelfInteractor(
|
||||
keyguardRepository,
|
||||
deviceEntryFaceAuthRepository,
|
||||
centralSurfaces,
|
||||
systemClock,
|
||||
keyguardTransitionController,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun shelfIsNotStatic_whenKeyguardNotShowing() = runTest {
|
||||
@@ -85,4 +104,19 @@ class NotificationShelfInteractorTest : SysuiTestCase() {
|
||||
|
||||
assertThat(onKeyguard).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun goToLockedShadeFromShelf_wakesUpFromDoze() {
|
||||
underTest.goToLockedShadeFromShelf()
|
||||
|
||||
verify(centralSurfaces)
|
||||
.wakeUpIfDozing(anyLong(), any(), eq(PowerManager.WAKE_REASON_GESTURE))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun goToLockedShadeFromShelf_invokesKeyguardTransitionController() {
|
||||
underTest.goToLockedShadeFromShelf()
|
||||
|
||||
verify(keyguardTransitionController).goToLockedShade(isNull(), eq(true))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,28 +18,64 @@
|
||||
|
||||
package com.android.systemui.statusbar.notification.shelf.ui.viewmodel
|
||||
|
||||
import android.os.PowerManager
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.accessibility.data.repository.FakeAccessibilityRepository
|
||||
import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFaceAuthRepository
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||
import com.android.systemui.statusbar.LockscreenShadeTransitionController
|
||||
import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModel
|
||||
import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor
|
||||
import com.android.systemui.statusbar.phone.CentralSurfaces
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoRule
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
class NotificationShelfViewModelTest : SysuiTestCase() {
|
||||
|
||||
@Rule @JvmField val mockitoRule: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
// mocks
|
||||
@Mock private lateinit var centralSurfaces: CentralSurfaces
|
||||
@Mock private lateinit var keyguardTransitionController: LockscreenShadeTransitionController
|
||||
|
||||
// fakes
|
||||
private val keyguardRepository = FakeKeyguardRepository()
|
||||
private val deviceEntryFaceAuthRepository = FakeDeviceEntryFaceAuthRepository()
|
||||
private val interactor =
|
||||
NotificationShelfInteractor(keyguardRepository, deviceEntryFaceAuthRepository)
|
||||
private val underTest = NotificationShelfViewModel(interactor)
|
||||
private val systemClock = FakeSystemClock()
|
||||
private val a11yRepo = FakeAccessibilityRepository()
|
||||
|
||||
// real impls
|
||||
private val a11yInteractor = AccessibilityInteractor(a11yRepo)
|
||||
private val activatableViewModel = ActivatableNotificationViewModel(a11yInteractor)
|
||||
private val interactor by lazy {
|
||||
NotificationShelfInteractor(
|
||||
keyguardRepository,
|
||||
deviceEntryFaceAuthRepository,
|
||||
centralSurfaces,
|
||||
systemClock,
|
||||
keyguardTransitionController,
|
||||
)
|
||||
}
|
||||
private val underTest by lazy { NotificationShelfViewModel(interactor, activatableViewModel) }
|
||||
|
||||
@Test
|
||||
fun canModifyColorOfNotifications_whenKeyguardNotShowing() = runTest {
|
||||
@@ -87,4 +123,13 @@ class NotificationShelfViewModelTest : SysuiTestCase() {
|
||||
|
||||
assertThat(isClickable).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onClicked_goesToLockedShade() {
|
||||
underTest.onShelfClicked()
|
||||
|
||||
verify(centralSurfaces)
|
||||
.wakeUpIfDozing(ArgumentMatchers.anyLong(), any(), eq(PowerManager.WAKE_REASON_GESTURE))
|
||||
verify(keyguardTransitionController).goToLockedShade(Mockito.isNull(), eq(true))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,7 +387,6 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
||||
when(mStackScroller.generateLayoutParams(any())).thenReturn(new LayoutParams(0, 0));
|
||||
when(mNotificationPanelView.getLayoutParams()).thenReturn(new LayoutParams(0, 0));
|
||||
when(mPowerManagerService.isInteractive()).thenReturn(true);
|
||||
when(mStackScroller.getActivatedChild()).thenReturn(null);
|
||||
|
||||
doAnswer(invocation -> {
|
||||
OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
|
||||
@@ -1327,7 +1326,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
||||
|
||||
// WHEN wakeup is requested
|
||||
final int wakeReason = PowerManager.WAKE_REASON_TAP;
|
||||
mCentralSurfaces.wakeUpIfDozing(0, null, "", wakeReason);
|
||||
mCentralSurfaces.wakeUpIfDozing(0, "", wakeReason);
|
||||
|
||||
// THEN power manager receives wakeup
|
||||
verify(mPowerManagerService).wakeUp(eq(0L), eq(wakeReason), anyString(), anyString());
|
||||
@@ -1341,7 +1340,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
|
||||
|
||||
// WHEN wakeup is requested
|
||||
final int wakeReason = PowerManager.WAKE_REASON_TAP;
|
||||
mCentralSurfaces.wakeUpIfDozing(0, null, "", wakeReason);
|
||||
mCentralSurfaces.wakeUpIfDozing(0, "", wakeReason);
|
||||
|
||||
// THEN power manager receives wakeup
|
||||
verify(mPowerManagerService, never()).wakeUp(anyLong(), anyInt(), anyString(), anyString());
|
||||
|
||||
@@ -27,6 +27,7 @@ import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.demomode.DemoModeController;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.plugins.DarkIconDispatcher;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
@@ -75,6 +76,8 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase {
|
||||
@Mock private DemoModeController mDemoModeController;
|
||||
@Mock
|
||||
private NotificationIconContainer mAodIcons;
|
||||
@Mock
|
||||
private FeatureFlags mFeatureFlags;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@@ -91,6 +94,7 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase {
|
||||
Optional.of(mBubbles),
|
||||
mDemoModeController,
|
||||
mDarkIconDispatcher,
|
||||
mFeatureFlags,
|
||||
mStatusBarWindowController,
|
||||
mScreenOffAnimationController);
|
||||
}
|
||||
|
||||
@@ -25,15 +25,12 @@ import static org.mockito.Mockito.when;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.StatusBarManager;
|
||||
import android.metrics.LogMaker;
|
||||
import android.support.test.metricshelper.MetricsAsserts;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.logging.testing.FakeMetricsLogger;
|
||||
import com.android.systemui.ForegroundServiceNotificationListener;
|
||||
import com.android.systemui.InitController;
|
||||
@@ -61,7 +58,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB
|
||||
import com.android.systemui.statusbar.notification.collection.render.NotifShadeEventSource;
|
||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
|
||||
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
|
||||
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
|
||||
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
|
||||
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
|
||||
@@ -283,15 +279,4 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
|
||||
assertTrue("CentralSurfaces alerts disabled shouldn't allow interruptions",
|
||||
mInterruptSuppressor.suppressInterruptions(entry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActivatedMetrics() {
|
||||
ActivatableNotificationView view = mock(ActivatableNotificationView.class);
|
||||
mStatusBarNotificationPresenter.onActivated(view);
|
||||
|
||||
MetricsAsserts.assertHasLog("missing lockscreen note tap log",
|
||||
mMetricsLogger.getLogs(),
|
||||
new LogMaker(MetricsEvent.ACTION_LS_NOTE)
|
||||
.setType(MetricsEvent.TYPE_ACTION));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.accessibility.data.repository
|
||||
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class FakeAccessibilityRepository(
|
||||
override val isTouchExplorationEnabled: MutableStateFlow<Boolean> = MutableStateFlow(false)
|
||||
) : AccessibilityRepository
|
||||
Reference in New Issue
Block a user