Merge changes from topic "b147245740-activitable-notif-view-component"
* changes: Add new ExpandableNotificationRowController. Fill in ActivatableNotificationViewController.
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<NotificationEntry> getChildren() {
|
||||
if (row == null) {
|
||||
|
||||
@@ -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<RowInflaterTask> 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<RowInflaterTask> 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 {
|
||||
/**
|
||||
|
||||
@@ -90,7 +90,6 @@ class NotificationsControllerImpl @Inject constructor(
|
||||
notificationRowBinder.setUpWithPresenter(
|
||||
presenter,
|
||||
listContainer,
|
||||
headsUpManager,
|
||||
bindRowCallback)
|
||||
|
||||
if (featureFlags.isNewNotifPipelineEnabled) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 {}
|
||||
@@ -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<ExpandableNotificationRow> 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<ExpandableNotificationRowController>) 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
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user