Merge "Merge "Inline controls redesign" into rvc-dev am: eaebc6540c am: 259609c5cb" into rvc-d1-dev-plus-aosp
This commit is contained in:
committed by
Android (Google) Code Review
commit
1b50a2f3ec
@@ -121,7 +121,6 @@
|
|||||||
android:layout_marginEnd="2dp"
|
android:layout_marginEnd="2dp"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:text="@string/notification_delegate_header"
|
android:text="@string/notification_delegate_header"
|
||||||
android:layout_toEndOf="@id/pkg_divider"
|
|
||||||
android:maxLines="1" />
|
android:maxLines="1" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -27,51 +27,81 @@
|
|||||||
android:paddingStart="@*android:dimen/notification_content_margin_start">
|
android:paddingStart="@*android:dimen/notification_content_margin_start">
|
||||||
|
|
||||||
<!-- Package Info -->
|
<!-- Package Info -->
|
||||||
<RelativeLayout
|
<LinearLayout
|
||||||
android:id="@+id/header"
|
android:id="@+id/header"
|
||||||
android:layout_width="match_parent"
|
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:clipChildren="false"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false">
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/pkgicon"
|
android:id="@+id/pkg_icon"
|
||||||
android:layout_width="@dimen/notification_guts_header_height"
|
android:layout_width="@dimen/notification_guts_conversation_icon_size"
|
||||||
android:layout_height="@dimen/notification_guts_header_height"
|
android:layout_height="@dimen/notification_guts_conversation_icon_size"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_marginEnd="3dp" />
|
android:layout_marginEnd="15dp" />
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/pkgname"
|
android:id="@+id/names"
|
||||||
android:layout_width="wrap_content"
|
android:layout_weight="1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="@dimen/notification_guts_conversation_icon_size"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
style="@style/TextAppearance.NotificationImportanceHeader"
|
android:gravity="center_vertical"
|
||||||
android:layout_marginStart="3dp"
|
android:layout_alignEnd="@id/pkg_icon"
|
||||||
android:layout_marginEnd="2dp"
|
android:layout_toEndOf="@id/pkg_icon"
|
||||||
android:layout_toEndOf="@id/pkgicon"
|
android:layout_alignStart="@id/mute">
|
||||||
android:singleLine="true" />
|
<TextView
|
||||||
<TextView
|
android:id="@+id/channel_name"
|
||||||
android:id="@+id/pkg_divider"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
style="@style/TextAppearance.NotificationImportanceChannel"/>
|
||||||
android:layout_centerVertical="true"
|
<LinearLayout
|
||||||
style="@style/TextAppearance.NotificationImportanceHeader"
|
android:layout_width="match_parent"
|
||||||
android:layout_marginStart="2dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="2dp"
|
android:gravity="start"
|
||||||
android:layout_toEndOf="@id/pkgname"
|
android:orientation="horizontal">
|
||||||
android:text="@*android:string/notification_header_divider_symbol" />
|
<TextView
|
||||||
<TextView
|
android:id="@+id/pkg_name"
|
||||||
android:id="@+id/delegate_name"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
style="@style/TextAppearance.NotificationImportanceChannelGroup"
|
||||||
android:layout_centerVertical="true"
|
android:ellipsize="end"
|
||||||
style="@style/TextAppearance.NotificationImportanceHeader"
|
android:maxLines="1"/>
|
||||||
android:layout_marginStart="2dp"
|
<TextView
|
||||||
android:layout_marginEnd="2dp"
|
android:id="@+id/group_divider"
|
||||||
android:ellipsize="end"
|
android:layout_width="wrap_content"
|
||||||
android:text="@string/notification_delegate_header"
|
android:layout_height="wrap_content"
|
||||||
android:layout_toEndOf="@id/pkg_divider"
|
android:layout_centerVertical="true"
|
||||||
android:maxLines="1" />
|
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
|
<!-- Optional link to app. Only appears if the channel is not disabled and the app
|
||||||
asked for it -->
|
asked for it -->
|
||||||
<ImageButton
|
<ImageButton
|
||||||
@@ -95,91 +125,6 @@ asked for it -->
|
|||||||
android:src="@drawable/ic_settings"
|
android:src="@drawable/ic_settings"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:tint="@color/notification_guts_link_icon_tint"/>
|
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>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -357,34 +302,4 @@ asked for it -->
|
|||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</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>
|
</com.android.systemui.statusbar.notification.row.NotificationInfo>
|
||||||
|
|||||||
@@ -315,7 +315,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
|||||||
mNotificationActivityStarter.startNotificationGutsIntent(intent, sbn.getUid(),
|
mNotificationActivityStarter.startNotificationGutsIntent(intent, sbn.getUid(),
|
||||||
row);
|
row);
|
||||||
};
|
};
|
||||||
boolean isForBlockingHelper = row.isBlockingHelperShowing();
|
|
||||||
|
|
||||||
if (!userHandle.equals(UserHandle.ALL)
|
if (!userHandle.equals(UserHandle.ALL)
|
||||||
|| mLockscreenUserManager.getCurrentUserId() == UserHandle.USER_SYSTEM) {
|
|| mLockscreenUserManager.getCurrentUserId() == UserHandle.USER_SYSTEM) {
|
||||||
@@ -335,13 +334,10 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
|
|||||||
row.getEntry().getChannel(),
|
row.getEntry().getChannel(),
|
||||||
row.getUniqueChannels(),
|
row.getUniqueChannels(),
|
||||||
row.getEntry(),
|
row.getEntry(),
|
||||||
mCheckSaveListener,
|
|
||||||
onSettingsClick,
|
onSettingsClick,
|
||||||
onAppSettingsClick,
|
onAppSettingsClick,
|
||||||
mDeviceProvisionedController.isDeviceProvisioned(),
|
mDeviceProvisionedController.isDeviceProvisioned(),
|
||||||
row.getIsNonblockable(),
|
row.getIsNonblockable(),
|
||||||
isForBlockingHelper,
|
|
||||||
row.getEntry().getImportance(),
|
|
||||||
mHighPriorityProvider.isHighPriority(row.getEntry()));
|
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 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.IntDef;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.app.INotificationManager;
|
import android.app.INotificationManager;
|
||||||
@@ -53,7 +49,6 @@ import android.transition.TransitionSet;
|
|||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.accessibility.AccessibilityEvent;
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
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.MetricsLogger;
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.Interpolators;
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.statusbar.notification.VisualStabilityManager;
|
import com.android.systemui.statusbar.notification.VisualStabilityManager;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.notification.logging.NotificationCounters;
|
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The guts of a notification revealed when performing a long press. This also houses the blocking
|
* The guts of a notification revealed when performing a long press.
|
||||||
* helper affordance that allows a user to keep/stop notifications after swiping one away.
|
|
||||||
*/
|
*/
|
||||||
public class NotificationInfo extends LinearLayout implements NotificationGuts.GutsContent {
|
public class NotificationInfo extends LinearLayout implements NotificationGuts.GutsContent {
|
||||||
private static final String TAG = "InfoGuts";
|
private static final String TAG = "InfoGuts";
|
||||||
|
|
||||||
@IntDef(prefix = { "ACTION_" }, value = {
|
@IntDef(prefix = { "ACTION_" }, value = {
|
||||||
ACTION_NONE,
|
ACTION_NONE,
|
||||||
ACTION_UNDO,
|
ACTION_TOGGLE_ALERT,
|
||||||
ACTION_TOGGLE_SILENT,
|
ACTION_TOGGLE_SILENT,
|
||||||
ACTION_BLOCK,
|
|
||||||
})
|
})
|
||||||
public @interface NotificationInfoAction {
|
public @interface NotificationInfoAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int ACTION_NONE = 0;
|
public static final int ACTION_NONE = 0;
|
||||||
static final int ACTION_UNDO = 1;
|
|
||||||
// standard controls
|
// standard controls
|
||||||
static final int ACTION_TOGGLE_SILENT = 2;
|
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
|
// standard controls
|
||||||
private static final int ACTION_ALERT = 5;
|
private static final int ACTION_TOGGLE_ALERT = 5;
|
||||||
|
|
||||||
private TextView mPriorityDescriptionView;
|
private TextView mPriorityDescriptionView;
|
||||||
private TextView mSilentDescriptionView;
|
private TextView mSilentDescriptionView;
|
||||||
@@ -128,101 +114,35 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
@Nullable private Integer mChosenImportance;
|
@Nullable private Integer mChosenImportance;
|
||||||
private boolean mIsSingleDefaultChannel;
|
private boolean mIsSingleDefaultChannel;
|
||||||
private boolean mIsNonblockable;
|
private boolean mIsNonblockable;
|
||||||
private NotificationEntry mEntry;
|
|
||||||
private StatusBarNotification mSbn;
|
private StatusBarNotification mSbn;
|
||||||
private AnimatorSet mExpandAnimation;
|
|
||||||
private boolean mIsDeviceProvisioned;
|
private boolean mIsDeviceProvisioned;
|
||||||
|
|
||||||
private CheckSaveListener mCheckSaveListener;
|
|
||||||
private OnSettingsClickListener mOnSettingsClickListener;
|
private OnSettingsClickListener mOnSettingsClickListener;
|
||||||
private OnAppSettingsClickListener mAppSettingsClickListener;
|
private OnAppSettingsClickListener mAppSettingsClickListener;
|
||||||
private NotificationGuts mGutsContainer;
|
private NotificationGuts mGutsContainer;
|
||||||
private Drawable mPkgIcon;
|
private Drawable mPkgIcon;
|
||||||
|
|
||||||
/** Whether this view is being shown as part of the blocking helper. */
|
|
||||||
private boolean mIsForBlockingHelper;
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
boolean mSkipPost = false;
|
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
|
// used by standard ui
|
||||||
private OnClickListener mOnAlert = v -> {
|
private OnClickListener mOnAlert = v -> {
|
||||||
mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
|
|
||||||
mChosenImportance = IMPORTANCE_DEFAULT;
|
mChosenImportance = IMPORTANCE_DEFAULT;
|
||||||
applyAlertingBehavior(BEHAVIOR_ALERTING, true /* userTriggered */);
|
applyAlertingBehavior(BEHAVIOR_ALERTING, true /* userTriggered */);
|
||||||
};
|
};
|
||||||
|
|
||||||
// used by standard ui
|
// used by standard ui
|
||||||
private OnClickListener mOnSilent = v -> {
|
private OnClickListener mOnSilent = v -> {
|
||||||
mExitReason = NotificationCounters.BLOCKING_HELPER_DELIVER_SILENTLY;
|
|
||||||
mChosenImportance = IMPORTANCE_LOW;
|
mChosenImportance = IMPORTANCE_LOW;
|
||||||
applyAlertingBehavior(BEHAVIOR_SILENT, true /* userTriggered */);
|
applyAlertingBehavior(BEHAVIOR_SILENT, true /* userTriggered */);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// used by standard ui
|
// used by standard ui
|
||||||
private OnClickListener mOnDismissSettings = v -> {
|
private OnClickListener mOnDismissSettings = v -> {
|
||||||
mPressedApply = true;
|
mPressedApply = true;
|
||||||
closeControls(v, 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) {
|
public NotificationInfo(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
@@ -250,30 +170,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
void onClick(View v, Intent intent);
|
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(
|
public void bindNotification(
|
||||||
PackageManager pm,
|
PackageManager pm,
|
||||||
INotificationManager iNotificationManager,
|
INotificationManager iNotificationManager,
|
||||||
@@ -282,13 +178,10 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
NotificationChannel notificationChannel,
|
NotificationChannel notificationChannel,
|
||||||
Set<NotificationChannel> uniqueChannelsInRow,
|
Set<NotificationChannel> uniqueChannelsInRow,
|
||||||
NotificationEntry entry,
|
NotificationEntry entry,
|
||||||
CheckSaveListener checkSaveListener,
|
|
||||||
OnSettingsClickListener onSettingsClick,
|
OnSettingsClickListener onSettingsClick,
|
||||||
OnAppSettingsClickListener onAppSettingsClick,
|
OnAppSettingsClickListener onAppSettingsClick,
|
||||||
boolean isDeviceProvisioned,
|
boolean isDeviceProvisioned,
|
||||||
boolean isNonblockable,
|
boolean isNonblockable,
|
||||||
boolean isForBlockingHelper,
|
|
||||||
int importance,
|
|
||||||
boolean wasShownHighPriority)
|
boolean wasShownHighPriority)
|
||||||
throws RemoteException {
|
throws RemoteException {
|
||||||
mINotificationManager = iNotificationManager;
|
mINotificationManager = iNotificationManager;
|
||||||
@@ -298,18 +191,15 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
mPackageName = pkg;
|
mPackageName = pkg;
|
||||||
mUniqueChannelsInRow = uniqueChannelsInRow;
|
mUniqueChannelsInRow = uniqueChannelsInRow;
|
||||||
mNumUniqueChannelsInRow = uniqueChannelsInRow.size();
|
mNumUniqueChannelsInRow = uniqueChannelsInRow.size();
|
||||||
mEntry = entry;
|
|
||||||
mSbn = entry.getSbn();
|
mSbn = entry.getSbn();
|
||||||
mPm = pm;
|
mPm = pm;
|
||||||
mAppSettingsClickListener = onAppSettingsClick;
|
mAppSettingsClickListener = onAppSettingsClick;
|
||||||
mAppName = mPackageName;
|
mAppName = mPackageName;
|
||||||
mCheckSaveListener = checkSaveListener;
|
|
||||||
mOnSettingsClickListener = onSettingsClick;
|
mOnSettingsClickListener = onSettingsClick;
|
||||||
mSingleNotificationChannel = notificationChannel;
|
mSingleNotificationChannel = notificationChannel;
|
||||||
mStartingChannelImportance = mSingleNotificationChannel.getImportance();
|
mStartingChannelImportance = mSingleNotificationChannel.getImportance();
|
||||||
mWasShownHighPriority = wasShownHighPriority;
|
mWasShownHighPriority = wasShownHighPriority;
|
||||||
mIsNonblockable = isNonblockable;
|
mIsNonblockable = isNonblockable;
|
||||||
mIsForBlockingHelper = isForBlockingHelper;
|
|
||||||
mAppUid = mSbn.getUid();
|
mAppUid = mSbn.getUid();
|
||||||
mDelegatePkg = mSbn.getOpPkg();
|
mDelegatePkg = mSbn.getOpPkg();
|
||||||
mIsDeviceProvisioned = isDeviceProvisioned;
|
mIsDeviceProvisioned = isDeviceProvisioned;
|
||||||
@@ -329,36 +219,12 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
bindHeader();
|
bindHeader();
|
||||||
bindChannelDetails();
|
bindChannelDetails();
|
||||||
|
|
||||||
if (mIsForBlockingHelper) {
|
bindInlineControls();
|
||||||
bindBlockingHelper();
|
|
||||||
} else {
|
|
||||||
bindInlineControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
mMetricsLogger.write(notificationControlsLogMaker());
|
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() {
|
private void bindInlineControls() {
|
||||||
findViewById(R.id.inline_controls).setVisibility(VISIBLE);
|
|
||||||
findViewById(R.id.blocking_helper).setVisibility(GONE);
|
|
||||||
|
|
||||||
if (mIsNonblockable) {
|
if (mIsNonblockable) {
|
||||||
findViewById(R.id.non_configurable_text).setVisibility(VISIBLE);
|
findViewById(R.id.non_configurable_text).setVisibility(VISIBLE);
|
||||||
findViewById(R.id.non_configurable_multichannel_text).setVisibility(GONE);
|
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
|
// app is gone, just show package name and generic icon
|
||||||
mPkgIcon = mPm.getDefaultActivityIcon();
|
mPkgIcon = mPm.getDefaultActivityIcon();
|
||||||
}
|
}
|
||||||
((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(mPkgIcon);
|
((ImageView) findViewById(R.id.pkg_icon)).setImageDrawable(mPkgIcon);
|
||||||
((TextView) findViewById(R.id.pkgname)).setText(mAppName);
|
((TextView) findViewById(R.id.pkg_name)).setText(mAppName);
|
||||||
|
|
||||||
// Delegate
|
// Delegate
|
||||||
bindDelegate();
|
bindDelegate();
|
||||||
@@ -445,8 +311,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
if (mAppUid >= 0 && mOnSettingsClickListener != null && mIsDeviceProvisioned) {
|
if (mAppUid >= 0 && mOnSettingsClickListener != null && mIsDeviceProvisioned) {
|
||||||
final int appUidF = mAppUid;
|
final int appUidF = mAppUid;
|
||||||
return ((View view) -> {
|
return ((View view) -> {
|
||||||
logBlockingHelperCounter(
|
|
||||||
NotificationCounters.BLOCKING_HELPER_NOTIF_SETTINGS);
|
|
||||||
mOnSettingsClickListener.onClick(view,
|
mOnSettingsClickListener.onClick(view,
|
||||||
mNumUniqueChannelsInRow > 1 ? null : mSingleNotificationChannel,
|
mNumUniqueChannelsInRow > 1 ? null : mSingleNotificationChannel,
|
||||||
appUidF);
|
appUidF);
|
||||||
@@ -487,16 +351,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
|
|
||||||
private void bindDelegate() {
|
private void bindDelegate() {
|
||||||
TextView delegateView = findViewById(R.id.delegate_name);
|
TextView delegateView = findViewById(R.id.delegate_name);
|
||||||
TextView dividerView = findViewById(R.id.pkg_divider);
|
|
||||||
|
|
||||||
CharSequence delegatePkg = null;
|
CharSequence delegatePkg = null;
|
||||||
if (!TextUtils.equals(mPackageName, mDelegatePkg)) {
|
if (!TextUtils.equals(mPackageName, mDelegatePkg)) {
|
||||||
// this notification was posted by a delegate!
|
// this notification was posted by a delegate!
|
||||||
delegateView.setVisibility(View.VISIBLE);
|
delegateView.setVisibility(View.VISIBLE);
|
||||||
dividerView.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
} else {
|
||||||
delegateView.setVisibility(View.GONE);
|
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);
|
TextView groupNameView = findViewById(R.id.group_name);
|
||||||
|
View divider = findViewById(R.id.group_divider);
|
||||||
if (groupName != null) {
|
if (groupName != null) {
|
||||||
groupNameView.setText(groupName);
|
groupNameView.setText(groupName);
|
||||||
groupNameView.setVisibility(View.VISIBLE);
|
groupNameView.setVisibility(VISIBLE);
|
||||||
|
divider.setVisibility(VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
groupNameView.setVisibility(View.GONE);
|
groupNameView.setVisibility(GONE);
|
||||||
}
|
divider.setVisibility(GONE);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
void logBlockingHelperCounter(String counterTag) {
|
|
||||||
if (mIsForBlockingHelper) {
|
|
||||||
mMetricsLogger.count(counterTag, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveImportance() {
|
private void saveImportance() {
|
||||||
if (!mIsNonblockable
|
if (!mIsNonblockable) {
|
||||||
|| mExitReason != NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS) {
|
|
||||||
if (mChosenImportance == null) {
|
if (mChosenImportance == null) {
|
||||||
mChosenImportance = mStartingChannelImportance;
|
mChosenImportance = mStartingChannelImportance;
|
||||||
}
|
}
|
||||||
@@ -621,99 +476,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
: R.string.inline_done_button);
|
: 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
|
@Override
|
||||||
public void onFinishedClosing() {
|
public void onFinishedClosing() {
|
||||||
if (mChosenImportance != null) {
|
if (mChosenImportance != null) {
|
||||||
mStartingChannelImportance = mChosenImportance;
|
mStartingChannelImportance = mChosenImportance;
|
||||||
}
|
}
|
||||||
mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
|
|
||||||
|
|
||||||
if (mIsForBlockingHelper) {
|
bindInlineControls();
|
||||||
bindBlockingHelper();
|
|
||||||
} else {
|
|
||||||
bindInlineControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
mMetricsLogger.write(notificationControlsLogMaker().setType(MetricsEvent.TYPE_CLOSE));
|
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
|
* Closes the controls and commits the updated importance values (indirectly).
|
||||||
* being used to show the blocking helper, this will immediately dismiss the blocking helper and
|
|
||||||
* commit the updated importance.
|
|
||||||
*
|
*
|
||||||
* <p><b>Note,</b> this will only get called once the view is dismissing. This means that the
|
* <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
|
* user does not have the ability to undo the action anymore.
|
||||||
* {@link #swapContent(boolean, boolean)} for where undo is handled.
|
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void closeControls(View v, boolean save) {
|
void closeControls(View v, boolean save) {
|
||||||
@@ -811,7 +577,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
if (save) {
|
if (save) {
|
||||||
saveImportance();
|
saveImportance();
|
||||||
}
|
}
|
||||||
logBlockingHelperCounter(mExitReason);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -822,7 +587,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public boolean isAnimating() {
|
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() {
|
private LogMaker notificationControlsLogMaker() {
|
||||||
return getLogMaker().setCategory(MetricsEvent.ACTION_NOTE_CONTROLS)
|
return getLogMaker().setCategory(MetricsEvent.ACTION_NOTE_CONTROLS)
|
||||||
.setType(MetricsEvent.TYPE_OPEN)
|
.setType(MetricsEvent.TYPE_OPEN)
|
||||||
.setSubtype(mIsForBlockingHelper ? MetricsEvent.BLOCKING_HELPER_DISPLAY
|
.setSubtype(MetricsEvent.BLOCKING_HELPER_UNKNOWN);
|
||||||
: MetricsEvent.BLOCKING_HELPER_UNKNOWN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Retention(SOURCE)
|
@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());
|
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
|
@Test
|
||||||
public void testInitializeNotificationInfoView_highPriority() throws Exception {
|
public void testInitializeNotificationInfoView_highPriority() throws Exception {
|
||||||
NotificationInfo notificationInfoView = mock(NotificationInfo.class);
|
NotificationInfo notificationInfoView = mock(NotificationInfo.class);
|
||||||
ExpandableNotificationRow row = spy(mHelper.createRow());
|
ExpandableNotificationRow row = spy(mHelper.createRow());
|
||||||
row.setBlockingHelperShowing(true);
|
|
||||||
final NotificationEntry entry = row.getEntry();
|
final NotificationEntry entry = row.getEntry();
|
||||||
modifyRanking(entry)
|
modifyRanking(entry)
|
||||||
.setUserSentiment(USER_SENTIMENT_NEGATIVE)
|
.setUserSentiment(USER_SENTIMENT_NEGATIVE)
|
||||||
@@ -403,13 +338,10 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
|||||||
any(NotificationChannel.class),
|
any(NotificationChannel.class),
|
||||||
anySet(),
|
anySet(),
|
||||||
eq(entry),
|
eq(entry),
|
||||||
any(NotificationInfo.CheckSaveListener.class),
|
|
||||||
any(NotificationInfo.OnSettingsClickListener.class),
|
any(NotificationInfo.OnSettingsClickListener.class),
|
||||||
any(NotificationInfo.OnAppSettingsClickListener.class),
|
any(NotificationInfo.OnAppSettingsClickListener.class),
|
||||||
eq(false),
|
eq(false),
|
||||||
eq(false),
|
eq(false),
|
||||||
eq(true) /* isForBlockingHelper */,
|
|
||||||
eq(IMPORTANCE_HIGH),
|
|
||||||
eq(true) /* wasShownHighPriority */);
|
eq(true) /* wasShownHighPriority */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,13 +369,10 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
|||||||
any(NotificationChannel.class),
|
any(NotificationChannel.class),
|
||||||
anySet(),
|
anySet(),
|
||||||
eq(entry),
|
eq(entry),
|
||||||
any(NotificationInfo.CheckSaveListener.class),
|
|
||||||
any(NotificationInfo.OnSettingsClickListener.class),
|
any(NotificationInfo.OnSettingsClickListener.class),
|
||||||
any(NotificationInfo.OnAppSettingsClickListener.class),
|
any(NotificationInfo.OnAppSettingsClickListener.class),
|
||||||
eq(true),
|
eq(true),
|
||||||
eq(false),
|
eq(false),
|
||||||
eq(false) /* isForBlockingHelper */,
|
|
||||||
eq(0),
|
|
||||||
eq(false) /* wasShownHighPriority */);
|
eq(false) /* wasShownHighPriority */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,13 +398,10 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
|
|||||||
any(NotificationChannel.class),
|
any(NotificationChannel.class),
|
||||||
anySet(),
|
anySet(),
|
||||||
eq(entry),
|
eq(entry),
|
||||||
any(NotificationInfo.CheckSaveListener.class),
|
|
||||||
any(NotificationInfo.OnSettingsClickListener.class),
|
any(NotificationInfo.OnSettingsClickListener.class),
|
||||||
any(NotificationInfo.OnAppSettingsClickListener.class),
|
any(NotificationInfo.OnAppSettingsClickListener.class),
|
||||||
eq(false),
|
eq(false),
|
||||||
eq(false),
|
eq(false),
|
||||||
eq(true) /* isForBlockingHelper */,
|
|
||||||
eq(0),
|
|
||||||
eq(false) /* wasShownHighPriority */);
|
eq(false) /* wasShownHighPriority */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,15 +119,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private PackageManager mMockPackageManager;
|
private PackageManager mMockPackageManager;
|
||||||
@Mock
|
@Mock
|
||||||
private NotificationBlockingHelperManager mBlockingHelperManager;
|
|
||||||
@Mock
|
|
||||||
private VisualStabilityManager mVisualStabilityManager;
|
private VisualStabilityManager mVisualStabilityManager;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mDependency.injectTestDependency(
|
|
||||||
NotificationBlockingHelperManager.class,
|
|
||||||
mBlockingHelperManager);
|
|
||||||
mTestableLooper = TestableLooper.get(this);
|
mTestableLooper = TestableLooper.get(this);
|
||||||
|
|
||||||
mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
|
mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
|
||||||
@@ -183,13 +178,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
|
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
|
@Test
|
||||||
public void testBindNotification_SetsTextApplicationName() throws Exception {
|
public void testBindNotification_SetsTextApplicationName() throws Exception {
|
||||||
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
|
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
|
||||||
@@ -203,12 +191,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
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"));
|
assertTrue(textView.getText().toString().contains("App Name"));
|
||||||
assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
|
assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
|
||||||
}
|
}
|
||||||
@@ -228,12 +214,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final ImageView iconView = mNotificationInfo.findViewById(R.id.pkgicon);
|
final ImageView iconView = mNotificationInfo.findViewById(R.id.pkg_icon);
|
||||||
assertEquals(iconDrawable, iconView.getDrawable());
|
assertEquals(iconDrawable, iconView.getDrawable());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,14 +233,12 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
|
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
|
||||||
assertEquals(GONE, nameView.getVisibility());
|
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());
|
assertEquals(GONE, dividerView.getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,16 +263,12 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
entry,
|
entry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
|
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
|
||||||
assertEquals(VISIBLE, nameView.getVisibility());
|
assertEquals(VISIBLE, nameView.getVisibility());
|
||||||
assertTrue(nameView.getText().toString().contains("Proxied"));
|
assertTrue(nameView.getText().toString().contains("Proxied"));
|
||||||
final TextView dividerView = mNotificationInfo.findViewById(R.id.pkg_divider);
|
|
||||||
assertEquals(VISIBLE, dividerView.getVisibility());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -305,13 +283,13 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
|
final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
|
||||||
assertEquals(GONE, groupNameView.getVisibility());
|
assertEquals(GONE, groupNameView.getVisibility());
|
||||||
|
final TextView dividerView = mNotificationInfo.findViewById(R.id.group_divider);
|
||||||
|
assertEquals(GONE, dividerView.getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -332,14 +310,14 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
|
final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
|
||||||
assertEquals(View.VISIBLE, groupNameView.getVisibility());
|
assertEquals(View.VISIBLE, groupNameView.getVisibility());
|
||||||
assertEquals("Test Group Name", groupNameView.getText());
|
assertEquals("Test Group Name", groupNameView.getText());
|
||||||
|
final TextView dividerView = mNotificationInfo.findViewById(R.id.group_divider);
|
||||||
|
assertEquals(View.VISIBLE, dividerView.getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -354,10 +332,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
||||||
assertEquals(TEST_CHANNEL_NAME, textView.getText());
|
assertEquals(TEST_CHANNEL_NAME, textView.getText());
|
||||||
@@ -375,10 +351,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
||||||
assertEquals(GONE, textView.getVisibility());
|
assertEquals(GONE, textView.getVisibility());
|
||||||
@@ -387,7 +361,7 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testBindNotification_DefaultChannelUsesChannelNameIfMoreChannelsExist()
|
public void testBindNotification_DefaultChannelUsesChannelNameIfMoreChannelsExist()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
// Package has one channel by default.
|
// Package has more than one channel by default.
|
||||||
when(mMockINotificationManager.getNumNotificationChannelsForPackage(
|
when(mMockINotificationManager.getNumNotificationChannelsForPackage(
|
||||||
eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(10);
|
eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(10);
|
||||||
mNotificationInfo.bindNotification(
|
mNotificationInfo.bindNotification(
|
||||||
@@ -400,10 +374,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
||||||
assertEquals(VISIBLE, textView.getVisibility());
|
assertEquals(VISIBLE, textView.getVisibility());
|
||||||
@@ -421,41 +393,13 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
|
||||||
assertEquals(VISIBLE, textView.getVisibility());
|
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
|
@Test
|
||||||
public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
|
public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
@@ -467,7 +411,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mNotificationChannel,
|
mNotificationChannel,
|
||||||
mNotificationChannelSet,
|
mNotificationChannelSet,
|
||||||
mEntry,
|
mEntry,
|
||||||
null,
|
|
||||||
(View v, NotificationChannel c, int appUid) -> {
|
(View v, NotificationChannel c, int appUid) -> {
|
||||||
assertEquals(mNotificationChannel, c);
|
assertEquals(mNotificationChannel, c);
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
@@ -475,7 +418,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
|
|
||||||
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
||||||
@@ -496,10 +438,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
||||||
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
|
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
|
||||||
@@ -516,14 +456,12 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mNotificationChannel,
|
mNotificationChannel,
|
||||||
mNotificationChannelSet,
|
mNotificationChannelSet,
|
||||||
mEntry,
|
mEntry,
|
||||||
null,
|
|
||||||
(View v, NotificationChannel c, int appUid) -> {
|
(View v, NotificationChannel c, int appUid) -> {
|
||||||
assertEquals(mNotificationChannel, c);
|
assertEquals(mNotificationChannel, c);
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
||||||
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
|
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
|
||||||
@@ -541,10 +479,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
mNotificationInfo.bindNotification(
|
mNotificationInfo.bindNotification(
|
||||||
mMockPackageManager,
|
mMockPackageManager,
|
||||||
@@ -554,88 +490,15 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mNotificationChannel,
|
mNotificationChannel,
|
||||||
mNotificationChannelSet,
|
mNotificationChannelSet,
|
||||||
mEntry,
|
mEntry,
|
||||||
null,
|
|
||||||
(View v, NotificationChannel c, int appUid) -> { },
|
(View v, NotificationChannel c, int appUid) -> { },
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
|
||||||
assertEquals(View.VISIBLE, settingsButton.getVisibility());
|
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
|
@Test
|
||||||
public void testOnClickListenerPassesNullChannelForBundle() throws Exception {
|
public void testOnClickListenerPassesNullChannelForBundle() throws Exception {
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
@@ -646,7 +509,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
TEST_PACKAGE_NAME, mNotificationChannel,
|
TEST_PACKAGE_NAME, mNotificationChannel,
|
||||||
createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
|
createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
|
||||||
mEntry,
|
mEntry,
|
||||||
null,
|
|
||||||
(View v, NotificationChannel c, int appUid) -> {
|
(View v, NotificationChannel c, int appUid) -> {
|
||||||
assertEquals(null, c);
|
assertEquals(null, c);
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
@@ -654,7 +516,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
|
|
||||||
mNotificationInfo.findViewById(R.id.info).performClick();
|
mNotificationInfo.findViewById(R.id.info).performClick();
|
||||||
@@ -676,10 +537,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView channelNameView =
|
final TextView channelNameView =
|
||||||
mNotificationInfo.findViewById(R.id.channel_name);
|
mNotificationInfo.findViewById(R.id.channel_name);
|
||||||
@@ -699,10 +558,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
assertEquals(GONE, mNotificationInfo.findViewById(
|
assertEquals(GONE, mNotificationInfo.findViewById(
|
||||||
R.id.interruptiveness_settings).getVisibility());
|
R.id.interruptiveness_settings).getVisibility());
|
||||||
@@ -722,10 +579,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_text);
|
final TextView view = mNotificationInfo.findViewById(R.id.non_configurable_text);
|
||||||
assertEquals(View.VISIBLE, view.getVisibility());
|
assertEquals(View.VISIBLE, view.getVisibility());
|
||||||
@@ -747,10 +602,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
assertTrue(mNotificationInfo.findViewById(R.id.alert).isSelected());
|
assertTrue(mNotificationInfo.findViewById(R.id.alert).isSelected());
|
||||||
}
|
}
|
||||||
@@ -767,10 +620,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
false);
|
false);
|
||||||
assertTrue(mNotificationInfo.findViewById(R.id.silence).isSelected());
|
assertTrue(mNotificationInfo.findViewById(R.id.silence).isSelected());
|
||||||
}
|
}
|
||||||
@@ -787,10 +638,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
|
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
|
||||||
@@ -810,10 +659,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_LOW,
|
|
||||||
false);
|
false);
|
||||||
|
|
||||||
mNotificationInfo.findViewById(R.id.alert).performClick();
|
mNotificationInfo.findViewById(R.id.alert).performClick();
|
||||||
@@ -836,10 +683,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
|
|
||||||
mNotificationInfo.findViewById(R.id.silence).performClick();
|
mNotificationInfo.findViewById(R.id.silence).performClick();
|
||||||
@@ -862,10 +707,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
|
|
||||||
mNotificationInfo.handleCloseControls(true, false);
|
mNotificationInfo.handleCloseControls(true, false);
|
||||||
@@ -889,10 +732,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_UNSPECIFIED,
|
|
||||||
true);
|
true);
|
||||||
|
|
||||||
mNotificationInfo.handleCloseControls(true, false);
|
mNotificationInfo.handleCloseControls(true, false);
|
||||||
@@ -903,225 +744,6 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
assertEquals(IMPORTANCE_UNSPECIFIED, mNotificationChannel.getImportance());
|
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
|
@Test
|
||||||
public void testSilenceCallsUpdateNotificationChannel() throws Exception {
|
public void testSilenceCallsUpdateNotificationChannel() throws Exception {
|
||||||
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
|
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
|
||||||
@@ -1135,10 +757,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
|
|
||||||
mNotificationInfo.findViewById(R.id.silence).performClick();
|
mNotificationInfo.findViewById(R.id.silence).performClick();
|
||||||
@@ -1168,10 +788,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_LOW,
|
|
||||||
false);
|
false);
|
||||||
|
|
||||||
mNotificationInfo.findViewById(R.id.alert).performClick();
|
mNotificationInfo.findViewById(R.id.alert).performClick();
|
||||||
@@ -1202,10 +820,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_UNSPECIFIED,
|
|
||||||
true);
|
true);
|
||||||
|
|
||||||
mNotificationInfo.findViewById(R.id.silence).performClick();
|
mNotificationInfo.findViewById(R.id.silence).performClick();
|
||||||
@@ -1236,10 +852,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_MIN,
|
|
||||||
false);
|
false);
|
||||||
|
|
||||||
assertEquals(mContext.getString(R.string.inline_done_button),
|
assertEquals(mContext.getString(R.string.inline_done_button),
|
||||||
@@ -1273,10 +887,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_MIN,
|
|
||||||
false);
|
false);
|
||||||
|
|
||||||
assertEquals(mContext.getString(R.string.inline_done_button),
|
assertEquals(mContext.getString(R.string.inline_done_button),
|
||||||
@@ -1309,10 +921,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_DEFAULT,
|
|
||||||
true);
|
true);
|
||||||
|
|
||||||
mNotificationInfo.findViewById(R.id.silence).performClick();
|
mNotificationInfo.findViewById(R.id.silence).performClick();
|
||||||
@@ -1336,10 +946,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_LOW,
|
|
||||||
false);
|
false);
|
||||||
|
|
||||||
assertEquals(mContext.getString(R.string.inline_done_button),
|
assertEquals(mContext.getString(R.string.inline_done_button),
|
||||||
@@ -1366,10 +974,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_LOW,
|
|
||||||
false);
|
false);
|
||||||
|
|
||||||
mNotificationInfo.findViewById(R.id.alert).performClick();
|
mNotificationInfo.findViewById(R.id.alert).performClick();
|
||||||
@@ -1399,10 +1005,8 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mEntry,
|
mEntry,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_LOW,
|
|
||||||
false);
|
false);
|
||||||
|
|
||||||
mNotificationInfo.findViewById(R.id.alert).performClick();
|
mNotificationInfo.findViewById(R.id.alert).performClick();
|
||||||
@@ -1425,14 +1029,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mNotificationChannel,
|
mNotificationChannel,
|
||||||
mNotificationChannelSet,
|
mNotificationChannelSet,
|
||||||
mEntry,
|
mEntry,
|
||||||
(Runnable saveImportance, StatusBarNotification sbn) -> {
|
|
||||||
saveImportance.run();
|
|
||||||
},
|
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_LOW,
|
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1460,14 +1060,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mNotificationChannel,
|
mNotificationChannel,
|
||||||
mNotificationChannelSet,
|
mNotificationChannelSet,
|
||||||
mEntry,
|
mEntry,
|
||||||
(Runnable saveImportance, StatusBarNotification sbn) -> {
|
|
||||||
saveImportance.run();
|
|
||||||
},
|
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_LOW,
|
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1488,14 +1084,10 @@ public class NotificationInfoTest extends SysuiTestCase {
|
|||||||
mNotificationChannel,
|
mNotificationChannel,
|
||||||
mNotificationChannelSet,
|
mNotificationChannelSet,
|
||||||
mEntry,
|
mEntry,
|
||||||
(Runnable saveImportance, StatusBarNotification sbn) -> {
|
|
||||||
saveImportance.run();
|
|
||||||
},
|
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
IMPORTANCE_LOW,
|
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user