Inline Notification Controls to full spec
Based off redline spec
Support bundled notifications when long-press on summary
Hide banned text when sent from the default channel
Test: runtest systemui
Change-Id: I9315b4dc12cafbdf37ba9896879bfbe23c8d6921
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 5db5498..a9043e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -35,7 +35,6 @@
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;
@@ -59,6 +58,8 @@
import com.android.systemui.statusbar.NotificationGuts.OnSettingsClickListener;
import com.android.systemui.statusbar.stack.StackStateAnimator;
+import java.lang.IllegalArgumentException;
+import java.util.List;
import java.util.Set;
/**
@@ -68,9 +69,11 @@
private static final String TAG = "InfoGuts";
private INotificationManager mINotificationManager;
+ private String mPkg;
+ private int mAppUid;
+ private List<NotificationChannel> mNotificationChannels;
+ private NotificationChannel mSingleNotificationChannel;
private int mStartingUserImportance;
- private StatusBarNotification mStatusBarNotification;
- private NotificationChannel mNotificationChannel;
private TextView mNumChannelsView;
private View mChannelDisabledView;
@@ -83,36 +86,42 @@
}
public interface OnSettingsClickListener {
- void onClick(View v, int appUid);
+ void onClick(View v, NotificationChannel channel, int appUid);
}
public void bindNotification(final PackageManager pm,
final INotificationManager iNotificationManager,
- final StatusBarNotification sbn, final NotificationChannel channel,
+ final String pkg,
+ final List<NotificationChannel> notificationChannels,
OnSettingsClickListener onSettingsClick,
- OnClickListener onDoneClick, final Set<String> nonBlockablePkgs) {
+ OnClickListener onDoneClick, final Set<String> nonBlockablePkgs)
+ throws RemoteException {
mINotificationManager = iNotificationManager;
- mNotificationChannel = channel;
- mStatusBarNotification = sbn;
- mStartingUserImportance = channel.getImportance();
+ mPkg = pkg;
+ mNotificationChannels = notificationChannels;
+ if (mNotificationChannels.isEmpty()) {
+ throw new IllegalArgumentException("bindNotification requires at least one channel");
+ } else if (mNotificationChannels.size() == 1) {
+ mSingleNotificationChannel = mNotificationChannels.get(0);
+ mStartingUserImportance = mSingleNotificationChannel.getImportance();
+ } else {
+ mSingleNotificationChannel = null;
+ }
- final String pkg = sbn.getPackageName();
- int appUid = -1;
- String appName = pkg;
+ String appName = mPkg;
Drawable pkgicon = null;
CharSequence channelNameText = "";
ApplicationInfo info = null;
try {
- info = pm.getApplicationInfo(pkg,
+ info = pm.getApplicationInfo(mPkg,
PackageManager.MATCH_UNINSTALLED_PACKAGES
| PackageManager.MATCH_DISABLED_COMPONENTS
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_DIRECT_BOOT_AWARE);
if (info != null) {
- appUid = info.uid;
+ mAppUid = 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
@@ -121,38 +130,54 @@
((ImageView) findViewById(R.id.pkgicon)).setImageDrawable(pkgicon);
int numChannels = 1;
- try {
- numChannels = iNotificationManager.getNumNotificationChannelsForPackage(
- pkg, appUid, false /* includeDeleted */);
- } catch (RemoteException e) {
- Log.e(TAG, e.toString());
- }
+ numChannels = iNotificationManager.getNumNotificationChannelsForPackage(
+ pkg, mAppUid, false /* includeDeleted */);
+ String channelsDescText;
mNumChannelsView = (TextView) (findViewById(R.id.num_channels_desc));
- mNumChannelsView.setText(String.format(mContext.getResources().getQuantityString(
- R.plurals.notification_num_channels_desc, numChannels), numChannels));
+ switch (mNotificationChannels.size()) {
+ case 1:
+ channelsDescText = String.format(mContext.getResources().getQuantityString(
+ R.plurals.notification_num_channels_desc, numChannels), numChannels);
+ break;
+ case 2:
+ channelsDescText = mContext.getString(R.string.notification_channels_list_desc_2,
+ mNotificationChannels.get(0).getName(),
+ mNotificationChannels.get(1).getName());
+ break;
+ default:
+ final int numOthers = mNotificationChannels.size() - 2;
+ channelsDescText = String.format(
+ mContext.getResources().getQuantityString(
+ R.plurals.notification_channels_list_desc_2_and_others, numOthers),
+ mNotificationChannels.get(0).getName(),
+ mNotificationChannels.get(1).getName(),
+ numOthers);
+ }
+ mNumChannelsView.setText(channelsDescText);
- // If this is the placeholder channel, don't use our channel-specific text.
- if (channel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
+ if (mSingleNotificationChannel == null) {
+ // Multiple channels don't use a channel name for the title.
+ channelNameText = mContext.getString(R.string.notification_num_channels,
+ mNotificationChannels.size());
+ } else if (mSingleNotificationChannel.getId()
+ .equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
+ // If this is the placeholder channel, don't use our channel-specific text.
channelNameText = mContext.getString(R.string.notification_header_default_channel);
} else {
- channelNameText = channel.getName();
+ channelNameText = mSingleNotificationChannel.getName();
}
((TextView) findViewById(R.id.pkgname)).setText(appName);
((TextView) findViewById(R.id.channel_name)).setText(channelNameText);
// Set group information if this channel has an associated group.
CharSequence groupName = null;
- if (channel.getGroup() != null) {
- try {
- final NotificationChannelGroup notificationChannelGroup =
- iNotificationManager.getNotificationChannelGroupForPackage(
- channel.getGroup(), pkg, appUid);
- if (notificationChannelGroup != null) {
- groupName = notificationChannelGroup.getName();
- }
- } catch (RemoteException e) {
- Log.e(TAG, e.toString());
+ if (mSingleNotificationChannel != null && mSingleNotificationChannel.getGroup() != null) {
+ final NotificationChannelGroup notificationChannelGroup =
+ iNotificationManager.getNotificationChannelGroupForPackage(
+ mSingleNotificationChannel.getGroup(), pkg, mAppUid);
+ if (notificationChannelGroup != null) {
+ groupName = notificationChannelGroup.getName();
}
}
TextView groupNameView = ((TextView) findViewById(R.id.group_name));
@@ -181,15 +206,15 @@
// Top-level importance group
mChannelDisabledView = findViewById(R.id.channel_disabled);
- updateImportanceDisplay();
+ updateSecondaryText();
// Settings button.
final TextView settingsButton = (TextView) findViewById(R.id.more_settings);
- if (appUid >= 0 && onSettingsClick != null) {
- final int appUidF = appUid;
+ if (mAppUid >= 0 && onSettingsClick != null) {
+ final int appUidF = mAppUid;
settingsButton.setOnClickListener(
(View view) -> {
- onSettingsClick.onClick(view, appUidF);
+ onSettingsClick.onClick(view, mSingleNotificationChannel, appUidF);
});
if (numChannels > 1) {
settingsButton.setText(R.string.notification_all_categories);
@@ -208,21 +233,24 @@
}
public boolean hasImportanceChanged() {
- return mStartingUserImportance != getSelectedImportance();
+ return mSingleNotificationChannel != null &&
+ mStartingUserImportance != getSelectedImportance();
}
private void saveImportance() {
+ if (mSingleNotificationChannel == null) {
+ return;
+ }
int selectedImportance = getSelectedImportance();
if (selectedImportance == mStartingUserImportance) {
return;
}
MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
selectedImportance - mStartingUserImportance);
- mNotificationChannel.setImportance(selectedImportance);
+ mSingleNotificationChannel.setImportance(selectedImportance);
try {
mINotificationManager.updateNotificationChannelForPackage(
- mStatusBarNotification.getPackageName(), mStatusBarNotification.getUid(),
- mNotificationChannel);
+ mPkg, mAppUid, mSingleNotificationChannel);
} catch (RemoteException e) {
// :(
}
@@ -241,26 +269,32 @@
mChannelEnabledSwitch = (Switch) findViewById(R.id.channel_enabled_switch);
mChannelEnabledSwitch.setChecked(
mStartingUserImportance != NotificationManager.IMPORTANCE_NONE);
- mChannelEnabledSwitch.setVisibility(nonBlockable ? View.INVISIBLE : View.VISIBLE);
+ final boolean visible = !nonBlockable && mSingleNotificationChannel != null;
+ mChannelEnabledSwitch.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
// Callback when checked.
mChannelEnabledSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (mGutsInteractionListener != null) {
mGutsInteractionListener.onInteraction(NotificationInfo.this);
}
- updateImportanceDisplay();
+ updateSecondaryText();
});
}
- private void updateImportanceDisplay() {
- final boolean disabled = getSelectedImportance() == NotificationManager.IMPORTANCE_NONE;
- mChannelDisabledView.setVisibility(disabled ? View.VISIBLE : View.GONE);
- if (disabled) {
- // To be replaced by disabled text.
+ private void updateSecondaryText() {
+ final boolean defaultChannel = mSingleNotificationChannel != null &&
+ mSingleNotificationChannel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID);
+ final boolean disabled = mSingleNotificationChannel != null &&
+ getSelectedImportance() == NotificationManager.IMPORTANCE_NONE;
+ if (defaultChannel) {
+ // Don't show any secondary text if this is from the default channel.
+ mChannelDisabledView.setVisibility(View.GONE);
mNumChannelsView.setVisibility(View.GONE);
- } else if (mNotificationChannel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
- mNumChannelsView.setVisibility(View.INVISIBLE);
+ } else if (disabled) {
+ mChannelDisabledView.setVisibility(View.VISIBLE);
+ mNumChannelsView.setVisibility(View.GONE);
} else {
+ mChannelDisabledView.setVisibility(View.GONE);
mNumChannelsView.setVisibility(View.VISIBLE);
}
}