diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java index 279b60ff99cd3..6f15a0ffd98ad 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/NotificationMenuRowProvider.java @@ -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) { diff --git a/packages/SystemUI/res/layout/notification_guts.xml b/packages/SystemUI/res/layout/notification_guts.xml index 3948dc4b87711..9d8ef83ab7e6b 100644 --- a/packages/SystemUI/res/layout/notification_guts.xml +++ b/packages/SystemUI/res/layout/notification_guts.xml @@ -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"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:theme="@*android:style/Theme.DeviceDefault.Light"/> diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml new file mode 100644 index 0000000000000..9770eccfd2c16 --- /dev/null +++ b/packages/SystemUI/res/layout/notification_info.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index d9298ed6be275..d4499df73e3cb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -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. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 3f88ff97337cb..bd1563070f6fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java index 83104e685e22c..f6056ddab0937 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java @@ -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 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 */); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java new file mode 100644 index 0000000000000..098984639a998 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java @@ -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 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; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java index e728d10235447..b4ed16a7a2b22 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java @@ -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; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java index cac0806e0f153..166fcb1e8a6a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsTest.java @@ -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()); } }