Change NotificationGuts to contain a view
NotificationGuts is now given a view to display, the notification management controls have been moved into their own view. NotificationGuts is provided a view to show via a MenuItem. This allows configuration via the NotificationMenuRowProvider Plugin. Test: manual Change-Id: I68cb23ea2cada30cc6e930fa8c03e0aa4014dfe2
This commit is contained in:
@@ -3,6 +3,7 @@ package com.android.systemui.plugins.statusbar;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -26,14 +27,34 @@ public interface NotificationMenuRowProvider extends Plugin {
|
||||
public void onMenuReset(View row);
|
||||
}
|
||||
|
||||
public interface GutsInteractionListener {
|
||||
public void onInteraction(View view);
|
||||
|
||||
public void closeGuts(View view);
|
||||
}
|
||||
|
||||
public interface GutsContent {
|
||||
public void setInteractionListener(GutsInteractionListener listener);
|
||||
|
||||
public View getContentView();
|
||||
|
||||
public boolean handleCloseControls();
|
||||
}
|
||||
|
||||
public static class MenuItem {
|
||||
public Drawable icon;
|
||||
public String menuDescription;
|
||||
public View menuView;
|
||||
public GutsContent gutsContent;
|
||||
|
||||
public MenuItem(Drawable i, String s) {
|
||||
public MenuItem(Drawable i, String s, GutsContent content) {
|
||||
icon = i;
|
||||
menuDescription = s;
|
||||
gutsContent = content;
|
||||
}
|
||||
|
||||
public View getGutsView() {
|
||||
return gutsContent.getContentView();
|
||||
}
|
||||
|
||||
public boolean onTouch(View v, int x, int y) {
|
||||
|
||||
@@ -23,125 +23,4 @@
|
||||
android:visibility="gone"
|
||||
android:clickable="true"
|
||||
android:gravity="top|start"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@*android:dimen/notification_content_margin_start"
|
||||
android:paddingEnd="8dp"
|
||||
android:background="@color/notification_guts_bg_color"
|
||||
android:theme="@*android:style/Theme.DeviceDefault.Light">
|
||||
|
||||
<!-- header -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="20dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingBottom="15dp"
|
||||
android:id="@+id/notification_guts_header">
|
||||
<TextView
|
||||
android:id="@+id/pkgname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
style="@style/TextAppearance.NotificationGuts.Secondary" />
|
||||
<TextView
|
||||
android:id="@+id/channel_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@id/pkgname"
|
||||
style="@style/TextAppearance.NotificationGuts.Header" />
|
||||
<Switch
|
||||
android:id="@+id/channel_enabled_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@null" />
|
||||
</RelativeLayout>
|
||||
<!-- Importance radio buttons -->
|
||||
<LinearLayout
|
||||
android:id="@+id/importance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<RadioGroup
|
||||
android:id="@+id/importance_buttons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="@*android:dimen/notification_content_margin_end">
|
||||
<RadioButton
|
||||
android:id="@+id/high_importance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/notification_inline_importance_height"
|
||||
style="@style/TextAppearance.NotificationGuts.Radio"
|
||||
android:buttonTint="@color/notification_guts_buttons" />
|
||||
<RadioButton
|
||||
android:id="@+id/default_importance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/notification_inline_importance_height"
|
||||
style="@style/TextAppearance.NotificationGuts.Radio"
|
||||
android:buttonTint="@color/notification_guts_buttons" />
|
||||
<RadioButton
|
||||
android:id="@+id/low_importance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/notification_inline_importance_height"
|
||||
style="@style/TextAppearance.NotificationGuts.Radio"
|
||||
android:buttonTint="@color/notification_guts_buttons" />
|
||||
<RadioButton
|
||||
android:id="@+id/min_importance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/notification_inline_importance_height"
|
||||
style="@style/TextAppearance.NotificationGuts.Radio"
|
||||
android:buttonTint="@color/notification_guts_buttons" />
|
||||
</RadioGroup>
|
||||
<LinearLayout
|
||||
android:id="@+id/importance_buttons_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<include layout="@layout/notification_guts_importance_text"/>
|
||||
<include layout="@layout/notification_guts_importance_text"/>
|
||||
<include layout="@layout/notification_guts_importance_text"/>
|
||||
<include layout="@layout/notification_guts_importance_text"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<!-- Channel Disabled Text -->
|
||||
<TextView
|
||||
android:id="@+id/channel_disabled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/notification_channel_disabled"
|
||||
style="@style/TextAppearance.NotificationGuts.Secondary" />
|
||||
<!-- Settings and Done buttons -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="8dp" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/more_settings"
|
||||
android:text="@string/notification_more_settings"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="36dp"
|
||||
style="@style/TextAppearance.NotificationGuts.Button"
|
||||
android:background="@drawable/btn_borderless_rect"
|
||||
android:gravity="center"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingStart="8dp"
|
||||
android:focusable="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/done"
|
||||
android:text="@string/notification_done"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="36dp"
|
||||
style="@style/TextAppearance.NotificationGuts.Button"
|
||||
android:background="@drawable/btn_borderless_rect"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:focusable="true"/>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.statusbar.NotificationGuts>
|
||||
android:theme="@*android:style/Theme.DeviceDefault.Light"/>
|
||||
|
||||
146
packages/SystemUI/res/layout/notification_info.xml
Normal file
146
packages/SystemUI/res/layout/notification_info.xml
Normal file
@@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2017, 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.
|
||||
-->
|
||||
|
||||
<com.android.systemui.statusbar.NotificationInfo
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/notification_guts"
|
||||
android:clickable="true"
|
||||
android:gravity="top|start"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="@*android:dimen/notification_content_margin_start"
|
||||
android:paddingEnd="8dp"
|
||||
android:background="@color/notification_guts_bg_color"
|
||||
android:theme="@*android:style/Theme.DeviceDefault.Light">
|
||||
|
||||
<!-- header -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="20dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingBottom="15dp"
|
||||
android:id="@+id/notification_guts_header">
|
||||
<TextView
|
||||
android:id="@+id/pkgname"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
style="@style/TextAppearance.NotificationGuts.Secondary" />
|
||||
<TextView
|
||||
android:id="@+id/channel_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@id/pkgname"
|
||||
style="@style/TextAppearance.NotificationGuts.Header" />
|
||||
<Switch
|
||||
android:id="@+id/channel_enabled_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@null" />
|
||||
</RelativeLayout>
|
||||
<!-- Importance radio buttons -->
|
||||
<LinearLayout
|
||||
android:id="@+id/importance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<RadioGroup
|
||||
android:id="@+id/importance_buttons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="@*android:dimen/notification_content_margin_end">
|
||||
<RadioButton
|
||||
android:id="@+id/high_importance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/notification_inline_importance_height"
|
||||
style="@style/TextAppearance.NotificationGuts.Radio"
|
||||
android:buttonTint="@color/notification_guts_buttons" />
|
||||
<RadioButton
|
||||
android:id="@+id/default_importance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/notification_inline_importance_height"
|
||||
style="@style/TextAppearance.NotificationGuts.Radio"
|
||||
android:buttonTint="@color/notification_guts_buttons" />
|
||||
<RadioButton
|
||||
android:id="@+id/low_importance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/notification_inline_importance_height"
|
||||
style="@style/TextAppearance.NotificationGuts.Radio"
|
||||
android:buttonTint="@color/notification_guts_buttons" />
|
||||
<RadioButton
|
||||
android:id="@+id/min_importance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/notification_inline_importance_height"
|
||||
style="@style/TextAppearance.NotificationGuts.Radio"
|
||||
android:buttonTint="@color/notification_guts_buttons" />
|
||||
</RadioGroup>
|
||||
<LinearLayout
|
||||
android:id="@+id/importance_buttons_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<include layout="@layout/notification_guts_importance_text"/>
|
||||
<include layout="@layout/notification_guts_importance_text"/>
|
||||
<include layout="@layout/notification_guts_importance_text"/>
|
||||
<include layout="@layout/notification_guts_importance_text"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<!-- Channel Disabled Text -->
|
||||
<TextView
|
||||
android:id="@+id/channel_disabled"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/notification_channel_disabled"
|
||||
style="@style/TextAppearance.NotificationGuts.Secondary" />
|
||||
<!-- Settings and Done buttons -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="8dp" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/more_settings"
|
||||
android:text="@string/notification_more_settings"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="36dp"
|
||||
style="@style/TextAppearance.NotificationGuts.Button"
|
||||
android:background="@drawable/btn_borderless_rect"
|
||||
android:gravity="center"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingStart="8dp"
|
||||
android:focusable="true" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/done"
|
||||
android:text="@string/notification_done"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="36dp"
|
||||
style="@style/TextAppearance.NotificationGuts.Button"
|
||||
android:background="@drawable/btn_borderless_rect"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:focusable="true"/>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.statusbar.NotificationInfo>
|
||||
@@ -101,6 +101,8 @@ import com.android.systemui.RecentsComponent;
|
||||
import com.android.systemui.SwipeHelper;
|
||||
import com.android.systemui.SystemUI;
|
||||
import com.android.systemui.assist.AssistManager;
|
||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider;
|
||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.MenuItem;
|
||||
import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.statusbar.NotificationData.Entry;
|
||||
import com.android.systemui.statusbar.notification.VisualStabilityManager;
|
||||
@@ -247,6 +249,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
|
||||
// which notification is currently being longpress-examined by the user
|
||||
private NotificationGuts mNotificationGutsExposed;
|
||||
private MenuItem mGutsMenuItem;
|
||||
|
||||
private KeyboardShortcuts mKeyboardShortcuts;
|
||||
|
||||
@@ -702,6 +705,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
|
||||
@@ -967,7 +971,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
entry.row.reInflateViews();
|
||||
if (exposedGuts) {
|
||||
mNotificationGutsExposed = entry.row.getGuts();
|
||||
bindGuts(entry.row);
|
||||
bindGuts(entry.row, mGutsMenuItem);
|
||||
}
|
||||
inflateViews(entry, mStackScroller);
|
||||
}
|
||||
@@ -1032,6 +1036,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
AsyncTask.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TaskStackBuilder.create(mContext)
|
||||
.addNextIntentWithParentStack(intent)
|
||||
@@ -1045,11 +1050,10 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}, false /* afterKeyguardGone */);
|
||||
}
|
||||
|
||||
private void bindGuts(final ExpandableNotificationRow row) {
|
||||
private void bindGuts(final ExpandableNotificationRow row, MenuItem item) {
|
||||
row.inflateGuts();
|
||||
row.setGutsView(item);
|
||||
final StatusBarNotification sbn = row.getStatusBarNotification();
|
||||
final NotificationChannel channel = row.getEntry().channel;
|
||||
PackageManager pmUser = getPackageManagerForUser(mContext, sbn.getUser().getIdentifier());
|
||||
row.setTag(sbn.getPackageName());
|
||||
final NotificationGuts guts = row.getGuts();
|
||||
guts.setClosedListener((NotificationGuts g) -> {
|
||||
@@ -1059,43 +1063,48 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
mNotificationGutsExposed = null;
|
||||
});
|
||||
|
||||
final INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
|
||||
|
||||
final String pkg = sbn.getPackageName();
|
||||
final NotificationGuts.OnSettingsClickListener onSettingsClick =
|
||||
(View v, int appUid) -> {
|
||||
MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTE_INFO);
|
||||
guts.resetFalsingCheck();
|
||||
startAppNotificationSettingsActivity(pkg, appUid);
|
||||
};
|
||||
final View.OnClickListener onDoneClick =
|
||||
(View v) -> {
|
||||
// If the user has security enabled, show challenge if the setting is changed.
|
||||
if (guts.hasImportanceChanged()
|
||||
&& isLockscreenPublicMode(sbn.getUser().getIdentifier())
|
||||
&& (mState == StatusBarState.KEYGUARD
|
||||
|| mState == StatusBarState.SHADE_LOCKED)) {
|
||||
OnDismissAction dismissAction = new OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
closeControls(row, guts, v);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
onLockedNotificationImportanceChange(dismissAction);
|
||||
} else {
|
||||
closeControls(row, guts, v);
|
||||
}
|
||||
};
|
||||
guts.bindNotification(pmUser, iNotificationManager, sbn, channel,
|
||||
onSettingsClick, onDoneClick, mNonBlockablePkgs);
|
||||
if (item.gutsContent instanceof NotificationInfo) {
|
||||
final NotificationChannel channel = row.getEntry().channel;
|
||||
PackageManager pmUser = getPackageManagerForUser(mContext,
|
||||
sbn.getUser().getIdentifier());
|
||||
final INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
|
||||
final String pkg = sbn.getPackageName();
|
||||
NotificationInfo info = (NotificationInfo) item.gutsContent;
|
||||
final NotificationInfo.OnSettingsClickListener onSettingsClick = (View v,
|
||||
int appUid) -> {
|
||||
MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTE_INFO);
|
||||
guts.resetFalsingCheck();
|
||||
startAppNotificationSettingsActivity(pkg, appUid);
|
||||
};
|
||||
final View.OnClickListener onDoneClick = (View v) -> {
|
||||
// If the user has security enabled, show challenge if the setting is changed.
|
||||
if (info.hasImportanceChanged()
|
||||
&& isLockscreenPublicMode(sbn.getUser().getIdentifier())
|
||||
&& (mState == StatusBarState.KEYGUARD
|
||||
|| mState == StatusBarState.SHADE_LOCKED)) {
|
||||
OnDismissAction dismissAction = new OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
saveAndCloseNotificationMenu(info, row, guts, v);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
onLockedNotificationImportanceChange(dismissAction);
|
||||
} else {
|
||||
saveAndCloseNotificationMenu(info, row, guts, v);
|
||||
}
|
||||
};
|
||||
info.bindNotification(pmUser, iNotificationManager, sbn, channel, onSettingsClick,
|
||||
onDoneClick,
|
||||
mNonBlockablePkgs);
|
||||
}
|
||||
}
|
||||
|
||||
private void closeControls(
|
||||
private void saveAndCloseNotificationMenu(NotificationInfo info,
|
||||
ExpandableNotificationRow row, NotificationGuts guts, View done) {
|
||||
guts.resetFalsingCheck();
|
||||
|
||||
info.saveImportance();
|
||||
int[] rowLocation = new int[2];
|
||||
int[] doneLocation = new int[2];
|
||||
row.getLocationOnScreen(rowLocation);
|
||||
@@ -1111,7 +1120,8 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
protected SwipeHelper.LongPressListener getNotificationLongClicker() {
|
||||
return new SwipeHelper.LongPressListener() {
|
||||
@Override
|
||||
public boolean onLongPress(View v, final int x, final int y) {
|
||||
public boolean onLongPress(View v, final int x, final int y,
|
||||
MenuItem item) {
|
||||
if (!(v instanceof ExpandableNotificationRow)) {
|
||||
return false;
|
||||
}
|
||||
@@ -1121,10 +1131,10 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}
|
||||
|
||||
final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
|
||||
bindGuts(row);
|
||||
bindGuts(row, item);
|
||||
NotificationGuts guts = row.getGuts();
|
||||
|
||||
// Assume we are a status_bar_notification_row
|
||||
final NotificationGuts guts = row.getGuts();
|
||||
if (guts == null) {
|
||||
// This view has no guts. Examples are the more card or the dismiss all view
|
||||
return false;
|
||||
@@ -1142,6 +1152,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
guts.setVisibility(View.INVISIBLE);
|
||||
// Post to ensure the the guts are properly laid out.
|
||||
guts.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (row.getWindowToken() == null) {
|
||||
Log.e(TAG, "Trying to show notification guts, but not attached to "
|
||||
@@ -1172,6 +1183,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
row.closeRemoteInput();
|
||||
mStackScroller.onHeightChanged(row, true /* needsAnimation */);
|
||||
mNotificationGutsExposed = guts;
|
||||
mGutsMenuItem = item;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
@@ -1483,6 +1495,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}
|
||||
|
||||
protected class H extends Handler {
|
||||
@Override
|
||||
public void handleMessage(Message m) {
|
||||
switch (m.what) {
|
||||
case MSG_SHOW_RECENT_APPS:
|
||||
@@ -1752,6 +1765,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
&& PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
|
||||
mCurrentUserId);
|
||||
dismissKeyguardThenExecute(new OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
new Thread() {
|
||||
@Override
|
||||
@@ -1802,6 +1816,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
private final class NotificationClicker implements View.OnClickListener {
|
||||
private final int[] mTmpInt2 = new int[2];
|
||||
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
if (!(v instanceof ExpandableNotificationRow)) {
|
||||
Log.e(TAG, "NotificationClicker called on a view that is not a notification row.");
|
||||
@@ -1845,6 +1860,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
&& PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
|
||||
mCurrentUserId);
|
||||
dismissKeyguardThenExecute(new OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
if (mHeadsUpManager != null && mHeadsUpManager.isHeadsUp(notificationKey)) {
|
||||
// Release the HUN notification to the shade.
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.android.internal.widget.CachingIconView;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.MenuItem;
|
||||
import com.android.systemui.statusbar.notification.HybridNotificationView;
|
||||
import com.android.systemui.statusbar.notification.VisualStabilityManager;
|
||||
import com.android.systemui.statusbar.phone.NotificationGroupManager;
|
||||
@@ -666,6 +667,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
|
||||
mHeadsUpManager = headsUpManager;
|
||||
}
|
||||
|
||||
public void setGutsView(MenuItem item) {
|
||||
if (mGuts != null) {
|
||||
item.gutsContent.setInteractionListener(mGuts);
|
||||
mGuts.setGutsContent(item.gutsContent);
|
||||
}
|
||||
}
|
||||
|
||||
public void reInflateViews() {
|
||||
initDimens();
|
||||
if (mIsSummaryWithChildren) {
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
@@ -53,6 +54,8 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider;
|
||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.GutsContent;
|
||||
import com.android.systemui.statusbar.stack.StackStateAnimator;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -60,7 +63,8 @@ import java.util.Set;
|
||||
/**
|
||||
* The guts of a notification revealed when performing a long press.
|
||||
*/
|
||||
public class NotificationGuts extends LinearLayout {
|
||||
public class NotificationGuts extends FrameLayout
|
||||
implements NotificationMenuRowProvider.GutsInteractionListener {
|
||||
private static final String TAG = "NotificationGuts";
|
||||
private static final long CLOSE_GUTS_DELAY = 8000;
|
||||
|
||||
@@ -69,24 +73,14 @@ public class NotificationGuts extends LinearLayout {
|
||||
private int mClipBottomAmount;
|
||||
private int mActualHeight;
|
||||
private boolean mExposed;
|
||||
private INotificationManager mINotificationManager;
|
||||
private int mStartingUserImportance;
|
||||
private StatusBarNotification mStatusBarNotification;
|
||||
private NotificationChannel mNotificationChannel;
|
||||
|
||||
private View mImportanceGroup;
|
||||
private View mChannelDisabled;
|
||||
private Switch mChannelEnabledSwitch;
|
||||
private RadioButton mMinImportanceButton;
|
||||
private RadioButton mLowImportanceButton;
|
||||
private RadioButton mDefaultImportanceButton;
|
||||
private RadioButton mHighImportanceButton;
|
||||
|
||||
private Handler mHandler;
|
||||
private Runnable mFalsingCheck;
|
||||
private boolean mNeedsFalsingProtection;
|
||||
private OnGutsClosedListener mListener;
|
||||
|
||||
private GutsContent mGutsContent;
|
||||
|
||||
public interface OnGutsClosedListener {
|
||||
public void onGutsClosed(NotificationGuts guts);
|
||||
}
|
||||
@@ -103,11 +97,22 @@ public class NotificationGuts extends LinearLayout {
|
||||
}
|
||||
}
|
||||
};
|
||||
final TypedArray ta =
|
||||
context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.Theme, 0, 0);
|
||||
final TypedArray ta = context.obtainStyledAttributes(attrs,
|
||||
com.android.internal.R.styleable.Theme, 0, 0);
|
||||
ta.recycle();
|
||||
}
|
||||
|
||||
public NotificationGuts(Context context) {
|
||||
this(context, null);
|
||||
|
||||
}
|
||||
|
||||
public void setGutsContent(GutsContent content) {
|
||||
mGutsContent = content;
|
||||
removeAllViews();
|
||||
addView(mGutsContent.getContentView());
|
||||
}
|
||||
|
||||
public void resetFalsingCheck() {
|
||||
mHandler.removeCallbacks(mFalsingCheck);
|
||||
if (mNeedsFalsingProtection && mExposed) {
|
||||
@@ -165,213 +170,23 @@ public class NotificationGuts extends LinearLayout {
|
||||
void onClick(View v, int appUid);
|
||||
}
|
||||
|
||||
void bindNotification(final PackageManager pm, final INotificationManager iNotificationManager,
|
||||
final StatusBarNotification sbn, final NotificationChannel channel,
|
||||
OnSettingsClickListener onSettingsClick,
|
||||
OnClickListener onDoneClick, final Set<String> nonBlockablePkgs) {
|
||||
mINotificationManager = iNotificationManager;
|
||||
mNotificationChannel = channel;
|
||||
mStatusBarNotification = sbn;
|
||||
mStartingUserImportance = channel.getImportance();
|
||||
|
||||
final String pkg = sbn.getPackageName();
|
||||
int appUid = -1;
|
||||
String appname = pkg;
|
||||
Drawable pkgicon = null;
|
||||
try {
|
||||
final ApplicationInfo info = pm.getApplicationInfo(pkg,
|
||||
PackageManager.MATCH_UNINSTALLED_PACKAGES
|
||||
| PackageManager.MATCH_DISABLED_COMPONENTS
|
||||
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
|
||||
| PackageManager.MATCH_DIRECT_BOOT_AWARE);
|
||||
if (info != null) {
|
||||
appUid = info.uid;
|
||||
appname = String.valueOf(pm.getApplicationLabel(info));
|
||||
pkgicon = pm.getApplicationIcon(info);
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// app is gone, just show package name and generic icon
|
||||
pkgicon = pm.getDefaultActivityIcon();
|
||||
}
|
||||
|
||||
// If this is the placeholder channel, don't use our channel-specific text.
|
||||
String appNameText;
|
||||
CharSequence channelNameText;
|
||||
if (channel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
|
||||
appNameText = appname;
|
||||
channelNameText = mContext.getString(R.string.notification_header_default_channel);
|
||||
} else {
|
||||
appNameText = mContext.getString(R.string.notification_importance_header_app, appname);
|
||||
channelNameText = channel.getName();
|
||||
}
|
||||
((TextView) findViewById(R.id.pkgname)).setText(appNameText);
|
||||
((TextView) findViewById(R.id.channel_name)).setText(channelNameText);
|
||||
|
||||
// Settings button.
|
||||
final TextView settingsButton = (TextView) findViewById(R.id.more_settings);
|
||||
if (appUid >= 0 && onSettingsClick != null) {
|
||||
final int appUidF = appUid;
|
||||
settingsButton.setOnClickListener(
|
||||
(View view) -> { onSettingsClick.onClick(view, appUidF); });
|
||||
settingsButton.setText(R.string.notification_more_settings);
|
||||
} else {
|
||||
settingsButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Done button.
|
||||
final TextView doneButton = (TextView) findViewById(R.id.done);
|
||||
doneButton.setText(R.string.notification_done);
|
||||
doneButton.setOnClickListener(onDoneClick);
|
||||
|
||||
boolean nonBlockable = false;
|
||||
try {
|
||||
final PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
|
||||
nonBlockable = Utils.isSystemPackage(getResources(), pm, info);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// unlikely.
|
||||
}
|
||||
if (nonBlockablePkgs != null) {
|
||||
nonBlockable |= nonBlockablePkgs.contains(pkg);
|
||||
}
|
||||
|
||||
final View importanceButtons = findViewById(R.id.importance_buttons);
|
||||
bindToggles(importanceButtons, mStartingUserImportance, nonBlockable);
|
||||
|
||||
// Importance Text (hardcoded to 4 importance levels)
|
||||
final ViewGroup importanceTextGroup =
|
||||
(ViewGroup) findViewById(R.id.importance_buttons_text);
|
||||
final int size = importanceTextGroup.getChildCount();
|
||||
for (int i = 0; i < size; i++) {
|
||||
int importanceNameResId = 0;
|
||||
int importanceDescResId = 0;
|
||||
switch (i) {
|
||||
case 0:
|
||||
importanceNameResId = R.string.high_importance;
|
||||
importanceDescResId = R.string.notification_importance_high;
|
||||
break;
|
||||
case 1:
|
||||
importanceNameResId = R.string.default_importance;
|
||||
importanceDescResId = R.string.notification_importance_default;
|
||||
break;
|
||||
case 2:
|
||||
importanceNameResId = R.string.low_importance;
|
||||
importanceDescResId = R.string.notification_importance_low;
|
||||
break;
|
||||
case 3:
|
||||
importanceNameResId = R.string.min_importance;
|
||||
importanceDescResId = R.string.notification_importance_min;
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Too many importance groups in this layout.");
|
||||
break;
|
||||
}
|
||||
final ViewGroup importanceChildGroup = (ViewGroup) importanceTextGroup.getChildAt(i);
|
||||
((TextView) importanceChildGroup.getChildAt(0)).setText(importanceNameResId);
|
||||
((TextView) importanceChildGroup.getChildAt(1)).setText(importanceDescResId);
|
||||
}
|
||||
|
||||
// Top-level importance group
|
||||
mImportanceGroup = findViewById(R.id.importance);
|
||||
mChannelDisabled = findViewById(R.id.channel_disabled);
|
||||
updateImportanceGroup();
|
||||
}
|
||||
|
||||
public boolean hasImportanceChanged() {
|
||||
return mStartingUserImportance != getSelectedImportance();
|
||||
}
|
||||
|
||||
private void saveImportance() {
|
||||
int selectedImportance = getSelectedImportance();
|
||||
if (selectedImportance == mStartingUserImportance) {
|
||||
return;
|
||||
}
|
||||
MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
|
||||
selectedImportance - mStartingUserImportance);
|
||||
mNotificationChannel.setImportance(selectedImportance);
|
||||
try {
|
||||
mINotificationManager.updateNotificationChannelForPackage(
|
||||
mStatusBarNotification.getPackageName(), mStatusBarNotification.getUid(),
|
||||
mNotificationChannel);
|
||||
} catch (RemoteException e) {
|
||||
// :(
|
||||
}
|
||||
}
|
||||
|
||||
private int getSelectedImportance() {
|
||||
if (!mChannelEnabledSwitch.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_NONE;
|
||||
} else if (mMinImportanceButton.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_MIN;
|
||||
} else if (mLowImportanceButton.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_LOW;
|
||||
} else if (mDefaultImportanceButton.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_DEFAULT;
|
||||
} else if (mHighImportanceButton.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_HIGH;
|
||||
} else {
|
||||
return NotificationManager.IMPORTANCE_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
private void bindToggles(final View importanceButtons, final int importance,
|
||||
final boolean nonBlockable) {
|
||||
// Enabled Switch
|
||||
mChannelEnabledSwitch = (Switch) findViewById(R.id.channel_enabled_switch);
|
||||
mChannelEnabledSwitch.setChecked(importance != NotificationManager.IMPORTANCE_NONE);
|
||||
mChannelEnabledSwitch.setVisibility(nonBlockable ? View.INVISIBLE : View.VISIBLE);
|
||||
|
||||
// Importance Buttons
|
||||
mMinImportanceButton = (RadioButton) importanceButtons.findViewById(R.id.min_importance);
|
||||
mLowImportanceButton = (RadioButton) importanceButtons.findViewById(R.id.low_importance);
|
||||
mDefaultImportanceButton =
|
||||
(RadioButton) importanceButtons.findViewById(R.id.default_importance);
|
||||
mHighImportanceButton = (RadioButton) importanceButtons.findViewById(R.id.high_importance);
|
||||
|
||||
// Set to current importance setting
|
||||
switch (importance) {
|
||||
case NotificationManager.IMPORTANCE_UNSPECIFIED:
|
||||
case NotificationManager.IMPORTANCE_NONE:
|
||||
break;
|
||||
case NotificationManager.IMPORTANCE_MIN:
|
||||
mMinImportanceButton.setChecked(true);
|
||||
break;
|
||||
case NotificationManager.IMPORTANCE_LOW:
|
||||
mLowImportanceButton.setChecked(true);
|
||||
break;
|
||||
case NotificationManager.IMPORTANCE_DEFAULT:
|
||||
mDefaultImportanceButton.setChecked(true);
|
||||
break;
|
||||
case NotificationManager.IMPORTANCE_HIGH:
|
||||
case NotificationManager.IMPORTANCE_MAX:
|
||||
mHighImportanceButton.setChecked(true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Callback when checked.
|
||||
mChannelEnabledSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
resetFalsingCheck();
|
||||
updateImportanceGroup();
|
||||
});
|
||||
((RadioGroup) importanceButtons).setOnCheckedChangeListener(
|
||||
(buttonView, isChecked) -> { resetFalsingCheck(); });
|
||||
}
|
||||
|
||||
private void updateImportanceGroup() {
|
||||
final boolean disabled = getSelectedImportance() == NotificationManager.IMPORTANCE_NONE;
|
||||
mImportanceGroup.setVisibility(disabled ? View.GONE : View.VISIBLE);
|
||||
mChannelDisabled.setVisibility(disabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
public void closeControls(int x, int y, boolean saveImportance) {
|
||||
if (saveImportance) {
|
||||
saveImportance();
|
||||
}
|
||||
if (getWindowToken() == null) {
|
||||
if (mListener != null) {
|
||||
mListener.onGutsClosed(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (mGutsContent == null || !mGutsContent.handleCloseControls()) {
|
||||
animateClose(x, y);
|
||||
}
|
||||
setExposed(false, mNeedsFalsingProtection);
|
||||
if (mListener != null) {
|
||||
mListener.onGutsClosed(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void animateClose(int x, int y) {
|
||||
if (x == -1 || y == -1) {
|
||||
x = (getLeft() + getRight()) / 2;
|
||||
y = (getTop() + getHeight() / 2);
|
||||
@@ -391,10 +206,6 @@ public class NotificationGuts extends LinearLayout {
|
||||
}
|
||||
});
|
||||
a.start();
|
||||
setExposed(false, mNeedsFalsingProtection);
|
||||
if (mListener != null) {
|
||||
mListener.onGutsClosed(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void setActualHeight(int actualHeight) {
|
||||
@@ -439,4 +250,14 @@ public class NotificationGuts extends LinearLayout {
|
||||
public boolean isExposed() {
|
||||
return mExposed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInteraction(View view) {
|
||||
resetFalsingCheck();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeGuts(View view) {
|
||||
closeControls(-1 /* x */, -1 /* y */, true /* notify */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,319 @@
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 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
|
||||
*/
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.app.INotificationManager;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.GutsContent;
|
||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.GutsInteractionListener;
|
||||
import com.android.systemui.statusbar.NotificationGuts.OnSettingsClickListener;
|
||||
import com.android.systemui.statusbar.stack.StackStateAnimator;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The guts of a notification revealed when performing a long press.
|
||||
*/
|
||||
public class NotificationInfo extends LinearLayout implements GutsContent {
|
||||
private static final String TAG = "InfoGuts";
|
||||
|
||||
private INotificationManager mINotificationManager;
|
||||
private int mStartingUserImportance;
|
||||
private StatusBarNotification mStatusBarNotification;
|
||||
private NotificationChannel mNotificationChannel;
|
||||
|
||||
private ImageView mAutoButton;
|
||||
private TextView mImportanceSummary;
|
||||
private TextView mImportanceTitle;
|
||||
private boolean mAuto;
|
||||
|
||||
private View mImportanceGroup;
|
||||
private View mChannelDisabled;
|
||||
private Switch mChannelEnabledSwitch;
|
||||
private RadioButton mMinImportanceButton;
|
||||
private RadioButton mLowImportanceButton;
|
||||
private RadioButton mDefaultImportanceButton;
|
||||
private RadioButton mHighImportanceButton;
|
||||
|
||||
private GutsInteractionListener mGutsInteractionListener;
|
||||
|
||||
public NotificationInfo(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
interface OnSettingsClickListener {
|
||||
void onClick(View v, int appUid);
|
||||
}
|
||||
|
||||
void bindNotification(final PackageManager pm, final INotificationManager iNotificationManager,
|
||||
final StatusBarNotification sbn, final NotificationChannel channel,
|
||||
OnSettingsClickListener onSettingsClick,
|
||||
OnClickListener onDoneClick, final Set<String> nonBlockablePkgs) {
|
||||
mINotificationManager = iNotificationManager;
|
||||
mNotificationChannel = channel;
|
||||
mStatusBarNotification = sbn;
|
||||
mStartingUserImportance = channel.getImportance();
|
||||
|
||||
final String pkg = sbn.getPackageName();
|
||||
int appUid = -1;
|
||||
String appname = pkg;
|
||||
Drawable pkgicon = null;
|
||||
try {
|
||||
final ApplicationInfo info = pm.getApplicationInfo(pkg,
|
||||
PackageManager.MATCH_UNINSTALLED_PACKAGES
|
||||
| PackageManager.MATCH_DISABLED_COMPONENTS
|
||||
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
|
||||
| PackageManager.MATCH_DIRECT_BOOT_AWARE);
|
||||
if (info != null) {
|
||||
appUid = info.uid;
|
||||
appname = String.valueOf(pm.getApplicationLabel(info));
|
||||
pkgicon = pm.getApplicationIcon(info);
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// app is gone, just show package name and generic icon
|
||||
pkgicon = pm.getDefaultActivityIcon();
|
||||
}
|
||||
|
||||
// If this is the placeholder channel, don't use our channel-specific text.
|
||||
String appNameText;
|
||||
CharSequence channelNameText;
|
||||
if (channel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
|
||||
appNameText = appname;
|
||||
channelNameText = mContext.getString(R.string.notification_header_default_channel);
|
||||
} else {
|
||||
appNameText = mContext.getString(R.string.notification_importance_header_app, appname);
|
||||
channelNameText = channel.getName();
|
||||
}
|
||||
((TextView) findViewById(R.id.pkgname)).setText(appNameText);
|
||||
((TextView) findViewById(R.id.channel_name)).setText(channelNameText);
|
||||
|
||||
// Settings button.
|
||||
final TextView settingsButton = (TextView) findViewById(R.id.more_settings);
|
||||
if (appUid >= 0 && onSettingsClick != null) {
|
||||
final int appUidF = appUid;
|
||||
settingsButton.setOnClickListener(
|
||||
(View view) -> {
|
||||
onSettingsClick.onClick(view, appUidF);
|
||||
});
|
||||
settingsButton.setText(R.string.notification_more_settings);
|
||||
} else {
|
||||
settingsButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Done button.
|
||||
final TextView doneButton = (TextView) findViewById(R.id.done);
|
||||
doneButton.setText(R.string.notification_done);
|
||||
doneButton.setOnClickListener(onDoneClick);
|
||||
|
||||
boolean nonBlockable = false;
|
||||
try {
|
||||
final PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
|
||||
nonBlockable = Utils.isSystemPackage(getResources(), pm, info);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// unlikely.
|
||||
}
|
||||
if (nonBlockablePkgs != null) {
|
||||
nonBlockable |= nonBlockablePkgs.contains(pkg);
|
||||
}
|
||||
|
||||
final View importanceButtons = findViewById(R.id.importance_buttons);
|
||||
bindToggles(importanceButtons, mStartingUserImportance, nonBlockable);
|
||||
|
||||
// Importance Text (hardcoded to 4 importance levels)
|
||||
final ViewGroup importanceTextGroup = (ViewGroup) findViewById(
|
||||
R.id.importance_buttons_text);
|
||||
final int size = importanceTextGroup.getChildCount();
|
||||
for (int i = 0; i < size; i++) {
|
||||
int importanceNameResId = 0;
|
||||
int importanceDescResId = 0;
|
||||
switch (i) {
|
||||
case 0:
|
||||
importanceNameResId = R.string.high_importance;
|
||||
importanceDescResId = R.string.notification_importance_high;
|
||||
break;
|
||||
case 1:
|
||||
importanceNameResId = R.string.default_importance;
|
||||
importanceDescResId = R.string.notification_importance_default;
|
||||
break;
|
||||
case 2:
|
||||
importanceNameResId = R.string.low_importance;
|
||||
importanceDescResId = R.string.notification_importance_low;
|
||||
break;
|
||||
case 3:
|
||||
importanceNameResId = R.string.min_importance;
|
||||
importanceDescResId = R.string.notification_importance_min;
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Too many importance groups in this layout.");
|
||||
break;
|
||||
}
|
||||
final ViewGroup importanceChildGroup = (ViewGroup) importanceTextGroup.getChildAt(i);
|
||||
((TextView) importanceChildGroup.getChildAt(0)).setText(importanceNameResId);
|
||||
((TextView) importanceChildGroup.getChildAt(1)).setText(importanceDescResId);
|
||||
}
|
||||
|
||||
// Top-level importance group
|
||||
mImportanceGroup = findViewById(R.id.importance);
|
||||
mChannelDisabled = findViewById(R.id.channel_disabled);
|
||||
updateImportanceGroup();
|
||||
}
|
||||
|
||||
public boolean hasImportanceChanged() {
|
||||
return mStartingUserImportance != getSelectedImportance();
|
||||
}
|
||||
|
||||
public void saveImportance() {
|
||||
int selectedImportance = getSelectedImportance();
|
||||
if (selectedImportance == mStartingUserImportance) {
|
||||
return;
|
||||
}
|
||||
MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
|
||||
selectedImportance - mStartingUserImportance);
|
||||
mNotificationChannel.setImportance(selectedImportance);
|
||||
try {
|
||||
mINotificationManager.updateNotificationChannelForPackage(
|
||||
mStatusBarNotification.getPackageName(), mStatusBarNotification.getUid(),
|
||||
mNotificationChannel);
|
||||
} catch (RemoteException e) {
|
||||
// :(
|
||||
}
|
||||
}
|
||||
|
||||
private int getSelectedImportance() {
|
||||
if (!mChannelEnabledSwitch.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_NONE;
|
||||
} else if (mMinImportanceButton.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_MIN;
|
||||
} else if (mLowImportanceButton.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_LOW;
|
||||
} else if (mDefaultImportanceButton.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_DEFAULT;
|
||||
} else if (mHighImportanceButton.isChecked()) {
|
||||
return NotificationManager.IMPORTANCE_HIGH;
|
||||
} else {
|
||||
return NotificationManager.IMPORTANCE_UNSPECIFIED;
|
||||
}
|
||||
}
|
||||
|
||||
private void bindToggles(final View importanceButtons, final int importance,
|
||||
final boolean nonBlockable) {
|
||||
// Enabled Switch
|
||||
mChannelEnabledSwitch = (Switch) findViewById(R.id.channel_enabled_switch);
|
||||
mChannelEnabledSwitch.setChecked(importance != NotificationManager.IMPORTANCE_NONE);
|
||||
mChannelEnabledSwitch.setVisibility(nonBlockable ? View.INVISIBLE : View.VISIBLE);
|
||||
|
||||
// Importance Buttons
|
||||
mMinImportanceButton = (RadioButton) importanceButtons.findViewById(R.id.min_importance);
|
||||
mLowImportanceButton = (RadioButton) importanceButtons.findViewById(R.id.low_importance);
|
||||
mDefaultImportanceButton = (RadioButton) importanceButtons
|
||||
.findViewById(R.id.default_importance);
|
||||
mHighImportanceButton = (RadioButton) importanceButtons.findViewById(R.id.high_importance);
|
||||
|
||||
// Set to current importance setting
|
||||
switch (importance) {
|
||||
case NotificationManager.IMPORTANCE_UNSPECIFIED:
|
||||
case NotificationManager.IMPORTANCE_NONE:
|
||||
break;
|
||||
case NotificationManager.IMPORTANCE_MIN:
|
||||
mMinImportanceButton.setChecked(true);
|
||||
break;
|
||||
case NotificationManager.IMPORTANCE_LOW:
|
||||
mLowImportanceButton.setChecked(true);
|
||||
break;
|
||||
case NotificationManager.IMPORTANCE_DEFAULT:
|
||||
mDefaultImportanceButton.setChecked(true);
|
||||
break;
|
||||
case NotificationManager.IMPORTANCE_HIGH:
|
||||
case NotificationManager.IMPORTANCE_MAX:
|
||||
mHighImportanceButton.setChecked(true);
|
||||
break;
|
||||
}
|
||||
|
||||
// Callback when checked.
|
||||
mChannelEnabledSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
mGutsInteractionListener.onInteraction(NotificationInfo.this);
|
||||
updateImportanceGroup();
|
||||
});
|
||||
((RadioGroup) importanceButtons).setOnCheckedChangeListener(
|
||||
(buttonView, isChecked) -> {
|
||||
mGutsInteractionListener.onInteraction(NotificationInfo.this);
|
||||
});
|
||||
}
|
||||
|
||||
private void updateImportanceGroup() {
|
||||
final boolean disabled = getSelectedImportance() == NotificationManager.IMPORTANCE_NONE;
|
||||
mImportanceGroup.setVisibility(disabled ? View.GONE : View.VISIBLE);
|
||||
mChannelDisabled.setVisibility(disabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
public void closeControls() {
|
||||
if (mGutsInteractionListener != null) {
|
||||
mGutsInteractionListener.closeGuts(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInteractionListener(GutsInteractionListener listener) {
|
||||
mGutsInteractionListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getContentView() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleCloseControls() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,9 @@ public class NotificationMenuRow extends FrameLayout
|
||||
public static MenuItem getSettingsMenuItem(Context context) {
|
||||
Drawable d = context.getResources().getDrawable(R.drawable.ic_settings);
|
||||
String s = context.getResources().getString(R.string.notification_menu_gear_description);
|
||||
MenuItem settings = new MenuItem(d, s);
|
||||
NotificationInfo content = (NotificationInfo) LayoutInflater.from(context).inflate(
|
||||
R.layout.notification_info, null, false);
|
||||
MenuItem settings = new MenuItem(d, s, content);
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public class NotificationGutsTest {
|
||||
private static final String TEST_CHANNEL = "test_channel";
|
||||
private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME";
|
||||
|
||||
private NotificationGuts mNotificationGuts;
|
||||
private NotificationInfo mNotificationInfo;
|
||||
private final INotificationManager mMockINotificationManager = mock(INotificationManager.class);
|
||||
private final PackageManager mMockPackageManager = mock(PackageManager.class);
|
||||
private NotificationChannel mNotificationChannel;
|
||||
@@ -76,7 +76,7 @@ public class NotificationGutsTest {
|
||||
// Inflate the layout
|
||||
final LayoutInflater layoutInflater =
|
||||
LayoutInflater.from(InstrumentationRegistry.getTargetContext());
|
||||
mNotificationGuts = (NotificationGuts) layoutInflater.inflate(R.layout.notification_guts,
|
||||
mNotificationInfo = (NotificationInfo) layoutInflater.inflate(R.layout.notification_info,
|
||||
null);
|
||||
|
||||
// PackageManager must return a packageInfo and applicationInfo.
|
||||
@@ -98,18 +98,18 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testBindNotification_SetsTextApplicationName() throws Exception {
|
||||
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
final TextView textView = (TextView) mNotificationGuts.findViewById(R.id.pkgname);
|
||||
final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.pkgname);
|
||||
assertTrue(textView.getText().toString().contains("App Name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testBindNotification_SetsTextChannelName() throws Exception {
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
final TextView textView = (TextView) mNotificationGuts.findViewById(R.id.channel_name);
|
||||
final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
|
||||
assertEquals(TEST_CHANNEL_NAME, textView.getText());
|
||||
}
|
||||
|
||||
@@ -117,12 +117,12 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel,
|
||||
(View v, int appUid) -> { latch.countDown(); }, null, null);
|
||||
|
||||
final TextView settingsButton =
|
||||
(TextView) mNotificationGuts.findViewById(R.id.more_settings);
|
||||
final TextView settingsButton =
|
||||
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
|
||||
settingsButton.performClick();
|
||||
// Verify that listener was triggered.
|
||||
assertEquals(0, latch.getCount());
|
||||
@@ -132,12 +132,12 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testBindNotification_SetsOnClickListenerForDone() throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null,
|
||||
(View v) -> { latch.countDown(); },
|
||||
null);
|
||||
|
||||
final TextView doneButton = (TextView) mNotificationGuts.findViewById(R.id.done);
|
||||
final TextView doneButton = (TextView) mNotificationInfo.findViewById(R.id.done);
|
||||
doneButton.performClick();
|
||||
// Verify that listener was triggered.
|
||||
assertEquals(0, latch.getCount());
|
||||
@@ -146,38 +146,38 @@ public class NotificationGutsTest {
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testHasImportanceChanged_DefaultsToFalse() throws Exception {
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
assertFalse(mNotificationGuts.hasImportanceChanged());
|
||||
assertFalse(mNotificationInfo.hasImportanceChanged());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testHasImportanceChanged_ReturnsTrueAfterButtonChecked() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
// Find the high button and check it.
|
||||
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
|
||||
RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
|
||||
highButton.setChecked(true);
|
||||
assertTrue(mNotificationGuts.hasImportanceChanged());
|
||||
assertTrue(mNotificationInfo.hasImportanceChanged());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testImportanceButtonCheckedBasedOnInitialImportance() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_HIGH);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
|
||||
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
|
||||
RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
|
||||
assertTrue(highButton.isChecked());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
|
||||
anyString(), anyInt(), any());
|
||||
@@ -187,10 +187,10 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
|
||||
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
|
||||
RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
|
||||
highButton.setChecked(true);
|
||||
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
|
||||
anyString(), anyInt(), any());
|
||||
@@ -199,10 +199,10 @@ public class NotificationGutsTest {
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testCloseControls_DoesNotUpdateNotificationChannelIfUnchanged() throws Exception {
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
|
||||
mNotificationGuts.closeControls(-1, -1, true);
|
||||
mNotificationInfo.closeControls();
|
||||
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
|
||||
anyString(), anyInt(), any());
|
||||
}
|
||||
@@ -211,10 +211,10 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testCloseControls_DoesNotUpdateNotificationChannelIfUnspecified() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
|
||||
mNotificationGuts.closeControls(-1, -1, true);
|
||||
mNotificationInfo.closeControls();
|
||||
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
|
||||
anyString(), anyInt(), any());
|
||||
}
|
||||
@@ -223,12 +223,12 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testCloseControls_CallsUpdateNotificationChannelIfChanged() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
|
||||
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
|
||||
RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
|
||||
highButton.setChecked(true);
|
||||
mNotificationGuts.closeControls(-1, -1, true);
|
||||
mNotificationInfo.closeControls();
|
||||
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
|
||||
eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
|
||||
assertEquals(NotificationManager.IMPORTANCE_HIGH, mNotificationChannel.getImportance());
|
||||
@@ -238,12 +238,12 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testCloseControls_DoesNotUpdateNotificationChannelIfSaveFalse() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
|
||||
RadioButton highButton = (RadioButton) mNotificationGuts.findViewById(R.id.high_importance);
|
||||
RadioButton highButton = (RadioButton) mNotificationInfo.findViewById(R.id.high_importance);
|
||||
highButton.setChecked(true);
|
||||
mNotificationGuts.closeControls(-1, -1, false);
|
||||
mNotificationInfo.closeControls();
|
||||
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
|
||||
anyString(), anyInt(), any());
|
||||
}
|
||||
@@ -252,10 +252,10 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testEnabledSwitchOnByDefault() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
|
||||
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
|
||||
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
|
||||
assertTrue(enabledSwitch.isChecked());
|
||||
}
|
||||
|
||||
@@ -263,10 +263,10 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testEnabledSwitchVisibleByDefault() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
|
||||
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
|
||||
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
|
||||
assertEquals(View.VISIBLE, enabledSwitch.getVisibility());
|
||||
}
|
||||
|
||||
@@ -274,11 +274,11 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testEnabledSwitchInvisibleIfNonBlockable() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null,
|
||||
Collections.singleton(TEST_PACKAGE_NAME));
|
||||
|
||||
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
|
||||
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
|
||||
assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
|
||||
}
|
||||
|
||||
@@ -286,13 +286,13 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testEnabledSwitchChangedCallsUpdateNotificationChannel() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null,
|
||||
Collections.singleton(TEST_PACKAGE_NAME));
|
||||
|
||||
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
|
||||
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
|
||||
enabledSwitch.setChecked(false);
|
||||
mNotificationGuts.closeControls(-1, -1, true);
|
||||
mNotificationInfo.closeControls();
|
||||
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
|
||||
eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
|
||||
}
|
||||
@@ -301,14 +301,14 @@ public class NotificationGutsTest {
|
||||
@UiThreadTest
|
||||
public void testEnabledSwitchOverridesOtherButtons() throws Exception {
|
||||
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
|
||||
mNotificationGuts.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
|
||||
mMockStatusBarNotification, mNotificationChannel, null, null, null);
|
||||
|
||||
Switch enabledSwitch = (Switch) mNotificationGuts.findViewById(R.id.channel_enabled_switch);
|
||||
RadioButton lowButton = (RadioButton) mNotificationGuts.findViewById(R.id.low_importance);
|
||||
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
|
||||
RadioButton lowButton = (RadioButton) mNotificationInfo.findViewById(R.id.low_importance);
|
||||
lowButton.setChecked(true);
|
||||
enabledSwitch.setChecked(false);
|
||||
mNotificationGuts.closeControls(-1, -1, true);
|
||||
mNotificationInfo.closeControls();
|
||||
assertEquals(NotificationManager.IMPORTANCE_NONE, mNotificationChannel.getImportance());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user