Merge "Inline controls redesign" into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
eaebc6540c
@@ -121,7 +121,6 @@
|
||||
android:layout_marginEnd="2dp"
|
||||
android:ellipsize="end"
|
||||
android:text="@string/notification_delegate_header"
|
||||
android:layout_toEndOf="@id/pkg_divider"
|
||||
android:maxLines="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -27,51 +27,81 @@
|
||||
android:paddingStart="@*android:dimen/notification_content_margin_start">
|
||||
|
||||
<!-- Package Info -->
|
||||
<RelativeLayout
|
||||
<LinearLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="@dimen/notification_guts_conversation_header_height"
|
||||
android:gravity="center_vertical"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
<ImageView
|
||||
android:id="@+id/pkgicon"
|
||||
android:layout_width="@dimen/notification_guts_header_height"
|
||||
android:layout_height="@dimen/notification_guts_header_height"
|
||||
android:id="@+id/pkg_icon"
|
||||
android:layout_width="@dimen/notification_guts_conversation_icon_size"
|
||||
android:layout_height="@dimen/notification_guts_conversation_icon_size"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginEnd="3dp" />
|
||||
<TextView
|
||||
android:id="@+id/pkgname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_marginEnd="15dp" />
|
||||
<LinearLayout
|
||||
android:id="@+id/names"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:orientation="vertical"
|
||||
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/notification_guts_conversation_icon_size"
|
||||
android:layout_centerVertical="true"
|
||||
style="@style/TextAppearance.NotificationImportanceHeader"
|
||||
android:layout_marginStart="3dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_toEndOf="@id/pkgicon"
|
||||
android:singleLine="true" />
|
||||
<TextView
|
||||
android:id="@+id/pkg_divider"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
style="@style/TextAppearance.NotificationImportanceHeader"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_toEndOf="@id/pkgname"
|
||||
android:text="@*android:string/notification_header_divider_symbol" />
|
||||
<TextView
|
||||
android:id="@+id/delegate_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
style="@style/TextAppearance.NotificationImportanceHeader"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:ellipsize="end"
|
||||
android:text="@string/notification_delegate_header"
|
||||
android:layout_toEndOf="@id/pkg_divider"
|
||||
android:maxLines="1" />
|
||||
android:gravity="center_vertical"
|
||||
android:layout_alignEnd="@id/pkg_icon"
|
||||
android:layout_toEndOf="@id/pkg_icon"
|
||||
android:layout_alignStart="@id/mute">
|
||||
<TextView
|
||||
android:id="@+id/channel_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextAppearance.NotificationImportanceChannel"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:id="@+id/pkg_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextAppearance.NotificationImportanceChannelGroup"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"/>
|
||||
<TextView
|
||||
android:id="@+id/group_divider"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
style="@style/TextAppearance.NotificationImportanceHeader"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:text="@*android:string/notification_header_divider_symbol" />
|
||||
<TextView
|
||||
android:id="@+id/group_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
style="@style/TextAppearance.NotificationImportanceChannel"/>
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/delegate_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
style="@style/TextAppearance.NotificationImportanceHeader"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:ellipsize="end"
|
||||
android:text="@string/notification_delegate_header"
|
||||
android:maxLines="1" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- end aligned fields -->
|
||||
<!-- Optional link to app. Only appears if the channel is not disabled and the app
|
||||
asked for it -->
|
||||
<ImageButton
|
||||
@@ -95,91 +125,6 @@ asked for it -->
|
||||
android:src="@drawable/ic_settings"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:tint="@color/notification_guts_link_icon_tint"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Channel Info Block -->
|
||||
<LinearLayout
|
||||
android:id="@+id/channel_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="@*android:dimen/notification_content_margin_end"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
<!-- Channel Name -->
|
||||
<TextView
|
||||
android:id="@+id/channel_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
style="@style/TextAppearance.NotificationImportanceChannel"/>
|
||||
<TextView
|
||||
android:id="@+id/group_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextAppearance.NotificationImportanceChannelGroup"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/blocking_helper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/notification_guts_button_spacing"
|
||||
android:layout_marginBottom="@dimen/notification_guts_button_spacing"
|
||||
android:paddingEnd="@*android:dimen/notification_content_margin_end"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
<!-- blocking helper text. no need for non-configurable check b/c controls won't be
|
||||
activated in that case -->
|
||||
<TextView
|
||||
android:id="@+id/blocking_helper_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="@string/inline_blocking_helper"
|
||||
style="@*android:style/TextAppearance.DeviceDefault.Notification" />
|
||||
<RelativeLayout
|
||||
android:id="@+id/block_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/notification_guts_button_spacing">
|
||||
<TextView
|
||||
android:id="@+id/blocking_helper_turn_off_notifications"
|
||||
android:text="@string/inline_turn_off_notifications"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:width="110dp"
|
||||
android:paddingEnd="15dp"
|
||||
android:breakStrategy="simple"
|
||||
style="@style/TextAppearance.NotificationInfo.Button"/>
|
||||
<TextView
|
||||
android:id="@+id/deliver_silently"
|
||||
android:text="@string/inline_deliver_silently_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
|
||||
android:paddingEnd="15dp"
|
||||
android:width="110dp"
|
||||
android:breakStrategy="simple"
|
||||
android:layout_toStartOf="@+id/keep_showing"
|
||||
style="@style/TextAppearance.NotificationInfo.Button"/>
|
||||
<TextView
|
||||
android:id="@+id/keep_showing"
|
||||
android:text="@string/inline_keep_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
|
||||
android:width="110dp"
|
||||
android:breakStrategy="simple"
|
||||
android:layout_alignParentEnd="true"
|
||||
style="@style/TextAppearance.NotificationInfo.Button"/>
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@@ -357,34 +302,4 @@ asked for it -->
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.android.systemui.statusbar.notification.row.NotificationUndoLayout
|
||||
android:id="@+id/confirmation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:orientation="horizontal" >
|
||||
<TextView
|
||||
android:id="@+id/confirmation_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_marginStart="@*android:dimen/notification_content_margin_start"
|
||||
android:layout_marginEnd="@*android:dimen/notification_content_margin_start"
|
||||
android:text="@string/notification_channel_disabled"
|
||||
style="@style/TextAppearance.NotificationInfo.Confirmation"/>
|
||||
<TextView
|
||||
android:id="@+id/undo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="@dimen/notification_importance_toggle_size"
|
||||
android:minHeight="@dimen/notification_importance_toggle_size"
|
||||
android:layout_marginTop="@dimen/notification_guts_button_spacing"
|
||||
android:layout_marginBottom="@dimen/notification_guts_button_spacing"
|
||||
android:layout_marginStart="@dimen/notification_guts_button_side_margin"
|
||||
android:layout_marginEnd="@dimen/notification_guts_button_side_margin"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:text="@string/inline_undo"
|
||||
style="@style/TextAppearance.NotificationInfo.Button"/>
|
||||
</com.android.systemui.statusbar.notification.row.NotificationUndoLayout>
|
||||
</com.android.systemui.statusbar.notification.row.NotificationInfo>
|
||||
|
||||
@@ -315,7 +315,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
||||
mNotificationActivityStarter.startNotificationGutsIntent(intent, sbn.getUid(),
|
||||
row);
|
||||
};
|
||||
boolean isForBlockingHelper = row.isBlockingHelperShowing();
|
||||
|
||||
if (!userHandle.equals(UserHandle.ALL)
|
||||
|| mLockscreenUserManager.getCurrentUserId() == UserHandle.USER_SYSTEM) {
|
||||
@@ -335,13 +334,10 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
||||
row.getEntry().getChannel(),
|
||||
row.getUniqueChannels(),
|
||||
row.getEntry(),
|
||||
mCheckSaveListener,
|
||||
onSettingsClick,
|
||||
onAppSettingsClick,
|
||||
mDeviceProvisionedController.isDeviceProvisioned(),
|
||||
row.getIsNonblockable(),
|
||||
isForBlockingHelper,
|
||||
row.getEntry().getImportance(),
|
||||
mHighPriorityProvider.isHighPriority(row.getEntry()));
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,6 @@ import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.INotificationManager;
|
||||
@@ -53,7 +49,6 @@ import android.transition.TransitionSet;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
@@ -63,42 +58,33 @@ import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.notification.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||
import com.android.systemui.statusbar.notification.logging.NotificationCounters;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The guts of a notification revealed when performing a long press. This also houses the blocking
|
||||
* helper affordance that allows a user to keep/stop notifications after swiping one away.
|
||||
* The guts of a notification revealed when performing a long press.
|
||||
*/
|
||||
public class NotificationInfo extends LinearLayout implements NotificationGuts.GutsContent {
|
||||
private static final String TAG = "InfoGuts";
|
||||
|
||||
@IntDef(prefix = { "ACTION_" }, value = {
|
||||
ACTION_NONE,
|
||||
ACTION_UNDO,
|
||||
ACTION_TOGGLE_ALERT,
|
||||
ACTION_TOGGLE_SILENT,
|
||||
ACTION_BLOCK,
|
||||
})
|
||||
public @interface NotificationInfoAction {
|
||||
}
|
||||
|
||||
public static final int ACTION_NONE = 0;
|
||||
static final int ACTION_UNDO = 1;
|
||||
// standard controls
|
||||
static final int ACTION_TOGGLE_SILENT = 2;
|
||||
// unused
|
||||
static final int ACTION_BLOCK = 3;
|
||||
// blocking helper
|
||||
static final int ACTION_DELIVER_SILENTLY = 4;
|
||||
// standard controls
|
||||
private static final int ACTION_ALERT = 5;
|
||||
private static final int ACTION_TOGGLE_ALERT = 5;
|
||||
|
||||
private TextView mPriorityDescriptionView;
|
||||
private TextView mSilentDescriptionView;
|
||||
@@ -128,101 +114,35 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
@Nullable private Integer mChosenImportance;
|
||||
private boolean mIsSingleDefaultChannel;
|
||||
private boolean mIsNonblockable;
|
||||
private NotificationEntry mEntry;
|
||||
private StatusBarNotification mSbn;
|
||||
private AnimatorSet mExpandAnimation;
|
||||
private boolean mIsDeviceProvisioned;
|
||||
|
||||
private CheckSaveListener mCheckSaveListener;
|
||||
private OnSettingsClickListener mOnSettingsClickListener;
|
||||
private OnAppSettingsClickListener mAppSettingsClickListener;
|
||||
private NotificationGuts mGutsContainer;
|
||||
private Drawable mPkgIcon;
|
||||
|
||||
/** Whether this view is being shown as part of the blocking helper. */
|
||||
private boolean mIsForBlockingHelper;
|
||||
|
||||
@VisibleForTesting
|
||||
boolean mSkipPost = false;
|
||||
|
||||
/**
|
||||
* String that describes how the user exit or quit out of this view, also used as a counter tag.
|
||||
*/
|
||||
private String mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
|
||||
|
||||
|
||||
// used by standard ui
|
||||
private OnClickListener mOnAlert = v -> {
|
||||
mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
|
||||
mChosenImportance = IMPORTANCE_DEFAULT;
|
||||
applyAlertingBehavior(BEHAVIOR_ALERTING, true /* userTriggered */);
|
||||
};
|
||||
|
||||
// used by standard ui
|
||||
private OnClickListener mOnSilent = v -> {
|
||||
mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
|
||||
mChosenImportance = IMPORTANCE_LOW;
|
||||
applyAlertingBehavior(BEHAVIOR_SILENT, true /* userTriggered */);
|
||||
};
|
||||
|
||||
|
||||
// used by standard ui
|
||||
private OnClickListener mOnDismissSettings = v -> {
|
||||
mPressedApply = true;
|
||||
closeControls(v, true);
|
||||
};
|
||||
|
||||
// used by blocking helper
|
||||
private OnClickListener mOnKeepShowing = v -> {
|
||||
mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
|
||||
closeControls(v, true);
|
||||
mMetricsLogger.write(getLogMaker().setCategory(
|
||||
MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
|
||||
.setType(MetricsEvent.TYPE_ACTION)
|
||||
.setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT));
|
||||
};
|
||||
|
||||
// used by blocking helper
|
||||
private OnClickListener mOnDeliverSilently = v -> {
|
||||
handleSaveImportance(
|
||||
ACTION_DELIVER_SILENTLY, MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT);
|
||||
};
|
||||
|
||||
private void handleSaveImportance(int action, int metricsSubtype) {
|
||||
Runnable saveImportance = () -> {
|
||||
saveImportanceAndExitReason(action);
|
||||
if (mIsForBlockingHelper) {
|
||||
swapContent(action, true /* animate */);
|
||||
mMetricsLogger.write(getLogMaker()
|
||||
.setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
|
||||
.setType(MetricsEvent.TYPE_ACTION)
|
||||
.setSubtype(metricsSubtype));
|
||||
}
|
||||
};
|
||||
if (mCheckSaveListener != null) {
|
||||
mCheckSaveListener.checkSave(saveImportance, mSbn);
|
||||
} else {
|
||||
saveImportance.run();
|
||||
}
|
||||
}
|
||||
|
||||
private OnClickListener mOnUndo = v -> {
|
||||
// Reset exit counter that we'll log and record an undo event separately (not an exit event)
|
||||
mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
|
||||
if (mIsForBlockingHelper) {
|
||||
logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_UNDO);
|
||||
mMetricsLogger.write(getLogMaker().setCategory(
|
||||
MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
|
||||
.setType(MetricsEvent.TYPE_DISMISS)
|
||||
.setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_UNDO));
|
||||
} else {
|
||||
// TODO: this can't happen?
|
||||
mMetricsLogger.write(importanceChangeLogMaker().setType(MetricsEvent.TYPE_DISMISS));
|
||||
}
|
||||
saveImportanceAndExitReason(ACTION_UNDO);
|
||||
swapContent(ACTION_UNDO, true /* animate */);
|
||||
};
|
||||
|
||||
public NotificationInfo(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
@@ -250,30 +170,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
void onClick(View v, Intent intent);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void bindNotification(
|
||||
final PackageManager pm,
|
||||
final INotificationManager iNotificationManager,
|
||||
final VisualStabilityManager visualStabilityManager,
|
||||
final String pkg,
|
||||
final NotificationChannel notificationChannel,
|
||||
final Set<NotificationChannel> uniqueChannelsInRow,
|
||||
final NotificationEntry entry,
|
||||
final CheckSaveListener checkSaveListener,
|
||||
final OnSettingsClickListener onSettingsClick,
|
||||
final OnAppSettingsClickListener onAppSettingsClick,
|
||||
boolean isDeviceProvisioned,
|
||||
boolean isNonblockable,
|
||||
int importance,
|
||||
boolean wasShownHighPriority)
|
||||
throws RemoteException {
|
||||
bindNotification(pm, iNotificationManager, visualStabilityManager, pkg, notificationChannel,
|
||||
uniqueChannelsInRow, entry, checkSaveListener, onSettingsClick,
|
||||
onAppSettingsClick, isDeviceProvisioned, isNonblockable,
|
||||
false /* isBlockingHelper */,
|
||||
importance, wasShownHighPriority);
|
||||
}
|
||||
|
||||
public void bindNotification(
|
||||
PackageManager pm,
|
||||
INotificationManager iNotificationManager,
|
||||
@@ -282,13 +178,10 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
NotificationChannel notificationChannel,
|
||||
Set<NotificationChannel> uniqueChannelsInRow,
|
||||
NotificationEntry entry,
|
||||
CheckSaveListener checkSaveListener,
|
||||
OnSettingsClickListener onSettingsClick,
|
||||
OnAppSettingsClickListener onAppSettingsClick,
|
||||
boolean isDeviceProvisioned,
|
||||
boolean isNonblockable,
|
||||
boolean isForBlockingHelper,
|
||||
int importance,
|
||||
boolean wasShownHighPriority)
|
||||
throws RemoteException {
|
||||
mINotificationManager = iNotificationManager;
|
||||
@@ -298,18 +191,15 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
mPackageName = pkg;
|
||||
mUniqueChannelsInRow = uniqueChannelsInRow;
|
||||
mNumUniqueChannelsInRow = uniqueChannelsInRow.size();
|
||||
mEntry = entry;
|
||||
mSbn = entry.getSbn();
|
||||
mPm = pm;
|
||||
mAppSettingsClickListener = onAppSettingsClick;
|
||||
mAppName = mPackageName;
|
||||
mCheckSaveListener = checkSaveListener;
|
||||
mOnSettingsClickListener = onSettingsClick;
|
||||
mSingleNotificationChannel = notificationChannel;
|
||||
mStartingChannelImportance = mSingleNotificationChannel.getImportance();
|
||||
mWasShownHighPriority = wasShownHighPriority;
|
||||
mIsNonblockable = isNonblockable;
|
||||
mIsForBlockingHelper = isForBlockingHelper;
|
||||
mAppUid = mSbn.getUid();
|
||||
mDelegatePkg = mSbn.getOpPkg();
|
||||
mIsDeviceProvisioned = isDeviceProvisioned;
|
||||
@@ -329,36 +219,12 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
bindHeader();
|
||||
bindChannelDetails();
|
||||
|
||||
if (mIsForBlockingHelper) {
|
||||
bindBlockingHelper();
|
||||
} else {
|
||||
bindInlineControls();
|
||||
}
|
||||
bindInlineControls();
|
||||
|
||||
mMetricsLogger.write(notificationControlsLogMaker());
|
||||
}
|
||||
|
||||
private void bindBlockingHelper() {
|
||||
findViewById(R.id.inline_controls).setVisibility(GONE);
|
||||
findViewById(R.id.blocking_helper).setVisibility(VISIBLE);
|
||||
|
||||
findViewById(R.id.undo).setOnClickListener(mOnUndo);
|
||||
|
||||
View turnOffButton = findViewById(R.id.blocking_helper_turn_off_notifications);
|
||||
turnOffButton.setOnClickListener(getSettingsOnClickListener());
|
||||
turnOffButton.setVisibility(turnOffButton.hasOnClickListeners() ? VISIBLE : GONE);
|
||||
|
||||
TextView keepShowing = findViewById(R.id.keep_showing);
|
||||
keepShowing.setOnClickListener(mOnKeepShowing);
|
||||
|
||||
View deliverSilently = findViewById(R.id.deliver_silently);
|
||||
deliverSilently.setOnClickListener(mOnDeliverSilently);
|
||||
}
|
||||
|
||||
private void bindInlineControls() {
|
||||
findViewById(R.id.inline_controls).setVisibility(VISIBLE);
|
||||
findViewById(R.id.blocking_helper).setVisibility(GONE);
|
||||
|
||||
if (mIsNonblockable) {
|
||||
findViewById(R.id.non_configurable_text).setVisibility(VISIBLE);
|
||||
findViewById(R.id.non_configurable_multichannel_text).setVisibility(GONE);
|
||||
@@ -414,8 +280,8 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
// app is gone, just show package name and generic icon
|
||||
mPkgIcon = mPm.getDefaultActivityIcon();
|
||||
}
|
||||
((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(mPkgIcon);
|
||||
((TextView) findViewById(R.id.pkgname)).setText(mAppName);
|
||||
((ImageView) findViewById(R.id.pkg_icon)).setImageDrawable(mPkgIcon);
|
||||
((TextView) findViewById(R.id.pkg_name)).setText(mAppName);
|
||||
|
||||
// Delegate
|
||||
bindDelegate();
|
||||
@@ -445,8 +311,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
if (mAppUid >= 0 && mOnSettingsClickListener != null && mIsDeviceProvisioned) {
|
||||
final int appUidF = mAppUid;
|
||||
return ((View view) -> {
|
||||
logBlockingHelperCounter(
|
||||
NotificationCounters.BLOCKING_HELPER_NOTIF_SETTINGS);
|
||||
mOnSettingsClickListener.onClick(view,
|
||||
mNumUniqueChannelsInRow > 1 ? null : mSingleNotificationChannel,
|
||||
appUidF);
|
||||
@@ -487,16 +351,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
|
||||
private void bindDelegate() {
|
||||
TextView delegateView = findViewById(R.id.delegate_name);
|
||||
TextView dividerView = findViewById(R.id.pkg_divider);
|
||||
|
||||
CharSequence delegatePkg = null;
|
||||
if (!TextUtils.equals(mPackageName, mDelegatePkg)) {
|
||||
// this notification was posted by a delegate!
|
||||
delegateView.setVisibility(View.VISIBLE);
|
||||
dividerView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
delegateView.setVisibility(View.GONE);
|
||||
dividerView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,25 +373,19 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
}
|
||||
}
|
||||
TextView groupNameView = findViewById(R.id.group_name);
|
||||
View divider = findViewById(R.id.group_divider);
|
||||
if (groupName != null) {
|
||||
groupNameView.setText(groupName);
|
||||
groupNameView.setVisibility(View.VISIBLE);
|
||||
groupNameView.setVisibility(VISIBLE);
|
||||
divider.setVisibility(VISIBLE);
|
||||
} else {
|
||||
groupNameView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
void logBlockingHelperCounter(String counterTag) {
|
||||
if (mIsForBlockingHelper) {
|
||||
mMetricsLogger.count(counterTag, 1);
|
||||
groupNameView.setVisibility(GONE);
|
||||
divider.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveImportance() {
|
||||
if (!mIsNonblockable
|
||||
|| mExitReason != NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS) {
|
||||
if (!mIsNonblockable) {
|
||||
if (mChosenImportance == null) {
|
||||
mChosenImportance = mStartingChannelImportance;
|
||||
}
|
||||
@@ -621,99 +476,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
: R.string.inline_done_button);
|
||||
}
|
||||
|
||||
private void saveImportanceAndExitReason(@NotificationInfoAction int action) {
|
||||
switch (action) {
|
||||
case ACTION_UNDO:
|
||||
mChosenImportance = mStartingChannelImportance;
|
||||
break;
|
||||
case ACTION_DELIVER_SILENTLY:
|
||||
mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
|
||||
mChosenImportance = mWasShownHighPriority
|
||||
? IMPORTANCE_LOW : mStartingChannelImportance;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
// only used for blocking helper
|
||||
private void swapContent(@NotificationInfoAction int action, boolean animate) {
|
||||
if (mExpandAnimation != null) {
|
||||
mExpandAnimation.cancel();
|
||||
}
|
||||
|
||||
View blockingHelper = findViewById(R.id.blocking_helper);
|
||||
ViewGroup confirmation = findViewById(R.id.confirmation);
|
||||
TextView confirmationText = findViewById(R.id.confirmation_text);
|
||||
|
||||
saveImportanceAndExitReason(action);
|
||||
|
||||
switch (action) {
|
||||
case ACTION_UNDO:
|
||||
break;
|
||||
case ACTION_DELIVER_SILENTLY:
|
||||
confirmationText.setText(R.string.notification_channel_silenced);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
boolean isUndo = action == ACTION_UNDO;
|
||||
|
||||
blockingHelper.setVisibility(isUndo ? VISIBLE : GONE);
|
||||
findViewById(R.id.channel_info).setVisibility(isUndo ? VISIBLE : GONE);
|
||||
findViewById(R.id.header).setVisibility(isUndo ? VISIBLE : GONE);
|
||||
confirmation.setVisibility(isUndo ? GONE : VISIBLE);
|
||||
|
||||
if (animate) {
|
||||
ObjectAnimator promptAnim = ObjectAnimator.ofFloat(blockingHelper, View.ALPHA,
|
||||
blockingHelper.getAlpha(), isUndo ? 1f : 0f);
|
||||
promptAnim.setInterpolator(isUndo ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
|
||||
ObjectAnimator confirmAnim = ObjectAnimator.ofFloat(confirmation, View.ALPHA,
|
||||
confirmation.getAlpha(), isUndo ? 0f : 1f);
|
||||
confirmAnim.setInterpolator(isUndo ? Interpolators.ALPHA_OUT : Interpolators.ALPHA_IN);
|
||||
|
||||
mExpandAnimation = new AnimatorSet();
|
||||
mExpandAnimation.playTogether(promptAnim, confirmAnim);
|
||||
mExpandAnimation.setDuration(150);
|
||||
mExpandAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
boolean mCancelled = false;
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
mCancelled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (!mCancelled) {
|
||||
blockingHelper.setVisibility(isUndo ? VISIBLE : GONE);
|
||||
confirmation.setVisibility(isUndo ? GONE : VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
mExpandAnimation.start();
|
||||
}
|
||||
|
||||
// Since we're swapping/update the content, reset the timeout so the UI can't close
|
||||
// immediately after the update.
|
||||
if (mGutsContainer != null) {
|
||||
mGutsContainer.resetFalsingCheck();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishedClosing() {
|
||||
if (mChosenImportance != null) {
|
||||
mStartingChannelImportance = mChosenImportance;
|
||||
}
|
||||
mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
|
||||
|
||||
if (mIsForBlockingHelper) {
|
||||
bindBlockingHelper();
|
||||
} else {
|
||||
bindInlineControls();
|
||||
}
|
||||
bindInlineControls();
|
||||
|
||||
mMetricsLogger.write(notificationControlsLogMaker().setType(MetricsEvent.TYPE_CLOSE));
|
||||
}
|
||||
@@ -756,13 +525,10 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the controls and commits the updated importance values (indirectly). If this view is
|
||||
* being used to show the blocking helper, this will immediately dismiss the blocking helper and
|
||||
* commit the updated importance.
|
||||
* Closes the controls and commits the updated importance values (indirectly).
|
||||
*
|
||||
* <p><b>Note,</b> this will only get called once the view is dismissing. This means that the
|
||||
* user does not have the ability to undo the action anymore. See
|
||||
* {@link #swapContent(boolean, boolean)} for where undo is handled.
|
||||
* user does not have the ability to undo the action anymore.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
void closeControls(View v, boolean save) {
|
||||
@@ -811,7 +577,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
if (save) {
|
||||
saveImportance();
|
||||
}
|
||||
logBlockingHelperCounter(mExitReason);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -822,7 +587,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
|
||||
@VisibleForTesting
|
||||
public boolean isAnimating() {
|
||||
return mExpandAnimation != null && mExpandAnimation.isRunning();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -901,8 +666,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
||||
private LogMaker notificationControlsLogMaker() {
|
||||
return getLogMaker().setCategory(MetricsEvent.ACTION_NOTE_CONTROLS)
|
||||
.setType(MetricsEvent.TYPE_OPEN)
|
||||
.setSubtype(mIsForBlockingHelper ? MetricsEvent.BLOCKING_HELPER_DISPLAY
|
||||
: MetricsEvent.BLOCKING_HELPER_UNKNOWN);
|
||||
.setSubtype(MetricsEvent.BLOCKING_HELPER_UNKNOWN);
|
||||
}
|
||||
|
||||
@Retention(SOURCE)
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
/**
|
||||
* Custom view for the NotificationInfo confirmation views so that the confirmation text can
|
||||
* occupy the full width of the notification and push the undo button down to the next line if
|
||||
* necessary.
|
||||
*
|
||||
* @see NotificationInfo
|
||||
*/
|
||||
public class NotificationUndoLayout extends FrameLayout {
|
||||
/**
|
||||
* View for the prompt/confirmation text to tell the user the previous action was successful.
|
||||
*/
|
||||
private View mConfirmationTextView;
|
||||
/** Undo button (actionable text) view. */
|
||||
private View mUndoView;
|
||||
|
||||
/**
|
||||
* Whether {@link #mConfirmationTextView} is multiline and will require the full width of the
|
||||
* parent (which causes the {@link #mUndoView} to push down).
|
||||
*/
|
||||
private boolean mIsMultiline = false;
|
||||
private int mMultilineTopMargin;
|
||||
|
||||
public NotificationUndoLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public NotificationUndoLayout(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public NotificationUndoLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
mConfirmationTextView = findViewById(R.id.confirmation_text);
|
||||
mUndoView = findViewById(R.id.undo);
|
||||
|
||||
mMultilineTopMargin = getResources().getDimensionPixelOffset(
|
||||
com.android.internal.R.dimen.notification_content_margin_start);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
LayoutParams confirmationLayoutParams =
|
||||
(LayoutParams) mConfirmationTextView.getLayoutParams();
|
||||
LayoutParams undoLayoutParams =(LayoutParams) mUndoView.getLayoutParams();
|
||||
|
||||
int measuredWidth = getMeasuredWidth();
|
||||
// Ignore the left margin on the undo button - no need for additional extra space between
|
||||
// the text and the button.
|
||||
int requiredWidth = mConfirmationTextView.getMeasuredWidth()
|
||||
+ confirmationLayoutParams.rightMargin
|
||||
+ confirmationLayoutParams.leftMargin
|
||||
+ mUndoView.getMeasuredWidth()
|
||||
+ undoLayoutParams.rightMargin;
|
||||
// If the measured width isn't enough to accommodate both the undo button and the text in
|
||||
// the same line, we'll need to adjust the view to be multi-line. Otherwise, we're done.
|
||||
if (requiredWidth > measuredWidth) {
|
||||
mIsMultiline = true;
|
||||
|
||||
// Update height requirement to the text height and the button's height (along with
|
||||
// additional spacing for the top of the text).
|
||||
int updatedHeight = mMultilineTopMargin
|
||||
+ mConfirmationTextView.getMeasuredHeight()
|
||||
+ mUndoView.getMeasuredHeight()
|
||||
+ undoLayoutParams.topMargin
|
||||
+ undoLayoutParams.bottomMargin;
|
||||
|
||||
setMeasuredDimension(measuredWidth, updatedHeight);
|
||||
} else {
|
||||
mIsMultiline = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
// If the text view and undo view don't fit on the same line, we'll need to manually lay
|
||||
// out the content.
|
||||
if (mIsMultiline) {
|
||||
// Re-align parent right/bottom values. Left and top are considered to be 0.
|
||||
int parentBottom = getMeasuredHeight();
|
||||
int parentRight = getMeasuredWidth();
|
||||
|
||||
LayoutParams confirmationLayoutParams =
|
||||
(LayoutParams) mConfirmationTextView.getLayoutParams();
|
||||
LayoutParams undoLayoutParams = (LayoutParams) mUndoView.getLayoutParams();
|
||||
|
||||
// The confirmation text occupies the full width as computed earlier. Both side margins
|
||||
// are equivalent, so we only need to grab the left one here.
|
||||
mConfirmationTextView.layout(
|
||||
confirmationLayoutParams.leftMargin,
|
||||
mMultilineTopMargin,
|
||||
confirmationLayoutParams.leftMargin + mConfirmationTextView.getMeasuredWidth(),
|
||||
mMultilineTopMargin + mConfirmationTextView.getMeasuredHeight());
|
||||
|
||||
// The undo button is aligned bottom|end with the parent in the case of multiline text.
|
||||
int undoViewLeft = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL
|
||||
? undoLayoutParams.rightMargin
|
||||
: parentRight - mUndoView.getMeasuredWidth() - undoLayoutParams.rightMargin;
|
||||
mUndoView.layout(
|
||||
undoViewLeft,
|
||||
parentBottom - mUndoView.getMeasuredHeight() - undoLayoutParams.bottomMargin,
|
||||
undoViewLeft + mUndoView.getMeasuredWidth(),
|
||||
parentBottom - undoLayoutParams.bottomMargin);
|
||||
} else {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,75 +315,10 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
||||
assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.getValue().getAction());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializeNotificationInfoView_showBlockingHelper() throws Exception {
|
||||
NotificationInfo notificationInfoView = mock(NotificationInfo.class);
|
||||
ExpandableNotificationRow row = spy(mHelper.createRow());
|
||||
row.setBlockingHelperShowing(true);
|
||||
modifyRanking(row.getEntry())
|
||||
.setUserSentiment(USER_SENTIMENT_NEGATIVE)
|
||||
.build();
|
||||
when(row.getIsNonblockable()).thenReturn(false);
|
||||
StatusBarNotification statusBarNotification = row.getEntry().getSbn();
|
||||
NotificationEntry entry = row.getEntry();
|
||||
|
||||
mGutsManager.initializeNotificationInfo(row, notificationInfoView);
|
||||
|
||||
verify(notificationInfoView).bindNotification(
|
||||
any(PackageManager.class),
|
||||
any(INotificationManager.class),
|
||||
eq(mVisualStabilityManager),
|
||||
eq(statusBarNotification.getPackageName()),
|
||||
any(NotificationChannel.class),
|
||||
anySet(),
|
||||
eq(entry),
|
||||
any(NotificationInfo.CheckSaveListener.class),
|
||||
any(NotificationInfo.OnSettingsClickListener.class),
|
||||
any(NotificationInfo.OnAppSettingsClickListener.class),
|
||||
eq(false),
|
||||
eq(false),
|
||||
eq(true) /* isForBlockingHelper */,
|
||||
eq(0),
|
||||
eq(false) /* wasShownHighPriority */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializeNotificationInfoView_dontShowBlockingHelper() throws Exception {
|
||||
NotificationInfo notificationInfoView = mock(NotificationInfo.class);
|
||||
ExpandableNotificationRow row = spy(mHelper.createRow());
|
||||
row.setBlockingHelperShowing(false);
|
||||
modifyRanking(row.getEntry())
|
||||
.setUserSentiment(USER_SENTIMENT_NEGATIVE)
|
||||
.build();
|
||||
when(row.getIsNonblockable()).thenReturn(false);
|
||||
StatusBarNotification statusBarNotification = row.getEntry().getSbn();
|
||||
NotificationEntry entry = row.getEntry();
|
||||
|
||||
mGutsManager.initializeNotificationInfo(row, notificationInfoView);
|
||||
|
||||
verify(notificationInfoView).bindNotification(
|
||||
any(PackageManager.class),
|
||||
any(INotificationManager.class),
|
||||
eq(mVisualStabilityManager),
|
||||
eq(statusBarNotification.getPackageName()),
|
||||
any(NotificationChannel.class),
|
||||
anySet(),
|
||||
eq(entry),
|
||||
any(NotificationInfo.CheckSaveListener.class),
|
||||
any(NotificationInfo.OnSettingsClickListener.class),
|
||||
any(NotificationInfo.OnAppSettingsClickListener.class),
|
||||
eq(false),
|
||||
eq(false),
|
||||
eq(false) /* isForBlockingHelper */,
|
||||
eq(0),
|
||||
eq(false) /* wasShownHighPriority */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializeNotificationInfoView_highPriority() throws Exception {
|
||||
NotificationInfo notificationInfoView = mock(NotificationInfo.class);
|
||||
ExpandableNotificationRow row = spy(mHelper.createRow());
|
||||
row.setBlockingHelperShowing(true);
|
||||
final NotificationEntry entry = row.getEntry();
|
||||
modifyRanking(entry)
|
||||
.setUserSentiment(USER_SENTIMENT_NEGATIVE)
|
||||
@@ -403,13 +338,10 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
||||
any(NotificationChannel.class),
|
||||
anySet(),
|
||||
eq(entry),
|
||||
any(NotificationInfo.CheckSaveListener.class),
|
||||
any(NotificationInfo.OnSettingsClickListener.class),
|
||||
any(NotificationInfo.OnAppSettingsClickListener.class),
|
||||
eq(false),
|
||||
eq(false),
|
||||
eq(true) /* isForBlockingHelper */,
|
||||
eq(IMPORTANCE_HIGH),
|
||||
eq(true) /* wasShownHighPriority */);
|
||||
}
|
||||
|
||||
@@ -437,13 +369,10 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
||||
any(NotificationChannel.class),
|
||||
anySet(),
|
||||
eq(entry),
|
||||
any(NotificationInfo.CheckSaveListener.class),
|
||||
any(NotificationInfo.OnSettingsClickListener.class),
|
||||
any(NotificationInfo.OnAppSettingsClickListener.class),
|
||||
eq(true),
|
||||
eq(false),
|
||||
eq(false) /* isForBlockingHelper */,
|
||||
eq(0),
|
||||
eq(false) /* wasShownHighPriority */);
|
||||
}
|
||||
|
||||
@@ -469,13 +398,10 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
||||
any(NotificationChannel.class),
|
||||
anySet(),
|
||||
eq(entry),
|
||||
any(NotificationInfo.CheckSaveListener.class),
|
||||
any(NotificationInfo.OnSettingsClickListener.class),
|
||||
any(NotificationInfo.OnAppSettingsClickListener.class),
|
||||
eq(false),
|
||||
eq(false),
|
||||
eq(true) /* isForBlockingHelper */,
|
||||
eq(0),
|
||||
eq(false) /* wasShownHighPriority */);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,15 +119,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private PackageManager mMockPackageManager;
|
||||
@Mock
|
||||
private NotificationBlockingHelperManager mBlockingHelperManager;
|
||||
@Mock
|
||||
private VisualStabilityManager mVisualStabilityManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mDependency.injectTestDependency(
|
||||
NotificationBlockingHelperManager.class,
|
||||
mBlockingHelperManager);
|
||||
mTestableLooper = TestableLooper.get(this);
|
||||
|
||||
mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
|
||||
@@ -183,13 +178,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
|
||||
}
|
||||
|
||||
// TODO: if tests are taking too long replace this with something that makes the animation
|
||||
// finish instantly.
|
||||
private void waitForUndoButton() {
|
||||
PollingCheck.waitFor(1000,
|
||||
() -> VISIBLE == mNotificationInfo.findViewById(R.id.confirmation).getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindNotification_SetsTextApplicationName() throws Exception {
|
||||
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
|
||||
@@ -203,12 +191,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView textView = mNotificationInfo.findViewById(R.id.pkgname);
|
||||
final TextView textView = mNotificationInfo.findViewById(R.id.pkg_name);
|
||||
assertTrue(textView.getText().toString().contains("App Name"));
|
||||
assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
|
||||
}
|
||||
@@ -228,12 +214,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final ImageView iconView = mNotificationInfo.findViewById(R.id.pkgicon);
|
||||
final ImageView iconView = mNotificationInfo.findViewById(R.id.pkg_icon);
|
||||
assertEquals(iconDrawable, iconView.getDrawable());
|
||||
}
|
||||
|
||||
@@ -249,14 +233,12 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
|
||||
assertEquals(GONE, nameView.getVisibility());
|
||||
final TextView dividerView = mNotificationInfo.findViewById(R.id.pkg_divider);
|
||||
final TextView dividerView = mNotificationInfo.findViewById(R.id.group_divider);
|
||||
assertEquals(GONE, dividerView.getVisibility());
|
||||
}
|
||||
|
||||
@@ -281,16 +263,12 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
entry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
|
||||
assertEquals(VISIBLE, nameView.getVisibility());
|
||||
assertTrue(nameView.getText().toString().contains("Proxied"));
|
||||
final TextView dividerView = mNotificationInfo.findViewById(R.id.pkg_divider);
|
||||
assertEquals(VISIBLE, dividerView.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -305,13 +283,13 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
|
||||
assertEquals(GONE, groupNameView.getVisibility());
|
||||
final TextView dividerView = mNotificationInfo.findViewById(R.id.group_divider);
|
||||
assertEquals(GONE, dividerView.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -332,14 +310,14 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
|
||||
assertEquals(View.VISIBLE, groupNameView.getVisibility());
|
||||
assertEquals("Test Group Name", groupNameView.getText());
|
||||
final TextView dividerView = mNotificationInfo.findViewById(R.id.group_divider);
|
||||
assertEquals(View.VISIBLE, dividerView.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -354,10 +332,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
||||
assertEquals(TEST_CHANNEL_NAME, textView.getText());
|
||||
@@ -375,10 +351,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
||||
assertEquals(GONE, textView.getVisibility());
|
||||
@@ -387,7 +361,7 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testBindNotification_DefaultChannelUsesChannelNameIfMoreChannelsExist()
|
||||
throws Exception {
|
||||
// Package has one channel by default.
|
||||
// Package has more than one channel by default.
|
||||
when(mMockINotificationManager.getNumNotificationChannelsForPackage(
|
||||
eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(10);
|
||||
mNotificationInfo.bindNotification(
|
||||
@@ -400,10 +374,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
||||
assertEquals(VISIBLE, textView.getVisibility());
|
||||
@@ -421,41 +393,13 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
||||
assertEquals(VISIBLE, textView.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindNotification_BlockLink_BlockingHelper() throws Exception {
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
null,
|
||||
mock(NotificationInfo.OnSettingsClickListener.class),
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
true /* isBlockingHelper */,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final View block =
|
||||
mNotificationInfo.findViewById(R.id.blocking_helper_turn_off_notifications);
|
||||
final View interruptivenessSettings = mNotificationInfo.findViewById(
|
||||
R.id.inline_controls);
|
||||
assertEquals(VISIBLE, block.getVisibility());
|
||||
assertEquals(GONE, interruptivenessSettings.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
@@ -467,7 +411,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
null,
|
||||
(View v, NotificationChannel c, int appUid) -> {
|
||||
assertEquals(mNotificationChannel, c);
|
||||
latch.countDown();
|
||||
@@ -475,7 +418,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
||||
@@ -496,10 +438,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
||||
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
|
||||
@@ -516,14 +456,12 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
null,
|
||||
(View v, NotificationChannel c, int appUid) -> {
|
||||
assertEquals(mNotificationChannel, c);
|
||||
},
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
||||
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
|
||||
@@ -541,10 +479,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
@@ -554,88 +490,15 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
null,
|
||||
(View v, NotificationChannel c, int appUid) -> { },
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
||||
assertEquals(View.VISIBLE, settingsButton.getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindNotificationLogging_notBlockingHelper() throws Exception {
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
verify(mMetricsLogger).write(argThat(logMaker ->
|
||||
logMaker.getCategory() == MetricsEvent.ACTION_NOTE_CONTROLS
|
||||
&& logMaker.getType() == MetricsEvent.TYPE_OPEN
|
||||
&& logMaker.getSubtype() == MetricsEvent.BLOCKING_HELPER_UNKNOWN
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBindNotificationLogging_BlockingHelper() throws Exception {
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
verify(mMetricsLogger).write(argThat(logMaker ->
|
||||
logMaker.getCategory() == MetricsEvent.ACTION_NOTE_CONTROLS
|
||||
&& logMaker.getType() == MetricsEvent.TYPE_OPEN
|
||||
&& logMaker.getSubtype() == MetricsEvent.BLOCKING_HELPER_DISPLAY
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLogBlockingHelperCounter_logsForBlockingHelper() throws Exception {
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
|
||||
verify(mMetricsLogger).count(eq("HowCanNotifsBeRealIfAppsArent"), eq(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClickListenerPassesNullChannelForBundle() throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
@@ -646,7 +509,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
TEST_PACKAGE_NAME, mNotificationChannel,
|
||||
createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
|
||||
mEntry,
|
||||
null,
|
||||
(View v, NotificationChannel c, int appUid) -> {
|
||||
assertEquals(null, c);
|
||||
latch.countDown();
|
||||
@@ -654,7 +516,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.info).performClick();
|
||||
@@ -676,10 +537,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView channelNameView =
|
||||
mNotificationInfo.findViewById(R.id.channel_name);
|
||||
@@ -699,10 +558,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
assertEquals(GONE, mNotificationInfo.findViewById(
|
||||
R.id.interruptiveness_settings).getVisibility());
|
||||
@@ -722,10 +579,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_text);
|
||||
assertEquals(View.VISIBLE, view.getVisibility());
|
||||
@@ -747,10 +602,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
assertTrue(mNotificationInfo.findViewById(R.id.alert).isSelected());
|
||||
}
|
||||
@@ -767,10 +620,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
false);
|
||||
assertTrue(mNotificationInfo.findViewById(R.id.silence).isSelected());
|
||||
}
|
||||
@@ -787,10 +638,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
|
||||
@@ -810,10 +659,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_LOW,
|
||||
false);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.alert).performClick();
|
||||
@@ -836,10 +683,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.silence).performClick();
|
||||
@@ -862,10 +707,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
mNotificationInfo.handleCloseControls(true, false);
|
||||
@@ -889,10 +732,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_UNSPECIFIED,
|
||||
true);
|
||||
|
||||
mNotificationInfo.handleCloseControls(true, false);
|
||||
@@ -903,225 +744,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
assertEquals(IMPORTANCE_UNSPECIFIED, mNotificationChannel.getImportance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseControls_nonNullCheckSaveListenerDoesntDelayKeepShowing_BlockingHelper()
|
||||
throws Exception {
|
||||
NotificationInfo.CheckSaveListener listener =
|
||||
mock(NotificationInfo.CheckSaveListener.class);
|
||||
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel /* notificationChannel */,
|
||||
createMultipleChannelSet(10) /* numUniqueChannelsInRow */,
|
||||
mEntry,
|
||||
listener /* checkSaveListener */,
|
||||
null /* onSettingsClick */,
|
||||
null /* onAppSettingsClick */,
|
||||
true /* provisioned */,
|
||||
false /* isNonblockable */,
|
||||
true /* isForBlockingHelper */,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
NotificationGuts guts = spy(new NotificationGuts(mContext, null));
|
||||
when(guts.getWindowToken()).thenReturn(mock(IBinder.class));
|
||||
doNothing().when(guts).animateClose(anyInt(), anyInt(), anyBoolean());
|
||||
doNothing().when(guts).setExposed(anyBoolean(), anyBoolean());
|
||||
guts.setGutsContent(mNotificationInfo);
|
||||
mNotificationInfo.setGutsParent(guts);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.keep_showing).performClick();
|
||||
|
||||
verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(mMockINotificationManager, times(1))
|
||||
.setNotificationsEnabledWithImportanceLockForPackage(
|
||||
anyString(), eq(TEST_UID), eq(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseControls_nonNullCheckSaveListenerDoesntDelayDismiss_BlockingHelper()
|
||||
throws Exception {
|
||||
NotificationInfo.CheckSaveListener listener =
|
||||
mock(NotificationInfo.CheckSaveListener.class);
|
||||
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel /* notificationChannel */,
|
||||
createMultipleChannelSet(10) /* numUniqueChannelsInRow */,
|
||||
mEntry,
|
||||
listener /* checkSaveListener */,
|
||||
null /* onSettingsClick */,
|
||||
null /* onAppSettingsClick */,
|
||||
false /* isNonblockable */,
|
||||
true /* isForBlockingHelper */,
|
||||
true, IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
mNotificationInfo.handleCloseControls(true /* save */, false /* force */);
|
||||
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(listener, times(0)).checkSave(any(Runnable.class), eq(mSbn));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseControls_checkSaveListenerDelaysStopNotifications_BlockingHelper()
|
||||
throws Exception {
|
||||
NotificationInfo.CheckSaveListener listener =
|
||||
mock(NotificationInfo.CheckSaveListener.class);
|
||||
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel /* notificationChannel */,
|
||||
createMultipleChannelSet(10) /* numUniqueChannelsInRow */,
|
||||
mEntry,
|
||||
listener /* checkSaveListener */,
|
||||
null /* onSettingsClick */,
|
||||
null /* onAppSettingsClick */,
|
||||
true /* provisioned */,
|
||||
false /* isNonblockable */,
|
||||
true /* isForBlockingHelper */,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.deliver_silently).performClick();
|
||||
mTestableLooper.processAllMessages();
|
||||
verify(listener).checkSave(any(Runnable.class), eq(mSbn));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseControls_blockingHelperDismissedIfShown() throws Exception {
|
||||
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet /* numChannels */,
|
||||
mEntry,
|
||||
null /* checkSaveListener */,
|
||||
null /* onSettingsClick */,
|
||||
null /* onAppSettingsClick */,
|
||||
false /* isNonblockable */,
|
||||
true /* isForBlockingHelper */,
|
||||
true,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
NotificationGuts guts = mock(NotificationGuts.class);
|
||||
doCallRealMethod().when(guts).closeControls(anyInt(), anyInt(), anyBoolean(), anyBoolean());
|
||||
mNotificationInfo.setGutsParent(guts);
|
||||
|
||||
mNotificationInfo.closeControls(mNotificationInfo, true);
|
||||
|
||||
verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSilentlyChangedCallsUpdateNotificationChannel_blockingHelper()
|
||||
throws Exception {
|
||||
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet /* numChannels */,
|
||||
mEntry,
|
||||
null /* checkSaveListener */,
|
||||
null /* onSettingsClick */,
|
||||
null /* onAppSettingsClick */,
|
||||
true /*provisioned */,
|
||||
false /* isNonblockable */,
|
||||
true /* isForBlockingHelper */,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.deliver_silently).performClick();
|
||||
waitForUndoButton();
|
||||
mNotificationInfo.handleCloseControls(true, false);
|
||||
|
||||
mTestableLooper.processAllMessages();
|
||||
ArgumentCaptor<NotificationChannel> updated =
|
||||
ArgumentCaptor.forClass(NotificationChannel.class);
|
||||
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
|
||||
anyString(), eq(TEST_UID), updated.capture());
|
||||
assertTrue((updated.getValue().getUserLockedFields()
|
||||
& USER_LOCKED_IMPORTANCE) != 0);
|
||||
assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeepUpdatesNotificationChannel_blockingHelper() throws Exception {
|
||||
mNotificationChannel.setImportance(IMPORTANCE_LOW);
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
IMPORTANCE_LOW,
|
||||
false);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.keep_showing).performClick();
|
||||
mNotificationInfo.handleCloseControls(true, false);
|
||||
|
||||
mTestableLooper.processAllMessages();
|
||||
ArgumentCaptor<NotificationChannel> updated =
|
||||
ArgumentCaptor.forClass(NotificationChannel.class);
|
||||
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
|
||||
anyString(), eq(TEST_UID), updated.capture());
|
||||
assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE));
|
||||
assertEquals(IMPORTANCE_LOW, mNotificationChannel.getImportance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoActionsUpdatesNotificationChannel_blockingHelper() throws Exception {
|
||||
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
|
||||
mNotificationInfo.bindNotification(
|
||||
mMockPackageManager,
|
||||
mMockINotificationManager,
|
||||
mVisualStabilityManager,
|
||||
TEST_PACKAGE_NAME,
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
true,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
mNotificationInfo.handleCloseControls(true, false);
|
||||
|
||||
mTestableLooper.processAllMessages();
|
||||
ArgumentCaptor<NotificationChannel> updated =
|
||||
ArgumentCaptor.forClass(NotificationChannel.class);
|
||||
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
|
||||
anyString(), eq(TEST_UID), updated.capture());
|
||||
assertTrue(0 != (mNotificationChannel.getUserLockedFields() & USER_LOCKED_IMPORTANCE));
|
||||
assertEquals(IMPORTANCE_DEFAULT, mNotificationChannel.getImportance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSilenceCallsUpdateNotificationChannel() throws Exception {
|
||||
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
|
||||
@@ -1135,10 +757,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.silence).performClick();
|
||||
@@ -1168,10 +788,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_LOW,
|
||||
false);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.alert).performClick();
|
||||
@@ -1202,10 +820,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_UNSPECIFIED,
|
||||
true);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.silence).performClick();
|
||||
@@ -1236,10 +852,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_MIN,
|
||||
false);
|
||||
|
||||
assertEquals(mContext.getString(R.string.inline_done_button),
|
||||
@@ -1273,10 +887,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_MIN,
|
||||
false);
|
||||
|
||||
assertEquals(mContext.getString(R.string.inline_done_button),
|
||||
@@ -1309,10 +921,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_DEFAULT,
|
||||
true);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.silence).performClick();
|
||||
@@ -1336,10 +946,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_LOW,
|
||||
false);
|
||||
|
||||
assertEquals(mContext.getString(R.string.inline_done_button),
|
||||
@@ -1366,10 +974,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_LOW,
|
||||
false);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.alert).performClick();
|
||||
@@ -1399,10 +1005,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mEntry,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_LOW,
|
||||
false);
|
||||
|
||||
mNotificationInfo.findViewById(R.id.alert).performClick();
|
||||
@@ -1425,14 +1029,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
(Runnable saveImportance, StatusBarNotification sbn) -> {
|
||||
saveImportance.run();
|
||||
},
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_LOW,
|
||||
false
|
||||
);
|
||||
|
||||
@@ -1460,14 +1060,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
(Runnable saveImportance, StatusBarNotification sbn) -> {
|
||||
saveImportance.run();
|
||||
},
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_LOW,
|
||||
false
|
||||
);
|
||||
|
||||
@@ -1488,14 +1084,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
||||
mNotificationChannel,
|
||||
mNotificationChannelSet,
|
||||
mEntry,
|
||||
(Runnable saveImportance, StatusBarNotification sbn) -> {
|
||||
saveImportance.run();
|
||||
},
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false,
|
||||
IMPORTANCE_LOW,
|
||||
false
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user