Loading packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +84 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.systemui.statusbar; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters; import static com.android.systemui.statusbar.notification.NotificationInflater.InflationCallback; Loading @@ -25,7 +24,10 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.annotation.Nullable; import android.app.NotificationChannel; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Path; Loading @@ -39,6 +41,7 @@ import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Log; import android.util.MathUtils; import android.util.Property; import android.view.KeyEvent; Loading Loading @@ -90,12 +93,17 @@ import java.util.List; import java.util.function.BooleanSupplier; import java.util.function.Consumer; /** * View representing a notification item - this can be either the individual child notification or * the group summary (which contains 1 or more child notifications). */ public class ExpandableNotificationRow extends ActivatableNotificationView implements PluginListener<NotificationMenuRowPlugin> { private static final int DEFAULT_DIVIDER_ALPHA = 0x29; private static final int COLORED_DIVIDER_ALPHA = 0x7B; private static final int MENU_VIEW_INDEX = 0; private static final String TAG = "ExpandableNotifRow"; public interface LayoutListener { public void onLayout(); Loading Loading @@ -166,6 +174,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private NotificationGuts mGuts; private NotificationData.Entry mEntry; private StatusBarNotification mStatusBarNotification; private PackageManager mCachedPackageManager; private PackageInfo mCachedPackageInfo; private String mAppName; private boolean mIsHeadsUp; private boolean mLastChronometerRunning = true; Loading Loading @@ -372,6 +382,53 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mEntry = entry; mStatusBarNotification = entry.notification; mNotificationInflater.inflateNotificationViews(); perhapsCachePackageInfo(); } /** * Caches the package manager and info objects which are expensive to obtain. */ private void perhapsCachePackageInfo() { if (mCachedPackageInfo == null) { mCachedPackageManager = StatusBar.getPackageManagerForUser( mContext, mStatusBarNotification.getUser().getIdentifier()); try { mCachedPackageInfo = mCachedPackageManager.getPackageInfo( mStatusBarNotification.getPackageName(), PackageManager.GET_SIGNATURES); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "perhapsCachePackageInfo: Could not find package info"); } } } /** * Returns whether this row is considered non-blockable (e.g. it's a non-blockable system notif, * covers multiple channels, or is in a whitelist). */ public boolean getIsNonblockable() { boolean isNonblockable; isNonblockable = Dependency.get(NotificationBlockingHelperManager.class) .isNonblockablePackage(mStatusBarNotification.getPackageName()); // Only bother with going through the children if the row is still blockable based on the // number of unique channels. if (!isNonblockable) { isNonblockable = getNumUniqueChannels() > 1; } // Only bother with IPC if the package is still blockable. if (!isNonblockable && mCachedPackageManager != null && mCachedPackageInfo != null) { if (com.android.settingslib.Utils.isSystemPackage( mContext.getResources(), mCachedPackageManager, mCachedPackageInfo)) { if (mEntry.channel != null && !mEntry.channel.isBlockableSystem()) { isNonblockable = true; } } } return isNonblockable; } public void onNotificationUpdated() { Loading Loading @@ -2019,6 +2076,32 @@ public class ExpandableNotificationRow extends ActivatableNotificationView updateChildrenVisibility(); applyChildrenRoundness(); } /** * Returns the number of channels covered by the notification row (including its children if * it's a summary notification). */ public int getNumUniqueChannels() { ArraySet<NotificationChannel> channels = new ArraySet<>(); channels.add(mEntry.channel); // If this is a summary, then add in the children notification channels for the // same user and pkg. if (mIsSummaryWithChildren) { final List<ExpandableNotificationRow> childrenRows = getNotificationChildren(); final int numChildren = childrenRows.size(); for (int i = 0; i < numChildren; i++) { final ExpandableNotificationRow childRow = childrenRows.get(i); final NotificationChannel childChannel = childRow.getEntry().channel; final StatusBarNotification childSbn = childRow.getStatusBarNotification(); if (childSbn.getUser().equals(mStatusBarNotification.getUser()) && childSbn.getPackageName().equals(mStatusBarNotification.getPackageName())) { channels.add(childChannel); } } } return channels.size(); } public void updateChildrenHeaderAppearance() { if (mIsSummaryWithChildren) { Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationBlockingHelperManager.java +24 −6 Original line number Diff line number Diff line Loading @@ -17,11 +17,19 @@ package com.android.systemui.statusbar; import android.content.Context; import android.content.pm.PackageManager; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.support.annotation.VisibleForTesting; import android.util.Log; import com.android.systemui.Dependency; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.phone.StatusBar; import java.util.Collections; import java.util.HashSet; import java.util.Set; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; Loading @@ -37,6 +45,7 @@ public class NotificationBlockingHelperManager { private final Context mContext; /** Row that the blocking helper will be shown in (via {@link NotificationGuts}. */ private ExpandableNotificationRow mBlockingHelperRow; private Set<String> mNonBlockablePkgs; /** * Whether the notification shade/stack is expanded - used to determine blocking helper Loading @@ -46,6 +55,9 @@ public class NotificationBlockingHelperManager { public NotificationBlockingHelperManager(Context context) { mContext = context; mNonBlockablePkgs = new HashSet<>(); Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray( com.android.internal.R.array.config_nonBlockableNotificationPackages)); } /** Loading @@ -59,15 +71,14 @@ public class NotificationBlockingHelperManager { */ boolean perhapsShowBlockingHelper( ExpandableNotificationRow row, NotificationMenuRowPlugin menuRow) { int numChildren = row.getNumberOfNotificationChildren(); // We only show the blocking helper if: // - The dismissed row is a valid group (>1 or 0 children) or the only child in the group // - User sentiment is negative (DEBUG flag can bypass) // - The notification shade is fully expanded (guarantees we're not touching a HUN). // - User sentiment is negative if (DEBUG || row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE // - The row is blockable (i.e. not non-blockable) // - The dismissed row is a valid group (>1 or 0 children) or the only child in the group if ((row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE || DEBUG) && mIsShadeExpanded && !row.getIsNonblockable() && (!row.isChildInGroup() || row.isOnlyChildInGroup())) { // Dismiss any current blocking helper before continuing forward (only one can be shown // at a given time). Loading Loading @@ -125,6 +136,13 @@ public class NotificationBlockingHelperManager { mIsShadeExpanded = expandedHeight > 0.0f; } /** * Returns whether the given package name is in the list of non-blockable packages. */ public boolean isNonblockablePackage(String packageName) { return mNonBlockablePkgs.contains(packageName); } @VisibleForTesting boolean isBlockingHelperRowNull() { return mBlockingHelperRow == null; Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java +2 −35 Original line number Diff line number Diff line Loading @@ -65,7 +65,6 @@ public class NotificationGutsManager implements Dumpable { private static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key"; private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); private final Set<String> mNonBlockablePkgs; private final Context mContext; private final AccessibilityManager mAccessibilityManager; Loading @@ -87,10 +86,6 @@ public class NotificationGutsManager implements Dumpable { mContext = context; Resources res = context.getResources(); mNonBlockablePkgs = new HashSet<>(); Collections.addAll(mNonBlockablePkgs, res.getStringArray( com.android.internal.R.array.config_nonBlockableNotificationPackages)); mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); } Loading Loading @@ -279,12 +274,12 @@ public class NotificationGutsManager implements Dumpable { iNotificationManager, packageName, row.getEntry().channel, getNumNotificationChannels(row, packageName, userHandle), row.getNumUniqueChannels(), sbn, mCheckSaveListener, onSettingsClick, onAppSettingsClick, mNonBlockablePkgs, row.getIsNonblockable(), isForBlockingHelper, row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE); } catch (RemoteException e) { Loading @@ -292,34 +287,6 @@ public class NotificationGutsManager implements Dumpable { } } /** * @return the number of channels covered by the notification row (including its children if * it's a summary notification). */ private int getNumNotificationChannels( ExpandableNotificationRow row, String packageName, UserHandle userHandle) { ArraySet<NotificationChannel> channels = new ArraySet<>(); channels.add(row.getEntry().channel); // If this is a summary, then add in the children notification channels for the // same user and pkg. if (row.isSummaryWithChildren()) { final List<ExpandableNotificationRow> childrenRows = row.getNotificationChildren(); final int numChildren = childrenRows.size(); for (int i = 0; i < numChildren; i++) { final ExpandableNotificationRow childRow = childrenRows.get(i); final NotificationChannel childChannel = childRow.getEntry().channel; final StatusBarNotification childSbn = childRow.getStatusBarNotification(); if (childSbn.getUser().equals(userHandle) && childSbn.getPackageName().equals(packageName)) { channels.add(childChannel); } } } return channels.size(); } /** * Closes guts or notification menus that might be visible and saves any changes. * Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java +8 −26 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; Loading @@ -49,13 +48,11 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; import java.util.List; import java.util.Set; /** * The guts of a notification revealed when performing a long press. Loading @@ -74,7 +71,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G private int mStartingUserImportance; private int mChosenImportance; private boolean mIsSingleDefaultChannel; private boolean mNonblockable; private boolean mIsNonblockable; private StatusBarNotification mSbn; private AnimatorSet mExpandAnimation; private boolean mIsForeground; Loading Loading @@ -128,10 +125,10 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G final CheckSaveListener checkSaveListener, final OnSettingsClickListener onSettingsClick, final OnAppSettingsClickListener onAppSettingsClick, final Set<String> nonBlockablePkgs) boolean isNonblockable) throws RemoteException { bindNotification(pm, iNotificationManager, pkg, notificationChannel, numChannels, sbn, checkSaveListener, onSettingsClick, onAppSettingsClick, nonBlockablePkgs, checkSaveListener, onSettingsClick, onAppSettingsClick, isNonblockable, false /* isBlockingHelper */, false /* isUserSentimentNegative */); } Loading @@ -146,7 +143,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G CheckSaveListener checkSaveListener, OnSettingsClickListener onSettingsClick, OnAppSettingsClickListener onAppSettingsClick, Set<String> nonBlockablePkgs, boolean isNonblockable, boolean isForBlockingHelper, boolean isUserSentimentNegative) throws RemoteException { Loading @@ -162,6 +159,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G mSingleNotificationChannel = notificationChannel; mStartingUserImportance = mChosenImportance = mSingleNotificationChannel.getImportance(); mNegativeUserSentiment = isUserSentimentNegative; mIsNonblockable = isNonblockable; mIsForeground = (mSbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0; mIsForBlockingHelper = isForBlockingHelper; Loading @@ -179,22 +177,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G && numTotalChannels == 1; } try { final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); if (Utils.isSystemPackage(getResources(), pm, pkgInfo)) { if (mSingleNotificationChannel != null && !mSingleNotificationChannel.isBlockableSystem()) { mNonblockable = true; } } } catch (PackageManager.NameNotFoundException e) { // unlikely. } if (nonBlockablePkgs != null) { mNonblockable |= nonBlockablePkgs.contains(pkg); } mNonblockable |= (mNumNotificationChannels > 1); bindHeader(); bindPrompt(); bindButtons(); Loading Loading @@ -261,7 +243,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G private void bindPrompt() { final TextView blockPrompt = findViewById(R.id.block_prompt); bindName(); if (mNonblockable) { if (mIsNonblockable) { blockPrompt.setText(R.string.notification_unblockable_desc); } else { if (mNegativeUserSentiment) { Loading @@ -288,7 +270,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G } private void saveImportance() { if (mNonblockable) { if (mIsNonblockable) { return; } MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE, Loading @@ -314,7 +296,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G keep.setOnClickListener(mOnKeepShowing); minimize.setOnClickListener(mOnStopMinNotifications); if (mNonblockable) { if (mIsNonblockable) { keep.setText(R.string.notification_done); block.setVisibility(GONE); minimize.setVisibility(GONE); Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java +24 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.statusbar; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; Loading @@ -29,6 +31,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; import android.app.NotificationChannel; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.util.ArraySet; Loading @@ -50,6 +53,7 @@ import org.mockito.Spy; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.util.List; import java.util.function.Consumer; @SmallTest Loading Loading @@ -274,4 +278,24 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { mGroupRow.setBlockingHelperShowing(false); assertFalse(mGroupRow.isBlockingHelperShowing()); } @Test public void testGetNumUniqueChildren_defaultChannel() { assertEquals(1, mGroupRow.getNumUniqueChannels()); } @Test public void testGetNumUniqueChildren_multiChannel() { List<ExpandableNotificationRow> childRows = mGroupRow.getChildrenContainer().getNotificationChildren(); // Give each child a unique channel id/name. int i = 0; for (ExpandableNotificationRow childRow : childRows) { childRow.getEntry().channel = new NotificationChannel("id" + i, "dinnertime" + i, IMPORTANCE_DEFAULT); i++; } assertEquals(3, mGroupRow.getNumUniqueChannels()); } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +84 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.systemui.statusbar; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters; import static com.android.systemui.statusbar.notification.NotificationInflater.InflationCallback; Loading @@ -25,7 +24,10 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.annotation.Nullable; import android.app.NotificationChannel; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Path; Loading @@ -39,6 +41,7 @@ import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Log; import android.util.MathUtils; import android.util.Property; import android.view.KeyEvent; Loading Loading @@ -90,12 +93,17 @@ import java.util.List; import java.util.function.BooleanSupplier; import java.util.function.Consumer; /** * View representing a notification item - this can be either the individual child notification or * the group summary (which contains 1 or more child notifications). */ public class ExpandableNotificationRow extends ActivatableNotificationView implements PluginListener<NotificationMenuRowPlugin> { private static final int DEFAULT_DIVIDER_ALPHA = 0x29; private static final int COLORED_DIVIDER_ALPHA = 0x7B; private static final int MENU_VIEW_INDEX = 0; private static final String TAG = "ExpandableNotifRow"; public interface LayoutListener { public void onLayout(); Loading Loading @@ -166,6 +174,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView private NotificationGuts mGuts; private NotificationData.Entry mEntry; private StatusBarNotification mStatusBarNotification; private PackageManager mCachedPackageManager; private PackageInfo mCachedPackageInfo; private String mAppName; private boolean mIsHeadsUp; private boolean mLastChronometerRunning = true; Loading Loading @@ -372,6 +382,53 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mEntry = entry; mStatusBarNotification = entry.notification; mNotificationInflater.inflateNotificationViews(); perhapsCachePackageInfo(); } /** * Caches the package manager and info objects which are expensive to obtain. */ private void perhapsCachePackageInfo() { if (mCachedPackageInfo == null) { mCachedPackageManager = StatusBar.getPackageManagerForUser( mContext, mStatusBarNotification.getUser().getIdentifier()); try { mCachedPackageInfo = mCachedPackageManager.getPackageInfo( mStatusBarNotification.getPackageName(), PackageManager.GET_SIGNATURES); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "perhapsCachePackageInfo: Could not find package info"); } } } /** * Returns whether this row is considered non-blockable (e.g. it's a non-blockable system notif, * covers multiple channels, or is in a whitelist). */ public boolean getIsNonblockable() { boolean isNonblockable; isNonblockable = Dependency.get(NotificationBlockingHelperManager.class) .isNonblockablePackage(mStatusBarNotification.getPackageName()); // Only bother with going through the children if the row is still blockable based on the // number of unique channels. if (!isNonblockable) { isNonblockable = getNumUniqueChannels() > 1; } // Only bother with IPC if the package is still blockable. if (!isNonblockable && mCachedPackageManager != null && mCachedPackageInfo != null) { if (com.android.settingslib.Utils.isSystemPackage( mContext.getResources(), mCachedPackageManager, mCachedPackageInfo)) { if (mEntry.channel != null && !mEntry.channel.isBlockableSystem()) { isNonblockable = true; } } } return isNonblockable; } public void onNotificationUpdated() { Loading Loading @@ -2019,6 +2076,32 @@ public class ExpandableNotificationRow extends ActivatableNotificationView updateChildrenVisibility(); applyChildrenRoundness(); } /** * Returns the number of channels covered by the notification row (including its children if * it's a summary notification). */ public int getNumUniqueChannels() { ArraySet<NotificationChannel> channels = new ArraySet<>(); channels.add(mEntry.channel); // If this is a summary, then add in the children notification channels for the // same user and pkg. if (mIsSummaryWithChildren) { final List<ExpandableNotificationRow> childrenRows = getNotificationChildren(); final int numChildren = childrenRows.size(); for (int i = 0; i < numChildren; i++) { final ExpandableNotificationRow childRow = childrenRows.get(i); final NotificationChannel childChannel = childRow.getEntry().channel; final StatusBarNotification childSbn = childRow.getStatusBarNotification(); if (childSbn.getUser().equals(mStatusBarNotification.getUser()) && childSbn.getPackageName().equals(mStatusBarNotification.getPackageName())) { channels.add(childChannel); } } } return channels.size(); } public void updateChildrenHeaderAppearance() { if (mIsSummaryWithChildren) { Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationBlockingHelperManager.java +24 −6 Original line number Diff line number Diff line Loading @@ -17,11 +17,19 @@ package com.android.systemui.statusbar; import android.content.Context; import android.content.pm.PackageManager; import android.os.UserHandle; import android.service.notification.StatusBarNotification; import android.support.annotation.VisibleForTesting; import android.util.Log; import com.android.systemui.Dependency; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.statusbar.phone.StatusBar; import java.util.Collections; import java.util.HashSet; import java.util.Set; import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE; Loading @@ -37,6 +45,7 @@ public class NotificationBlockingHelperManager { private final Context mContext; /** Row that the blocking helper will be shown in (via {@link NotificationGuts}. */ private ExpandableNotificationRow mBlockingHelperRow; private Set<String> mNonBlockablePkgs; /** * Whether the notification shade/stack is expanded - used to determine blocking helper Loading @@ -46,6 +55,9 @@ public class NotificationBlockingHelperManager { public NotificationBlockingHelperManager(Context context) { mContext = context; mNonBlockablePkgs = new HashSet<>(); Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray( com.android.internal.R.array.config_nonBlockableNotificationPackages)); } /** Loading @@ -59,15 +71,14 @@ public class NotificationBlockingHelperManager { */ boolean perhapsShowBlockingHelper( ExpandableNotificationRow row, NotificationMenuRowPlugin menuRow) { int numChildren = row.getNumberOfNotificationChildren(); // We only show the blocking helper if: // - The dismissed row is a valid group (>1 or 0 children) or the only child in the group // - User sentiment is negative (DEBUG flag can bypass) // - The notification shade is fully expanded (guarantees we're not touching a HUN). // - User sentiment is negative if (DEBUG || row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE // - The row is blockable (i.e. not non-blockable) // - The dismissed row is a valid group (>1 or 0 children) or the only child in the group if ((row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE || DEBUG) && mIsShadeExpanded && !row.getIsNonblockable() && (!row.isChildInGroup() || row.isOnlyChildInGroup())) { // Dismiss any current blocking helper before continuing forward (only one can be shown // at a given time). Loading Loading @@ -125,6 +136,13 @@ public class NotificationBlockingHelperManager { mIsShadeExpanded = expandedHeight > 0.0f; } /** * Returns whether the given package name is in the list of non-blockable packages. */ public boolean isNonblockablePackage(String packageName) { return mNonBlockablePkgs.contains(packageName); } @VisibleForTesting boolean isBlockingHelperRowNull() { return mBlockingHelperRow == null; Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java +2 −35 Original line number Diff line number Diff line Loading @@ -65,7 +65,6 @@ public class NotificationGutsManager implements Dumpable { private static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key"; private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); private final Set<String> mNonBlockablePkgs; private final Context mContext; private final AccessibilityManager mAccessibilityManager; Loading @@ -87,10 +86,6 @@ public class NotificationGutsManager implements Dumpable { mContext = context; Resources res = context.getResources(); mNonBlockablePkgs = new HashSet<>(); Collections.addAll(mNonBlockablePkgs, res.getStringArray( com.android.internal.R.array.config_nonBlockableNotificationPackages)); mAccessibilityManager = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); } Loading Loading @@ -279,12 +274,12 @@ public class NotificationGutsManager implements Dumpable { iNotificationManager, packageName, row.getEntry().channel, getNumNotificationChannels(row, packageName, userHandle), row.getNumUniqueChannels(), sbn, mCheckSaveListener, onSettingsClick, onAppSettingsClick, mNonBlockablePkgs, row.getIsNonblockable(), isForBlockingHelper, row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE); } catch (RemoteException e) { Loading @@ -292,34 +287,6 @@ public class NotificationGutsManager implements Dumpable { } } /** * @return the number of channels covered by the notification row (including its children if * it's a summary notification). */ private int getNumNotificationChannels( ExpandableNotificationRow row, String packageName, UserHandle userHandle) { ArraySet<NotificationChannel> channels = new ArraySet<>(); channels.add(row.getEntry().channel); // If this is a summary, then add in the children notification channels for the // same user and pkg. if (row.isSummaryWithChildren()) { final List<ExpandableNotificationRow> childrenRows = row.getNotificationChildren(); final int numChildren = childrenRows.size(); for (int i = 0; i < numChildren; i++) { final ExpandableNotificationRow childRow = childrenRows.get(i); final NotificationChannel childChannel = childRow.getEntry().channel; final StatusBarNotification childSbn = childRow.getStatusBarNotification(); if (childSbn.getUser().equals(userHandle) && childSbn.getPackageName().equals(packageName)) { channels.add(childChannel); } } } return channels.size(); } /** * Closes guts or notification menus that might be visible and saves any changes. * Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java +8 −26 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; Loading @@ -49,13 +48,11 @@ import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.R; import java.util.List; import java.util.Set; /** * The guts of a notification revealed when performing a long press. Loading @@ -74,7 +71,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G private int mStartingUserImportance; private int mChosenImportance; private boolean mIsSingleDefaultChannel; private boolean mNonblockable; private boolean mIsNonblockable; private StatusBarNotification mSbn; private AnimatorSet mExpandAnimation; private boolean mIsForeground; Loading Loading @@ -128,10 +125,10 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G final CheckSaveListener checkSaveListener, final OnSettingsClickListener onSettingsClick, final OnAppSettingsClickListener onAppSettingsClick, final Set<String> nonBlockablePkgs) boolean isNonblockable) throws RemoteException { bindNotification(pm, iNotificationManager, pkg, notificationChannel, numChannels, sbn, checkSaveListener, onSettingsClick, onAppSettingsClick, nonBlockablePkgs, checkSaveListener, onSettingsClick, onAppSettingsClick, isNonblockable, false /* isBlockingHelper */, false /* isUserSentimentNegative */); } Loading @@ -146,7 +143,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G CheckSaveListener checkSaveListener, OnSettingsClickListener onSettingsClick, OnAppSettingsClickListener onAppSettingsClick, Set<String> nonBlockablePkgs, boolean isNonblockable, boolean isForBlockingHelper, boolean isUserSentimentNegative) throws RemoteException { Loading @@ -162,6 +159,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G mSingleNotificationChannel = notificationChannel; mStartingUserImportance = mChosenImportance = mSingleNotificationChannel.getImportance(); mNegativeUserSentiment = isUserSentimentNegative; mIsNonblockable = isNonblockable; mIsForeground = (mSbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0; mIsForBlockingHelper = isForBlockingHelper; Loading @@ -179,22 +177,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G && numTotalChannels == 1; } try { final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES); if (Utils.isSystemPackage(getResources(), pm, pkgInfo)) { if (mSingleNotificationChannel != null && !mSingleNotificationChannel.isBlockableSystem()) { mNonblockable = true; } } } catch (PackageManager.NameNotFoundException e) { // unlikely. } if (nonBlockablePkgs != null) { mNonblockable |= nonBlockablePkgs.contains(pkg); } mNonblockable |= (mNumNotificationChannels > 1); bindHeader(); bindPrompt(); bindButtons(); Loading Loading @@ -261,7 +243,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G private void bindPrompt() { final TextView blockPrompt = findViewById(R.id.block_prompt); bindName(); if (mNonblockable) { if (mIsNonblockable) { blockPrompt.setText(R.string.notification_unblockable_desc); } else { if (mNegativeUserSentiment) { Loading @@ -288,7 +270,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G } private void saveImportance() { if (mNonblockable) { if (mIsNonblockable) { return; } MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE, Loading @@ -314,7 +296,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G keep.setOnClickListener(mOnKeepShowing); minimize.setOnClickListener(mOnStopMinNotifications); if (mNonblockable) { if (mIsNonblockable) { keep.setText(R.string.notification_done); block.setVisibility(GONE); minimize.setVisibility(GONE); Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java +24 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.systemui.statusbar; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; Loading @@ -29,6 +31,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.AppOpsManager; import android.app.NotificationChannel; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.util.ArraySet; Loading @@ -50,6 +53,7 @@ import org.mockito.Spy; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import java.util.List; import java.util.function.Consumer; @SmallTest Loading Loading @@ -274,4 +278,24 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { mGroupRow.setBlockingHelperShowing(false); assertFalse(mGroupRow.isBlockingHelperShowing()); } @Test public void testGetNumUniqueChildren_defaultChannel() { assertEquals(1, mGroupRow.getNumUniqueChannels()); } @Test public void testGetNumUniqueChildren_multiChannel() { List<ExpandableNotificationRow> childRows = mGroupRow.getChildrenContainer().getNotificationChildren(); // Give each child a unique channel id/name. int i = 0; for (ExpandableNotificationRow childRow : childRows) { childRow.getEntry().channel = new NotificationChannel("id" + i, "dinnertime" + i, IMPORTANCE_DEFAULT); i++; } assertEquals(3, mGroupRow.getNumUniqueChannels()); } }