diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index 53a23b89f9434..0ec739fecaa72 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -30,6 +30,7 @@ import android.view.IWindowManager; import android.view.LayoutInflater; import com.android.internal.logging.MetricsLogger; +import com.android.internal.util.NotificationMessagingUtil; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.dagger.qualifiers.Background; @@ -191,6 +192,12 @@ public class DependencyProvider { return new AlwaysOnDisplayPolicy(context); } + /***/ + @Provides + public NotificationMessagingUtil provideNotificationMessagingUtil(Context context) { + return new NotificationMessagingUtil(context); + } + /** */ @Provides public ViewMediatorCallback providesViewMediatorCallback(KeyguardViewMediator viewMediator) { diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index 7b541991088cd..f068d9c10e86f 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -40,6 +40,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.Notifica import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl; import com.android.systemui.statusbar.notification.dagger.NotificationsModule; import com.android.systemui.statusbar.notification.people.PeopleHubModule; +import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent; import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent; import com.android.systemui.statusbar.phone.KeyguardLiftController; import com.android.systemui.statusbar.phone.StatusBar; @@ -68,7 +69,9 @@ import dagger.Provides; NotificationsModule.class, PeopleHubModule.class, }, - subcomponents = {StatusBarComponent.class, NotificationRowComponent.class}) + subcomponents = {StatusBarComponent.class, + NotificationRowComponent.class, + ExpandableNotificationRowComponent.class}) public abstract class SystemUIModule { @Binds diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java index 5dbf47e294076..a489f3b220314 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java @@ -68,6 +68,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter; import com.android.systemui.statusbar.notification.collection.notifcollection.NotifLifetimeExtender; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController; import com.android.systemui.statusbar.notification.row.NotificationGuts; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag; import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager; @@ -149,6 +150,7 @@ public final class NotificationEntry extends ListEntry { private NotificationEntry parent; // our parent (if we're in a group) private ExpandableNotificationRow row; // the outer expanded view + private ExpandableNotificationRowController mRowController; private int mCachedContrastColor = COLOR_INVALID; private int mCachedContrastColorIsFor = COLOR_INVALID; @@ -420,6 +422,14 @@ public final class NotificationEntry extends ListEntry { this.row = row; } + public ExpandableNotificationRowController getRowController() { + return mRowController; + } + + public void setRowController(ExpandableNotificationRowController controller) { + mRowController = controller; + } + @Nullable public List getChildren() { if (row == null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java index ecf62db4680bd..e8a62e48e75e4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotificationRowBinderImpl.java @@ -17,7 +17,6 @@ package com.android.systemui.statusbar.notification.collection.inflation; import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; -import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT; import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP; import android.annotation.Nullable; @@ -40,19 +39,19 @@ import com.android.systemui.statusbar.notification.InflationException; import com.android.systemui.statusbar.notification.NotificationClicker; import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider; import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController; import com.android.systemui.statusbar.notification.row.NotifBindPipeline; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder; import com.android.systemui.statusbar.notification.row.RowContentBindParams; import com.android.systemui.statusbar.notification.row.RowContentBindStage; import com.android.systemui.statusbar.notification.row.RowInflaterTask; +import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.StatusBar; -import com.android.systemui.statusbar.policy.HeadsUpManager; import java.util.Objects; @@ -67,35 +66,28 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { private static final String TAG = "NotificationViewManager"; - private final NotificationGroupManager mGroupManager; - private final NotificationGutsManager mGutsManager; private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider; private final Context mContext; private final NotifBindPipeline mNotifBindPipeline; private final RowContentBindStage mRowContentBindStage; private final NotificationMessagingUtil mMessagingUtil; - private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger = - this::logNotificationExpansion; private final NotificationRemoteInputManager mNotificationRemoteInputManager; private final NotificationLockscreenUserManager mNotificationLockscreenUserManager; - private final boolean mAllowLongPress; - private final KeyguardBypassController mKeyguardBypassController; - private final StatusBarStateController mStatusBarStateController; private NotificationPresenter mPresenter; private NotificationListContainer mListContainer; - private HeadsUpManager mHeadsUpManager; private NotificationRowContentBinder.InflationCallback mInflationCallback; - private ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener; private BindRowCallback mBindRowCallback; private NotificationClicker mNotificationClicker; private final Provider mRowInflaterTaskProvider; - private final NotificationLogger mNotificationLogger; + private final ExpandableNotificationRowComponent.Builder + mExpandableNotificationRowComponentBuilder; @Inject public NotificationRowBinderImpl( Context context, + NotificationMessagingUtil notificationMessagingUtil, NotificationRemoteInputManager notificationRemoteInputManager, NotificationLockscreenUserManager notificationLockscreenUserManager, NotifBindPipeline notifBindPipeline, @@ -107,21 +99,16 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { NotificationGutsManager notificationGutsManager, NotificationInterruptionStateProvider notificationInterruptionStateProvider, Provider rowInflaterTaskProvider, - NotificationLogger logger) { + ExpandableNotificationRowComponent.Builder expandableNotificationRowComponentBuilder) { mContext = context; mNotifBindPipeline = notifBindPipeline; mRowContentBindStage = rowContentBindStage; - mMessagingUtil = new NotificationMessagingUtil(context); + mMessagingUtil = notificationMessagingUtil; mNotificationRemoteInputManager = notificationRemoteInputManager; mNotificationLockscreenUserManager = notificationLockscreenUserManager; - mAllowLongPress = allowLongPress; - mKeyguardBypassController = keyguardBypassController; - mStatusBarStateController = statusBarStateController; - mGroupManager = notificationGroupManager; - mGutsManager = notificationGutsManager; mNotificationInterruptionStateProvider = notificationInterruptionStateProvider; mRowInflaterTaskProvider = rowInflaterTaskProvider; - mNotificationLogger = logger; + mExpandableNotificationRowComponentBuilder = expandableNotificationRowComponentBuilder; } /** @@ -129,13 +116,10 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { */ public void setUpWithPresenter(NotificationPresenter presenter, NotificationListContainer listContainer, - HeadsUpManager headsUpManager, BindRowCallback bindRowCallback) { mPresenter = presenter; mListContainer = listContainer; - mHeadsUpManager = headsUpManager; mBindRowCallback = bindRowCallback; - mOnAppOpsClickListener = mGutsManager::openGuts; } public void setInflationCallback(NotificationRowContentBinder.InflationCallback callback) { @@ -150,9 +134,7 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { * Inflates the views for the given entry (possibly asynchronously). */ @Override - public void inflateViews( - NotificationEntry entry, - Runnable onDismissRunnable) + public void inflateViews(NotificationEntry entry, Runnable onDismissRunnable) throws InflationException { ViewGroup parent = mListContainer.getViewParentForNotification(entry); PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext, @@ -163,12 +145,26 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { entry.updateIcons(mContext, sbn); entry.reset(); updateNotification(entry, pmUser, sbn, entry.getRow()); - entry.getRow().setOnDismissRunnable(onDismissRunnable); + entry.getRowController().setOnDismissRunnable(onDismissRunnable); } else { entry.createIcons(mContext, sbn); mRowInflaterTaskProvider.get().inflate(mContext, parent, entry, row -> { - bindRow(entry, pmUser, sbn, row, onDismissRunnable); + // Setup the controller for the view. + ExpandableNotificationRowComponent component = + mExpandableNotificationRowComponentBuilder + .expandableNotificationRow(row) + .notificationEntry(entry) + .onDismissRunnable(onDismissRunnable) + .inflationCallback(mInflationCallback) + .rowContentBindStage(mRowContentBindStage) + .onExpandClickListener(mPresenter) + .build(); + ExpandableNotificationRowController rowController = + component.getExpandableNotificationRowController(); + rowController.init(); + entry.setRowController(rowController); + bindRow(entry, pmUser, sbn, row); updateNotification(entry, pmUser, sbn, row); }); } @@ -176,55 +172,12 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { //TODO: This method associates a row with an entry, but eventually needs to not do that private void bindRow(NotificationEntry entry, PackageManager pmUser, - StatusBarNotification sbn, ExpandableNotificationRow row, - Runnable onDismissRunnable) { - // Get the app name. - // Note that Notification.Builder#bindHeaderAppName has similar logic - // but since this field is used in the guts, it must be accurate. - // Therefore we will only show the application label, or, failing that, the - // package name. No substitutions. - final String pkg = sbn.getPackageName(); - String appname = pkg; - try { - final ApplicationInfo info = pmUser.getApplicationInfo(pkg, - PackageManager.MATCH_UNINSTALLED_PACKAGES - | PackageManager.MATCH_DISABLED_COMPONENTS); - if (info != null) { - appname = String.valueOf(pmUser.getApplicationLabel(info)); - } - } catch (PackageManager.NameNotFoundException e) { - // Do nothing - } - - row.initialize( - appname, - sbn.getKey(), - mExpansionLogger, - mKeyguardBypassController, - mGroupManager, - mHeadsUpManager, - mRowContentBindStage, - mPresenter); - - // TODO: Either move these into ExpandableNotificationRow#initialize or out of row entirely - row.setStatusBarStateController(mStatusBarStateController); - row.setAppOpsOnClickListener(mOnAppOpsClickListener); - if (mAllowLongPress) { - row.setLongPressListener(mGutsManager::openGuts); - } + StatusBarNotification sbn, ExpandableNotificationRow row) { mListContainer.bindRow(row); mNotificationRemoteInputManager.bindRow(row); - - row.setOnDismissRunnable(onDismissRunnable); - row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); - if (ENABLE_REMOTE_INPUT) { - row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); - } - entry.setRow(row); row.setEntry(entry); mNotifBindPipeline.manageRow(entry, row); - mBindRowCallback.onBindRow(entry, pmUser, sbn, row); } @@ -307,10 +260,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder { Objects.requireNonNull(mNotificationClicker).register(row, sbn); } - private void logNotificationExpansion(String key, boolean userAction, boolean expanded) { - mNotificationLogger.onExpansionChanged(key, userAction, expanded); - } - /** Callback for when a row is bound to an entry. */ public interface BindRowCallback { /** diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt index 254b64ffcd901..3e0bcbb796bff 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt @@ -90,7 +90,6 @@ class NotificationsControllerImpl @Inject constructor( notificationRowBinder.setUpWithPresenter( presenter, listContainer, - headsUpManager, bindRowCallback) if (featureFlags.isNewNotifPipelineEnabled) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java index 50a20374fee52..a6ef81d4612ce 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java @@ -29,20 +29,17 @@ import android.util.MathUtils; import android.view.MotionEvent; import android.view.View; import android.view.ViewAnimationUtils; -import android.view.accessibility.AccessibilityManager; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; -import com.android.systemui.Dependency; +import com.android.systemui.Gefingerpoken; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.NotificationShelf; import com.android.systemui.statusbar.notification.FakeShadowView; import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; import com.android.systemui.statusbar.notification.stack.StackStateAnimator; -import com.android.systemui.statusbar.phone.DoubleTapHelper; /** * Base class for both {@link ExpandableNotificationRow} and {@link NotificationShelf} @@ -94,14 +91,12 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR = new PathInterpolator(0, 0, 0.5f, 1); private int mTintedRippleColor; - protected int mNormalRippleColor; - private final AccessibilityManager mAccessibilityManager; - private final DoubleTapHelper mDoubleTapHelper; + private int mNormalRippleColor; + private Gefingerpoken mTouchHandler; private boolean mDimmed; - protected int mBgTint = NO_COLOR; - private float mBgAlpha = 1f; + int mBgTint = NO_COLOR; /** * Flag to indicate that the notification has been touched once and the second touch will @@ -116,7 +111,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private Interpolator mCurrentAppearInterpolator; private Interpolator mCurrentAlphaInterpolator; - protected NotificationBackgroundView mBackgroundNormal; + NotificationBackgroundView mBackgroundNormal; private NotificationBackgroundView mBackgroundDimmed; private ObjectAnimator mBackgroundAnimator; private RectF mAppearAnimationRect = new RectF(); @@ -130,7 +125,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private boolean mLastInSection; private boolean mFirstInSection; private boolean mIsBelowSpeedBump; - private final FalsingManager mFalsingManager; private float mNormalBackgroundVisibilityAmount; private float mDimmedBackgroundFadeInAmount = -1; @@ -154,38 +148,24 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView */ private boolean mNeedsDimming; private int mDimmedAlpha; - private boolean mBlockNextTouch; private boolean mIsHeadsUpAnimation; private int mHeadsUpAddStartLocation; private float mHeadsUpLocation; private boolean mIsAppearing; private boolean mDismissed; private boolean mRefocusOnDismiss; + private OnDimmedListener mOnDimmedListener; 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); - mFalsingManager = Dependency.get(FalsingManager.class); // TODO: inject into a controller. setClipChildren(false); setClipToPadding(false); updateColors(); - mAccessibilityManager = AccessibilityManager.getInstance(mContext); - - mDoubleTapHelper = new DoubleTapHelper(this, (active) -> { - if (active) { - makeActive(); - } else { - makeInactive(true /* animate */); - } - }, super::performClick, this::handleSlideBack, mFalsingManager::onNotificationDoubleTap); initDimens(); } - public FalsingManager getFalsingManager() { - return mFalsingManager; - } - private void updateColors() { mNormalColor = mContext.getColor(R.color.notification_material_background_color); mTintedRippleColor = mContext.getColor( @@ -236,32 +216,15 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundDimmed.setCustomBackground(R.drawable.notification_material_bg_dim); } - private final Runnable mTapTimeoutRunnable = new Runnable() { - @Override - public void run() { - makeInactive(true /* animate */); - } - }; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (mNeedsDimming && ev.getActionMasked() == MotionEvent.ACTION_DOWN - && disallowSingleClick(ev) && !isTouchExplorationEnabled()) { - if (!mActivated) { - return true; - } else if (!mDoubleTapHelper.isWithinDoubleTapSlop(ev)) { - mBlockNextTouch = true; - makeInactive(true /* animate */); - return true; - } + if (mTouchHandler != null && mTouchHandler.onInterceptTouchEvent(ev)) { + return true; } return super.onInterceptTouchEvent(ev); } - private boolean isTouchExplorationEnabled() { - return mAccessibilityManager.isTouchExplorationEnabled(); - } - protected boolean disallowSingleClick(MotionEvent ev) { return false; } @@ -270,25 +233,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView return false; } - @Override - public boolean onTouchEvent(MotionEvent event) { - boolean result; - if (mBlockNextTouch) { - mBlockNextTouch = false; - return false; - } - if (mNeedsDimming && !isTouchExplorationEnabled() && isInteractive()) { - boolean wasActivated = mActivated; - result = handleTouchEventDimmed(event); - if (wasActivated && result && event.getAction() == MotionEvent.ACTION_UP) { - removeCallbacks(mTapTimeoutRunnable); - } - } else { - result = super.onTouchEvent(event); - } - return result; - } - /** * @return whether this view is interactive and can be double tapped */ @@ -313,28 +257,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } } - public void setRippleAllowed(boolean allowed) { + void setRippleAllowed(boolean allowed) { mBackgroundNormal.setPressedAllowed(allowed); } - private boolean handleTouchEventDimmed(MotionEvent event) { - if (mNeedsDimming && !mDimmed) { - // We're actually dimmed, but our content isn't dimmable, let's ensure we have a ripple - super.onTouchEvent(event); - } - return mDoubleTapHelper.onTouchEvent(event, getActualHeight()); - } - - @Override - public boolean performClick() { - if (!mNeedsDimming || isTouchExplorationEnabled()) { - return super.performClick(); - } - return false; - } - - private void makeActive() { - mFalsingManager.onNotificationActive(); + void makeActive() { startActivateAnimation(false /* reverse */); mActivated = true; if (mOnActivatedListener != null) { @@ -388,15 +315,12 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundNormal.animate() .alpha(reverse ? 0f : 1f) .setInterpolator(alphaInterpolator) - .setUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - float animatedFraction = animation.getAnimatedFraction(); - if (reverse) { - animatedFraction = 1.0f - animatedFraction; - } - setNormalBackgroundVisibilityAmount(animatedFraction); + .setUpdateListener(animation -> { + float animatedFraction = animation.getAnimatedFraction(); + if (reverse) { + animatedFraction = 1.0f - animatedFraction; } + setNormalBackgroundVisibilityAmount(animatedFraction); }) .setDuration(ACTIVATE_ANIMATION_LENGTH); } @@ -418,11 +342,13 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView if (mOnActivatedListener != null) { mOnActivatedListener.onActivationReset(this); } - removeCallbacks(mTapTimeoutRunnable); } public void setDimmed(boolean dimmed, boolean fade) { mNeedsDimming = dimmed; + if (mOnDimmedListener != null) { + mOnDimmedListener.onSetDimmed(dimmed); + } dimmed &= isDimmable(); if (mDimmed != dimmed) { mDimmed = dimmed; @@ -439,13 +365,17 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView return true; } + public boolean isDimmed() { + return mDimmed; + } + private void updateOutlineAlpha() { float alpha = NotificationStackScrollLayout.BACKGROUND_ALPHA_DIMMED; alpha = (alpha + (1.0f - alpha) * mNormalBackgroundVisibilityAmount); setOutlineAlpha(alpha); } - public void setNormalBackgroundVisibilityAmount(float normalBackgroundVisibilityAmount) { + private void setNormalBackgroundVisibilityAmount(float normalBackgroundVisibilityAmount) { mNormalBackgroundVisibilityAmount = normalBackgroundVisibilityAmount; updateOutlineAlpha(); } @@ -473,14 +403,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView /** * Sets the tint color of the background */ - public void setTintColor(int color) { + protected void setTintColor(int color) { setTintColor(color, false); } /** * Sets the tint color of the background */ - public void setTintColor(int color, boolean animated) { + void setTintColor(int color, boolean animated) { if (color != mBgTint) { mBgTint = color; updateBackgroundTint(animated); @@ -562,13 +492,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mStartTint = mCurrentBackgroundTint; mTargetTint = color; mBackgroundColorAnimator = ValueAnimator.ofFloat(0.0f, 1.0f); - mBackgroundColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - int newColor = NotificationUtils.interpolateColors(mStartTint, mTargetTint, - animation.getAnimatedFraction()); - setBackgroundTintColor(newColor); - } + mBackgroundColorAnimator.addUpdateListener(animation -> { + int newColor = NotificationUtils.interpolateColors(mStartTint, mTargetTint, + animation.getAnimatedFraction()); + setBackgroundTintColor(newColor); }); mBackgroundColorAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); mBackgroundColorAnimator.setInterpolator(Interpolators.LINEAR); @@ -643,11 +570,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } protected void updateBackgroundAlpha(float transformationAmount) { - mBgAlpha = isChildInGroup() && mDimmed ? transformationAmount : 1f; + float bgAlpha = isChildInGroup() && mDimmed ? transformationAmount : 1f; if (mDimmedBackgroundFadeInAmount != -1) { - mBgAlpha *= mDimmedBackgroundFadeInAmount; + bgAlpha *= mDimmedBackgroundFadeInAmount; } - mBackgroundDimmed.setAlpha(mBgAlpha); + mBackgroundDimmed.setAlpha(bgAlpha); } protected void resetBackgroundAlpha() { @@ -671,7 +598,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundDimmed.setVisibility(View.INVISIBLE); mBackgroundNormal.setVisibility(View.VISIBLE); mBackgroundNormal.setAlpha(1f); - removeCallbacks(mTapTimeoutRunnable); // make in inactive to avoid it sticking around active makeInactive(false /* animate */); } @@ -783,14 +709,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mAppearAnimator.setInterpolator(Interpolators.LINEAR); mAppearAnimator.setDuration( (long) (duration * Math.abs(mAppearAnimationFraction - targetValue))); - mAppearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - mAppearAnimationFraction = (float) animation.getAnimatedValue(); - updateAppearAnimationAlpha(); - updateAppearRect(); - invalidate(); - } + mAppearAnimator.addUpdateListener(animation -> { + mAppearAnimationFraction = (float) animation.getAnimatedValue(); + updateAppearAnimationAlpha(); + updateAppearRect(); + invalidate(); }); if (animationListener != null) { mAppearAnimator.addListener(animationListener); @@ -921,7 +844,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView getCurrentBackgroundRadiusBottom()); } - protected void applyBackgroundRoundness(float topRadius, float bottomRadius) { + private void applyBackgroundRoundness(float topRadius, float bottomRadius) { mBackgroundDimmed.setRoundness(topRadius, bottomRadius); mBackgroundNormal.setRoundness(topRadius, bottomRadius); } @@ -963,7 +886,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView } } - protected int getRippleColor() { + private int getRippleColor() { if (mBgTint != 0) { return mTintedRippleColor; } else { @@ -1010,10 +933,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mOnActivatedListener = onActivatedListener; } - public boolean hasSameBgColor(ActivatableNotificationView otherView) { - return calculateBgColor() == otherView.calculateBgColor(); - } - @Override public void setFakeShadowIntensity(float shadowIntensity, float outlineAlpha, int shadowYEnd, int outlineTranslation) { @@ -1071,8 +990,20 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView return mRefocusOnDismiss || isAccessibilityFocused(); } + void setTouchHandler(Gefingerpoken touchHandler) { + mTouchHandler = touchHandler; + } + + void setOnDimmedListener(OnDimmedListener onDimmedListener) { + mOnDimmedListener = onDimmedListener; + } + public interface OnActivatedListener { void onActivated(ActivatableNotificationView view); void onActivationReset(ActivatableNotificationView view); } + + interface OnDimmedListener { + void onSetDimmed(boolean dimmed); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java index 18993ffec3577..a6a1a4a3a56bf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java @@ -16,9 +16,13 @@ package com.android.systemui.statusbar.notification.row; +import android.view.MotionEvent; +import android.view.View; import android.view.accessibility.AccessibilityManager; +import com.android.systemui.Gefingerpoken; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.statusbar.phone.DoubleTapHelper; import javax.inject.Inject; @@ -27,21 +31,106 @@ import javax.inject.Inject; */ public class ActivatableNotificationViewController { private final ActivatableNotificationView mView; + private final ExpandableOutlineViewController mExpandableOutlineViewController; private final AccessibilityManager mAccessibilityManager; private final FalsingManager mFalsingManager; + private DoubleTapHelper mDoubleTapHelper; + private boolean mNeedsDimming; + + private TouchHandler mTouchHandler = new TouchHandler(); @Inject public ActivatableNotificationViewController(ActivatableNotificationView view, + ExpandableOutlineViewController expandableOutlineViewController, AccessibilityManager accessibilityManager, FalsingManager falsingManager) { mView = view; + mExpandableOutlineViewController = expandableOutlineViewController; mAccessibilityManager = accessibilityManager; mFalsingManager = falsingManager; + + mView.setOnActivatedListener(new ActivatableNotificationView.OnActivatedListener() { + @Override + public void onActivated(ActivatableNotificationView view) { + mFalsingManager.onNotificationActive(); + } + + @Override + public void onActivationReset(ActivatableNotificationView view) { + } + }); } /** * Initialize the controller, setting up handlers and other behavior. */ public void init() { + mExpandableOutlineViewController.init(); + mDoubleTapHelper = new DoubleTapHelper(mView, (active) -> { + if (active) { + mView.makeActive(); + mFalsingManager.onNotificationActive(); + } else { + mView.makeInactive(true /* animate */); + } + }, mView::performClick, mView::handleSlideBack, mFalsingManager::onNotificationDoubleTap); + mView.setOnTouchListener(mTouchHandler); + mView.setTouchHandler(mTouchHandler); + mView.setOnDimmedListener(dimmed -> { + mNeedsDimming = dimmed; + if (dimmed && !mAccessibilityManager.isTouchExplorationEnabled()) { + mView.setOnClickListener(null); + } else { + mView.setOnClickListener((v) -> mView.performClick()); + } + }); + } + class TouchHandler implements Gefingerpoken, View.OnTouchListener { + private boolean mBlockNextTouch; + + @Override + public boolean onTouch(View v, MotionEvent ev) { + boolean result; + if (mBlockNextTouch) { + mBlockNextTouch = false; + return true; + } + if (mNeedsDimming && !mAccessibilityManager.isTouchExplorationEnabled() + && mView.isInteractive()) { + if (mNeedsDimming && !mView.isDimmed()) { + // We're actually dimmed, but our content isn't dimmable, + // let's ensure we have a ripple + return false; + } + result = mDoubleTapHelper.onTouchEvent(ev, mView.getActualHeight()); + } else { + return false; + } + return result; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (mNeedsDimming && ev.getActionMasked() == MotionEvent.ACTION_DOWN + && mView.disallowSingleClick(ev) + && !mAccessibilityManager.isTouchExplorationEnabled()) { + if (!mView.isActivated()) { + return true; + } else if (!mDoubleTapHelper.isWithinDoubleTapSlop(ev)) { + mBlockNextTouch = true; + mView.makeInactive(true /* animate */); + return true; + } + } + return false; + } + + /** + * Use {@link #onTouch(View, MotionEvent) instead}. + */ + @Override + public boolean onTouchEvent(MotionEvent ev) { + return false; + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java index c34bba782ad51..5517318245708 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java @@ -42,7 +42,6 @@ import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.os.SystemClock; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.AttributeSet; @@ -72,11 +71,11 @@ import com.android.internal.widget.CachingIconView; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.RemoteInputController; import com.android.systemui.statusbar.StatusBarIconView; @@ -199,6 +198,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private NotificationGuts mGuts; private NotificationEntry mEntry; private String mAppName; + private FalsingManager mFalsingManager; /** * Whether or not the notification is using the heads up view and should peek from the top. @@ -1086,20 +1086,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView } } - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - mEntry.setInitializationTime(SystemClock.elapsedRealtime()); - Dependency.get(PluginManager.class).addPluginListener(this, - NotificationMenuRowPlugin.class, false /* Allow multiple */); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - Dependency.get(PluginManager.class).removePluginListener(this); - } - @Override public void onPluginConnected(NotificationMenuRowPlugin plugin, Context pluginContext) { boolean existed = mMenuRow != null && mMenuRow.getMenuView() != null; @@ -1439,7 +1425,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mIsBlockingHelperShowing && mNotificationTranslationFinished; } - public void setOnDismissRunnable(Runnable onDismissRunnable) { + void setOnDismissRunnable(Runnable onDismissRunnable) { mOnDismissRunnable = onDismissRunnable; } @@ -1597,7 +1583,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mMenuRow = new NotificationMenuRow(mContext); mImageResolver = new NotificationInlineImageResolver(context, new NotificationInlineImageCache()); - mMediaManager = Dependency.get(NotificationMediaManager.class); initDimens(); } @@ -1612,7 +1597,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView NotificationGroupManager groupManager, HeadsUpManager headsUpManager, RowContentBindStage rowContentBindStage, - OnExpandClickListener onExpandClickListener) { + OnExpandClickListener onExpandClickListener, + NotificationMediaManager notificationMediaManager, + OnAppOpsClickListener onAppOpsClickListener, + FalsingManager falsingManager, + StatusBarStateController statusBarStateController) { mAppName = appName; if (mMenuRow != null && mMenuRow.getMenuView() != null) { mMenuRow.setAppName(mAppName); @@ -1625,9 +1614,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mHeadsUpManager = headsUpManager; mRowContentBindStage = rowContentBindStage; mOnExpandClickListener = onExpandClickListener; - } - - public void setStatusBarStateController(StatusBarStateController statusBarStateController) { + mMediaManager = notificationMediaManager; + setAppOpsOnClickListener(onAppOpsClickListener); + mFalsingManager = falsingManager; mStatusbarStateController = statusBarStateController; } @@ -1719,7 +1708,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView return mOnAppOpsClickListener; } - public void setAppOpsOnClickListener(ExpandableNotificationRow.OnAppOpsClickListener l) { + void setAppOpsOnClickListener(ExpandableNotificationRow.OnAppOpsClickListener l) { mOnAppOpsClickListener = v -> { createMenu(); NotificationMenuRowPlugin provider = getProvider(); @@ -2188,7 +2177,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView * @param allowChildExpansion whether a call to this method allows expanding children */ public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) { - getFalsingManager().setNotificationExpanded(); + mFalsingManager.setNotificationExpanded(); if (mIsSummaryWithChildren && !shouldShowPublic() && allowChildExpansion && !mChildrenContainer.showingAsLowPriority()) { final boolean wasExpanded = mGroupManager.isGroupExpanded(mEntry.getSbn()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java new file mode 100644 index 0000000000000..39fab439ad071 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row; + +import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME; +import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT; + +import android.view.View; +import android.view.ViewGroup; + +import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; +import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shared.plugins.PluginManager; +import com.android.systemui.statusbar.NotificationMediaManager; +import com.android.systemui.statusbar.notification.logging.NotificationLogger; +import com.android.systemui.statusbar.notification.row.dagger.AppName; +import com.android.systemui.statusbar.notification.row.dagger.DismissRunnable; +import com.android.systemui.statusbar.notification.row.dagger.NotificationKey; +import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope; +import com.android.systemui.statusbar.phone.KeyguardBypassController; +import com.android.systemui.statusbar.phone.NotificationGroupManager; +import com.android.systemui.statusbar.policy.HeadsUpManager; +import com.android.systemui.util.time.SystemClock; + +import javax.inject.Inject; +import javax.inject.Named; + +/** + * Controller for {@link ExpandableNotificationRow}. + */ +@NotificationRowScope +public class ExpandableNotificationRowController { + private final ExpandableNotificationRow mView; + private final ActivatableNotificationViewController mActivatableNotificationViewController; + private final NotificationMediaManager mMediaManager; + private final PluginManager mPluginManager; + private final SystemClock mClock; + private final String mAppName; + private final String mNotificationKey; + private final KeyguardBypassController mKeyguardBypassController; + private final NotificationGroupManager mNotificationGroupManager; + private final RowContentBindStage mRowContentBindStage; + private final NotificationLogger mNotificationLogger; + private final HeadsUpManager mHeadsUpManager; + private final ExpandableNotificationRow.OnExpandClickListener mOnExpandClickListener; + private final StatusBarStateController mStatusBarStateController; + private final NotificationRowContentBinder.InflationCallback mInflationCallback; + + private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger = + this::logNotificationExpansion; + private final ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener; + private final NotificationGutsManager mNotificationGutsManager; + private Runnable mOnDismissRunnable; + private final FalsingManager mFalsingManager; + private final boolean mAllowLongPress; + + @Inject + public ExpandableNotificationRowController(ExpandableNotificationRow view, + ActivatableNotificationViewController activatableNotificationViewController, + NotificationMediaManager mediaManager, PluginManager pluginManager, + SystemClock clock, @AppName String appName, @NotificationKey String notificationKey, + KeyguardBypassController keyguardBypassController, + NotificationGroupManager notificationGroupManager, + RowContentBindStage rowContentBindStage, + NotificationLogger notificationLogger, HeadsUpManager headsUpManager, + ExpandableNotificationRow.OnExpandClickListener onExpandClickListener, + StatusBarStateController statusBarStateController, + NotificationRowContentBinder.InflationCallback inflationCallback, + NotificationGutsManager notificationGutsManager, + @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress, + @DismissRunnable Runnable onDismissRunnable, FalsingManager falsingManager) { + mView = view; + mActivatableNotificationViewController = activatableNotificationViewController; + mMediaManager = mediaManager; + mPluginManager = pluginManager; + mClock = clock; + mAppName = appName; + mNotificationKey = notificationKey; + mKeyguardBypassController = keyguardBypassController; + mNotificationGroupManager = notificationGroupManager; + mRowContentBindStage = rowContentBindStage; + mNotificationLogger = notificationLogger; + mHeadsUpManager = headsUpManager; + mOnExpandClickListener = onExpandClickListener; + mStatusBarStateController = statusBarStateController; + mInflationCallback = inflationCallback; + mNotificationGutsManager = notificationGutsManager; + mOnDismissRunnable = onDismissRunnable; + mOnAppOpsClickListener = mNotificationGutsManager::openGuts; + mAllowLongPress = allowLongPress; + mFalsingManager = falsingManager; + } + + /** + * Initialize the controller. + */ + public void init() { + mActivatableNotificationViewController.init(); + mView.initialize( + mAppName, + mNotificationKey, + mExpansionLogger, + mKeyguardBypassController, + mNotificationGroupManager, + mHeadsUpManager, + mRowContentBindStage, + mOnExpandClickListener, + mMediaManager, + mOnAppOpsClickListener, + mFalsingManager, + mStatusBarStateController + ); + mView.setOnDismissRunnable(mOnDismissRunnable); + mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); + if (mAllowLongPress) { + mView.setLongPressListener(mNotificationGutsManager::openGuts); + } + if (ENABLE_REMOTE_INPUT) { + mView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); + } + + mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { + @Override + public void onViewAttachedToWindow(View v) { + mView.getEntry().setInitializationTime(mClock.elapsedRealtime()); + mPluginManager.addPluginListener(mView, + NotificationMenuRowPlugin.class, false /* Allow multiple */); + } + + @Override + public void onViewDetachedFromWindow(View v) { + mPluginManager.removePluginListener(mView); + } + }); + } + + private void logNotificationExpansion(String key, boolean userAction, boolean expanded) { + mNotificationLogger.onExpansionChanged(key, userAction, expanded); + } + + /** */ + public void setOnDismissRunnable(Runnable onDismissRunnable) { + mOnDismissRunnable = onDismissRunnable; + mView.setOnDismissRunnable(onDismissRunnable); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineViewController.java new file mode 100644 index 0000000000000..75c9d1e6f2fc7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableOutlineViewController.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row; + +import javax.inject.Inject; + +/** + * Controller for {@link ExpandableOutlineView}. + */ +public class ExpandableOutlineViewController { + private final ExpandableOutlineView mView; + private final ExpandableViewController mExpandableViewController; + + @Inject + public ExpandableOutlineViewController(ExpandableOutlineView view, + ExpandableViewController expandableViewController) { + mView = view; + mExpandableViewController = expandableViewController; + } + + /** + * Initialize the controller. + */ + public void init() { + mExpandableViewController.init(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableViewController.java new file mode 100644 index 0000000000000..e14ca8c4e590e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableViewController.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row; + +import javax.inject.Inject; + +/** + * Controller for {@link ExpandableView}. + */ +public class ExpandableViewController { + private final ExpandableView mView; + + @Inject + public ExpandableViewController(ExpandableView view) { + mView = view; + } + + /** + * Initialize the controller. + */ + public void init() { + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java index c173b4dbaebe2..6feffe6546301 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java @@ -26,7 +26,6 @@ import androidx.asynclayoutinflater.view.AsyncLayoutInflater; import com.android.systemui.R; import com.android.systemui.statusbar.InflationTask; import com.android.systemui.statusbar.notification.collection.NotificationEntry; -import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent; import javax.inject.Inject; @@ -37,7 +36,6 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf private static final String TAG = "RowInflaterTask"; private static final boolean TRACE_ORIGIN = true; - private final NotificationRowComponent.Builder mNotificationRowComponentBuilder; private RowInflationFinishedListener mListener; private NotificationEntry mEntry; @@ -45,10 +43,7 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf private Throwable mInflateOrigin; @Inject - public RowInflaterTask( - NotificationRowComponent.Builder notificationRowComponentBuilder) { - super(); - mNotificationRowComponentBuilder = notificationRowComponentBuilder; + public RowInflaterTask() { } /** @@ -75,12 +70,6 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf public void onInflateFinished(View view, int resid, ViewGroup parent) { if (!mCancelled) { try { - // Setup the controller for the view. - NotificationRowComponent component = mNotificationRowComponentBuilder - .activatableNotificationView((ActivatableNotificationView) view) - .build(); - component.getActivatableNotificationViewController().init(); - mEntry.onInflationTaskFinished(); mListener.onInflationFinished((ExpandableNotificationRow) view); } catch (Throwable t) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ActivatableNotificationViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ActivatableNotificationViewModule.java new file mode 100644 index 0000000000000..a3dfa608c7098 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ActivatableNotificationViewModule.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row.dagger; + +import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; +import com.android.systemui.statusbar.notification.row.ExpandableOutlineView; +import com.android.systemui.statusbar.notification.row.ExpandableView; + +import dagger.Binds; +import dagger.Module; + +/** + * Module for NotificationRowComponent. + */ +@Module +public interface ActivatableNotificationViewModule { + /** ExpandableView is provided as an instance of ActivatableNotificationView. */ + @Binds + ExpandableView bindExpandableView(ActivatableNotificationView view); + /** ExpandableOutlineView is provided as an instance of ActivatableNotificationView. */ + @Binds + ExpandableOutlineView bindExpandableOutlineView(ActivatableNotificationView view); +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/AppName.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/AppName.java new file mode 100644 index 0000000000000..1dbca0cd5527a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/AppName.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row.dagger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Qualifier; + +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface AppName { +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java new file mode 100644 index 0000000000000..4331142242892 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/DismissRunnable.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row.dagger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Qualifier; + +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface DismissRunnable { +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java new file mode 100644 index 0000000000000..6d6d3e446f536 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/ExpandableNotificationRowComponent.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row.dagger; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.service.notification.StatusBarNotification; + +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.ExpandableNotificationRowController; +import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder; +import com.android.systemui.statusbar.notification.row.RowContentBindStage; +import com.android.systemui.statusbar.phone.StatusBar; + +import dagger.Binds; +import dagger.BindsInstance; +import dagger.Module; +import dagger.Provides; +import dagger.Subcomponent; + +/** + * Dagger Component for a {@link ExpandableNotificationRow}. + */ +@Subcomponent(modules = {ExpandableNotificationRowComponent.ExpandableNotificationRowModule.class, + ActivatableNotificationViewModule.class}) +@NotificationRowScope +public interface ExpandableNotificationRowComponent { + + /** + * Builder for {@link NotificationRowComponent}. + */ + @Subcomponent.Builder + interface Builder { + // TODO: NotificationEntry contains a reference to ExpandableNotificationRow, so it + // should be possible to pull one from the other, but they aren't connected at the time + // this component is constructed. + @BindsInstance + Builder expandableNotificationRow(ExpandableNotificationRow view); + @BindsInstance + Builder notificationEntry(NotificationEntry entry); + @BindsInstance + Builder onDismissRunnable(@DismissRunnable Runnable runnable); + @BindsInstance + Builder rowContentBindStage(RowContentBindStage rowContentBindStage); + @BindsInstance + Builder inflationCallback(NotificationRowContentBinder.InflationCallback inflationCallback); + @BindsInstance + Builder onExpandClickListener(ExpandableNotificationRow.OnExpandClickListener presenter); + ExpandableNotificationRowComponent build(); + } + + /** + * Creates a ExpandableNotificationRowController. + */ + @NotificationRowScope + ExpandableNotificationRowController getExpandableNotificationRowController(); + + /** + * Dagger Module that extracts interesting properties from an ExpandableNotificationRow. + */ + @Module + abstract class ExpandableNotificationRowModule { + + /** ExpandableNotificationRow is provided as an instance of ActivatableNotificationView. */ + @Binds + abstract ActivatableNotificationView bindExpandableView(ExpandableNotificationRow view); + + @Provides + static StatusBarNotification provideStatusBarNotification( + NotificationEntry notificationEntry) { + return notificationEntry.getSbn(); + } + + @Provides + @NotificationKey + static String provideNotificationKey(StatusBarNotification statusBarNotification) { + return statusBarNotification.getKey(); + } + + @Provides + @AppName + static String provideAppName(Context context, StatusBarNotification statusBarNotification) { + // Get the app name. + // Note that Notification.Builder#bindHeaderAppName has similar logic + // but since this field is used in the guts, it must be accurate. + // Therefore we will only show the application label, or, failing that, the + // package name. No substitutions. + PackageManager pmUser = StatusBar.getPackageManagerForUser( + context, statusBarNotification.getUser().getIdentifier()); + final String pkg = statusBarNotification.getPackageName(); + try { + final ApplicationInfo info = pmUser.getApplicationInfo(pkg, + PackageManager.MATCH_UNINSTALLED_PACKAGES + | PackageManager.MATCH_DISABLED_COMPONENTS); + if (info != null) { + return String.valueOf(pmUser.getApplicationLabel(info)); + } + } catch (PackageManager.NameNotFoundException e) { + // Do nothing + } + + return pkg; + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationKey.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationKey.java new file mode 100644 index 0000000000000..b1fff383cd5d3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationKey.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row.dagger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Qualifier; + +@Qualifier +@Documented +@Retention(RUNTIME) +public @interface NotificationKey { +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowComponent.java index f16ea7ae23e97..1f535c5e3f56d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowComponent.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowComponent.java @@ -16,24 +16,17 @@ package com.android.systemui.statusbar.notification.row.dagger; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - import com.android.systemui.statusbar.notification.row.ActivatableNotificationView; import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController; -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; - -import javax.inject.Scope; - import dagger.BindsInstance; import dagger.Subcomponent; /** * Dagger subcomponent for Notification related views. */ -@Subcomponent(modules = {}) -@NotificationRowComponent.NotificationRowScope +@Subcomponent(modules = {ActivatableNotificationViewModule.class}) +@NotificationRowScope public interface NotificationRowComponent { /** * Builder for {@link NotificationRowComponent}. @@ -45,14 +38,6 @@ public interface NotificationRowComponent { NotificationRowComponent build(); } - /** - * Scope annotation for singleton items within the StatusBarComponent. - */ - @Documented - @Retention(RUNTIME) - @Scope - @interface NotificationRowScope {} - /** * Creates a ActivatableNotificationViewController. */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java new file mode 100644 index 0000000000000..4555b839a3f21 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/NotificationRowScope.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.notification.row.dagger; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; + +import javax.inject.Scope; + +/** + * Scope annotation for singleton items within the StatusBarComponent. + */ +@Documented +@Retention(RUNTIME) +@Scope +public @interface NotificationRowScope {} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java index 07f6936ece070..5a0a495e1f851 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java @@ -58,10 +58,13 @@ import androidx.annotation.NonNull; import androidx.test.filters.SmallTest; import com.android.internal.statusbar.NotificationVisibility; +import com.android.internal.util.NotificationMessagingUtil; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationLifetimeExtender; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -83,12 +86,13 @@ import com.android.systemui.statusbar.notification.logging.NotificationLogger; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; +import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController; import com.android.systemui.statusbar.notification.row.NotifBindPipeline; import com.android.systemui.statusbar.notification.row.NotificationGutsManager; import com.android.systemui.statusbar.notification.row.RowContentBindParams; import com.android.systemui.statusbar.notification.row.RowContentBindStage; import com.android.systemui.statusbar.notification.row.RowInflaterTask; -import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent; +import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent; import com.android.systemui.statusbar.notification.stack.NotificationListContainer; import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.statusbar.phone.NotificationGroupManager; @@ -96,6 +100,7 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.util.Assert; import com.android.systemui.util.leak.LeakDetector; +import com.android.systemui.util.time.FakeSystemClock; import org.junit.After; import org.junit.Before; @@ -106,6 +111,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.Arrays; @@ -141,8 +147,13 @@ public class NotificationEntryManagerTest extends SysuiTestCase { @Mock private NotificationEntryManagerLogger mLogger; @Mock private FeatureFlags mFeatureFlags; @Mock private LeakDetector mLeakDetector; - @Mock private ActivatableNotificationViewController mActivatableNotificationViewController; - @Mock private NotificationRowComponent.Builder mNotificationRowComponentBuilder; + @Mock private NotificationMediaManager mNotificationMediaManager; + @Mock private ExpandableNotificationRowComponent.Builder + mExpandableNotificationRowComponentBuilder; + @Mock private ExpandableNotificationRowComponent mExpandableNotificationRowComponent; + @Mock private FalsingManager mFalsingManager; + @Mock private KeyguardBypassController mKeyguardBypassController; + @Mock private StatusBarStateController mStatusBarStateController; private int mId; private NotificationEntry mEntry; @@ -191,7 +202,6 @@ public class NotificationEntryManagerTest extends SysuiTestCase { public void setUp() { MockitoAnnotations.initMocks(this); mDependency.injectMockDependency(SmartReplyController.class); - mDependency.injectMockDependency(NotificationMediaManager.class); mCountDownLatch = new CountDownLatch(1); @@ -207,28 +217,23 @@ public class NotificationEntryManagerTest extends SysuiTestCase { mEntry.expandedIcon = mock(StatusBarIconView.class); - when(mNotificationRowComponentBuilder.activatableNotificationView(any())) - .thenReturn(mNotificationRowComponentBuilder); - when(mNotificationRowComponentBuilder.build()).thenReturn( - () -> mActivatableNotificationViewController); - RowContentBindStage bindStage = mock(RowContentBindStage.class); when(bindStage.getStageParams(any())).thenReturn(new RowContentBindParams()); - NotificationRowBinderImpl notificationRowBinder = new NotificationRowBinderImpl(mContext, + new NotificationMessagingUtil(mContext), mRemoteInputManager, mLockscreenUserManager, mock(NotifBindPipeline.class), bindStage, true, /* allowLongPress */ - mock(KeyguardBypassController.class), - mock(StatusBarStateController.class), + mKeyguardBypassController, + mStatusBarStateController, mGroupManager, mGutsManager, mNotificationInterruptionStateProvider, - () -> new RowInflaterTask(mNotificationRowComponentBuilder), - mock(NotificationLogger.class)); + RowInflaterTask::new, + mExpandableNotificationRowComponentBuilder); when(mFeatureFlags.isNewNotifPipelineEnabled()).thenReturn(false); when(mFeatureFlags.isNewNotifPipelineRenderingEnabled()).thenReturn(false); @@ -236,7 +241,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase { mLogger, mGroupManager, new NotificationRankingManager( - () -> mock(NotificationMediaManager.class), + () -> mNotificationMediaManager, mGroupManager, mHeadsUpManager, mock(NotificationFilter.class), @@ -255,13 +260,55 @@ public class NotificationEntryManagerTest extends SysuiTestCase { mEntryManager.addNotificationEntryListener(mEntryListener); mEntryManager.addNotificationRemoveInterceptor(mRemoveInterceptor); - notificationRowBinder.setUpWithPresenter( - mPresenter, mListContainer, mHeadsUpManager, mBindCallback); + notificationRowBinder.setUpWithPresenter(mPresenter, mListContainer, mBindCallback); notificationRowBinder.setInflationCallback(mEntryManager); notificationRowBinder.setNotificationClicker(mock(NotificationClicker.class)); setUserSentiment( mEntry.getKey(), Ranking.USER_SENTIMENT_NEUTRAL); + + ArgumentCaptor viewCaptor = + ArgumentCaptor.forClass(ExpandableNotificationRow.class); + when(mExpandableNotificationRowComponentBuilder + .expandableNotificationRow(viewCaptor.capture())) + .thenReturn(mExpandableNotificationRowComponentBuilder); + when(mExpandableNotificationRowComponentBuilder + .notificationEntry(any())) + .thenReturn(mExpandableNotificationRowComponentBuilder); + when(mExpandableNotificationRowComponentBuilder + .onDismissRunnable(any())) + .thenReturn(mExpandableNotificationRowComponentBuilder); + when(mExpandableNotificationRowComponentBuilder + .inflationCallback(any())) + .thenReturn(mExpandableNotificationRowComponentBuilder); + when(mExpandableNotificationRowComponentBuilder + .onExpandClickListener(any())) + .thenReturn(mExpandableNotificationRowComponentBuilder); + + when(mExpandableNotificationRowComponentBuilder.build()) + .thenReturn(mExpandableNotificationRowComponent); + when(mExpandableNotificationRowComponent.getExpandableNotificationRowController()) + .thenAnswer((Answer) invocation -> + new ExpandableNotificationRowController( + viewCaptor.getValue(), + mock(ActivatableNotificationViewController.class), + mNotificationMediaManager, + mock(PluginManager.class), + new FakeSystemClock(), + "FOOBAR", "FOOBAR", + mKeyguardBypassController, + mGroupManager, + bindStage, + mock(NotificationLogger.class), + mHeadsUpManager, + mPresenter, + mStatusBarStateController, + mEntryManager, + mGutsManager, + true, + null, + mFalsingManager + )); } @After diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java index d8cf6ed9a47b1..a8918103c4a21 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java @@ -194,9 +194,8 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { @Test public void testClickSound() throws Exception { assertTrue("Should play sounds by default.", mGroupRow.isSoundEffectsEnabled()); - StatusBarStateController mock = mock(StatusBarStateController.class); + StatusBarStateController mock = mNotificationTestHelper.getStatusBarStateController(); when(mock.isDozing()).thenReturn(true); - mGroupRow.setStatusBarStateController(mock); mGroupRow.setSecureStateProvider(()-> false); assertFalse("Shouldn't play sounds when dark and trusted.", mGroupRow.isSoundEffectsEnabled()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java index 3d9832de417a4..4283fad83a23c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java @@ -45,6 +45,7 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.systemui.TestableDependency; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.bubbles.BubblesTestActivity; +import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationRemoteInputManager; @@ -91,6 +92,7 @@ public class NotificationTestHelper { private final NotifBindPipeline mBindPipeline; private final NotificationEntryListener mBindPipelineEntryListener; private final RowContentBindStage mBindStage; + private StatusBarStateController mStatusBarStateController; public NotificationTestHelper(Context context, TestableDependency dependency) { mContext = context; @@ -98,9 +100,9 @@ public class NotificationTestHelper { dependency.injectMockDependency(BubbleController.class); dependency.injectMockDependency(NotificationShadeWindowController.class); dependency.injectMockDependency(SmartReplyController.class); - StatusBarStateController stateController = mock(StatusBarStateController.class); - mGroupManager = new NotificationGroupManager(stateController); - mHeadsUpManager = new HeadsUpManagerPhone(mContext, stateController, + mStatusBarStateController = mock(StatusBarStateController.class); + mGroupManager = new NotificationGroupManager(mStatusBarStateController); + mHeadsUpManager = new HeadsUpManagerPhone(mContext, mStatusBarStateController, mock(KeyguardBypassController.class)); mHeadsUpManager.setUp(null, mGroupManager, null, null); mGroupManager.setHeadsUpManager(mHeadsUpManager); @@ -307,6 +309,10 @@ public class NotificationTestHelper { return notificationBuilder.build(); } + public StatusBarStateController getStatusBarStateController() { + return mStatusBarStateController; + } + private ExpandableNotificationRow generateRow( Notification notification, String pkg, @@ -368,7 +374,11 @@ public class NotificationTestHelper { mGroupManager, mHeadsUpManager, mBindStage, - mock(OnExpandClickListener.class)); + mock(OnExpandClickListener.class), + mock(NotificationMediaManager.class), + mock(ExpandableNotificationRow.OnAppOpsClickListener.class), + mock(FalsingManager.class), + mStatusBarStateController); row.setAboveShelfChangedListener(aboveShelf -> { }); mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags); inflateAndWait(entry, mBindStage); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java index e84f14a6a2c10..2d1bc7890aeda 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java @@ -30,7 +30,6 @@ import android.testing.TestableLooper.RunWithLooper; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; -import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow; @@ -59,8 +58,6 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase { private ExpandableNotificationRow mFirst; private ExpandableNotificationRow mSecond; @Mock - private StatusBarStateController mStatusBarStateController; - @Mock private KeyguardBypassController mBypassController; @Before @@ -150,13 +147,12 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase { createSection(mFirst, mSecond), createSection(null, null) }); - ExpandableNotificationRow row = new NotificationTestHelper(getContext(), mDependency) - .createRow(); + NotificationTestHelper testHelper = new NotificationTestHelper(getContext(), mDependency); + ExpandableNotificationRow row = testHelper.createRow(); NotificationEntry entry = mock(NotificationEntry.class); when(entry.getRow()).thenReturn(row); - when(mStatusBarStateController.isDozing()).thenReturn(true); - row.setStatusBarStateController(mStatusBarStateController); + when(testHelper.getStatusBarStateController().isDozing()).thenReturn(true); row.setHeadsUp(true); mRoundnessManager.onHeadsUpStateChanged(entry, true); Assert.assertEquals(1f, row.getCurrentBottomRoundness(), 0.0f);