Update inline conversation controls

- Move actions to header
- Reorder items
- Fix missing icon
- Wrap header text so it won't overlap buttons
- Enable 'add to home screen'

Test: atest
Fixes: 149070309
Fixes: 148467829
Bug: 137397357
Change-Id: I6ad7702f4ffd1eeb5a48914fa6e55538a6c92be2
This commit is contained in:
Julia Reynolds
2020-02-07 14:41:02 -05:00
parent 729082ca25
commit e6fed50a1d
9 changed files with 192 additions and 305 deletions

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M4,18.99h11c0.67,0 1.27,-0.32 1.63,-0.83L21,12l-4.37,-6.16C16.27,5.33 15.67,5 15,5H4l5,7 -5,6.99z"/>
</vector>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M15,19L3,19l4.5,-7L3,5h12c0.65,0 1.26,0.31 1.63,0.84L21,12l-4.37,6.16c-0.37,0.52 -0.98,0.84 -1.63,0.84zM6.5,17L15,17l3.5,-5L15,7L6.5,7l3.5,5 -3.5,5z"/>
</vector>

View File

@@ -1,25 +0,0 @@
<!--
Copyright (C) 2020 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
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@android:color/white"
android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27z"/>
</vector>

View File

@@ -1,25 +0,0 @@
<!--
Copyright (C) 2020 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
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@android:color/white"
android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"/>
</vector>

View File

@@ -28,7 +28,7 @@
android:paddingStart="@*android:dimen/notification_content_margin_start">
<!-- Package Info -->
<RelativeLayout
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_guts_conversation_header_height"
@@ -41,16 +41,20 @@
android:layout_height="@dimen/notification_guts_conversation_icon_size"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:layout_marginEnd="6dp" />
android:layout_marginEnd="15dp" />
<LinearLayout
android:id="@+id/names"
android:layout_weight="1"
android:layout_width="0dp"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="@dimen/notification_guts_conversation_icon_size"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_toEndOf="@id/conversation_icon">
android:layout_alignEnd="@id/conversation_icon"
android:layout_toEndOf="@id/conversation_icon"
android:layout_alignStart="@id/mute">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -107,67 +111,40 @@
android:layout_weight="1"
style="@style/TextAppearance.NotificationImportanceChannel"/>
</LinearLayout>
<TextView
android:id="@+id/delegate_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
style="@style/TextAppearance.NotificationImportanceHeader"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:ellipsize="end"
android:text="@string/notification_delegate_header"
android:layout_toEndOf="@id/pkg_divider"
android:maxLines="1" />
</LinearLayout>
<TextView
android:id="@+id/pkg_divider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
style="@style/TextAppearance.NotificationImportanceHeader"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:layout_toEndOf="@id/name"
android:text="@*android:string/notification_header_divider_symbol" />
<TextView
android:id="@+id/delegate_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
style="@style/TextAppearance.NotificationImportanceHeader"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:ellipsize="end"
android:text="@string/notification_delegate_header"
android:layout_toEndOf="@id/pkg_divider"
android:maxLines="1" />
<!-- end aligned fields -->
<ImageButton
android:id="@+id/demote"
android:id="@+id/mute"
android:layout_width="@dimen/notification_importance_toggle_size"
android:layout_height="@dimen/notification_importance_toggle_size"
android:layout_centerVertical="true"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/demote"
android:src="@drawable/ic_demote_conversation"
android:layout_toStartOf="@id/app_settings"
android:tint="@color/notification_guts_link_icon_tint"/>
<!-- Optional link to app. Only appears if the channel is not disabled and the app
asked for it -->
<ImageButton
android:id="@+id/app_settings"
android:layout_width="@dimen/notification_importance_toggle_size"
android:layout_height="@dimen/notification_importance_toggle_size"
android:layout_centerVertical="true"
android:visibility="gone"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/notification_app_settings"
android:src="@drawable/ic_info"
android:layout_toStartOf="@id/info"
android:layout_toStartOf="@id/fave"
android:tint="@color/notification_guts_link_icon_tint"/>
<ImageButton
android:id="@+id/info"
android:id="@+id/fave"
android:layout_width="@dimen/notification_importance_toggle_size"
android:layout_height="@dimen/notification_importance_toggle_size"
android:layout_centerVertical="true"
android:background="@drawable/ripple_drawable"
android:contentDescription="@string/notification_more_settings"
android:src="@drawable/ic_settings"
android:layout_alignParentEnd="true"
android:tint="@color/notification_guts_link_icon_tint"/>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/actions"
@@ -182,6 +159,23 @@ asked for it -->
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/GM2_grey_300" />
<Button
android:id="@+id/snooze"
android:layout_height="@dimen/notification_guts_conversation_action_height"
android:layout_width="match_parent"
style="?android:attr/borderlessButtonStyle"
android:text="@string/notification_menu_snooze_action"
android:gravity="left|center_vertical"
android:drawableStart="@drawable/ic_snooze"
android:drawablePadding="@dimen/notification_guts_conversation_action_text_padding_start"
android:drawableTint="@color/notification_guts_link_icon_tint"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/GM2_grey_300" />
<Button
android:id="@+id/bubble"
android:layout_height="@dimen/notification_guts_conversation_action_height"
@@ -212,42 +206,15 @@ asked for it -->
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/GM2_grey_300" />
<Button
android:id="@+id/fave"
android:layout_height="@dimen/notification_guts_conversation_action_height"
android:layout_width="match_parent"
style="?android:attr/borderlessButtonStyle"
android:gravity="left|center_vertical"
android:drawablePadding="@dimen/notification_guts_conversation_action_text_padding_start"
android:drawableTint="@color/notification_guts_link_icon_tint"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/GM2_grey_300" />
<Button
android:id="@+id/snooze"
android:id="@+id/info"
android:layout_height="@dimen/notification_guts_conversation_action_height"
android:layout_width="match_parent"
style="?android:attr/borderlessButtonStyle"
android:text="@string/notification_menu_snooze_action"
android:drawableStart="@drawable/ic_settings"
android:text="@string/notification_menu_settings_action"
android:gravity="left|center_vertical"
android:drawableStart="@drawable/ic_snooze"
android:drawablePadding="@dimen/notification_guts_conversation_action_text_padding_start"
android:drawableTint="@color/notification_guts_link_icon_tint"/>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="@color/GM2_grey_300" />
<Button
android:id="@+id/mute"
android:layout_height="@dimen/notification_guts_conversation_action_height"
android:layout_width="match_parent"
style="?android:attr/borderlessButtonStyle"
android:text="@string/notification_conversation_mute"
android:gravity="left|center_vertical"
android:drawableStart="@drawable/ic_notifications_silence"
android:drawablePadding="@dimen/notification_guts_conversation_action_text_padding_start"
android:drawableTint="@color/notification_guts_link_icon_tint"/>

View File

@@ -1829,23 +1829,23 @@
<!-- Notification: Conversation: control panel, label for button that demotes notification from conversation to normal notification -->
<string name="demote">Mark this notification as not a conversation</string>
<!-- [CHAR LIMIT=100] Mark this conversation as a favorite -->
<string name="notification_conversation_favorite">Mark as important</string>
<!-- [CHAR LIMIT=100] This conversation is marked as important -->
<string name="notification_conversation_favorite">Important conversation</string>
<!-- [CHAR LIMIT=100] Unmark this conversation as a favorite -->
<string name="notification_conversation_unfavorite">Mark as unimportant</string>
<!-- [CHAR LIMIT=100] This conversation is not marked as important -->
<string name="notification_conversation_unfavorite">Not an important conversation</string>
<!-- [CHAR LIMIT=100] Mute this conversation -->
<string name="notification_conversation_mute">Silence</string>
<!-- [CHAR LIMIT=100] This conversation is silenced (will not make sound or vibrate)-->
<string name="notification_conversation_mute">Silenced</string>
<!-- [CHAR LIMIT=100] Umute this conversation -->
<!-- [CHAR LIMIT=100] This conversation is alerting (may make sound and/or vibrate)-->
<string name="notification_conversation_unmute">Alerting</string>
<!-- [CHAR LIMIT=100] Show notification as bubble -->
<string name="notification_conversation_bubble">Show as bubble</string>
<string name="notification_conversation_bubble">Show bubble</string>
<!-- [CHAR LIMIT=100] Turn off bubbles for notification -->
<string name="notification_conversation_unbubble">Turn off bubbles</string>
<string name="notification_conversation_unbubble">Remove bubbles</string>
<!-- [CHAR LIMIT=100] Add this conversation to home screen -->
<string name="notification_conversation_home_screen">Add to home screen</string>
@@ -1860,7 +1860,10 @@
<string name="notification_menu_snooze_description">notification snooze options</string>
<!-- Notification: Menu row: Label for the snooze action shown in local context menu. [CHAR LIMIT=NONE] -->
<string name="notification_menu_snooze_action">Snooze</string>
<string name="notification_menu_snooze_action">Remind me</string>
<!-- Notification: Menu row: Label for the snooze action shown in local context menu. [CHAR LIMIT=NONE] -->
<string name="notification_menu_settings_action">Settings</string>
<!-- Notification: Snooze panel: Snooze undo button label. [CHAR LIMIT=50]-->
<string name="snooze_undo">UNDO</string>

View File

@@ -23,14 +23,6 @@ import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED;
import static com.android.systemui.statusbar.notification.row.NotificationConversationInfo.UpdateChannelRunnable.ACTION_BUBBLE;
import static com.android.systemui.statusbar.notification.row.NotificationConversationInfo.UpdateChannelRunnable.ACTION_DEMOTE;
import static com.android.systemui.statusbar.notification.row.NotificationConversationInfo.UpdateChannelRunnable.ACTION_FAVORITE;
import static com.android.systemui.statusbar.notification.row.NotificationConversationInfo.UpdateChannelRunnable.ACTION_HOME;
import static com.android.systemui.statusbar.notification.row.NotificationConversationInfo.UpdateChannelRunnable.ACTION_MUTE;
import static com.android.systemui.statusbar.notification.row.NotificationConversationInfo.UpdateChannelRunnable.ACTION_SNOOZE;
import static com.android.systemui.statusbar.notification.row.NotificationConversationInfo.UpdateChannelRunnable.ACTION_UNBUBBLE;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
@@ -69,11 +61,13 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.phone.ShadeController;
import java.lang.annotation.Retention;
import java.util.Arrays;
@@ -92,6 +86,7 @@ public class NotificationConversationInfo extends LinearLayout implements
ShortcutManager mShortcutManager;
private PackageManager mPm;
private VisualStabilityManager mVisualStabilityManager;
private ShadeController mShadeController;
private String mPackageName;
private String mAppName;
@@ -103,24 +98,30 @@ public class NotificationConversationInfo extends LinearLayout implements
private NotificationEntry mEntry;
private StatusBarNotification mSbn;
private boolean mIsDeviceProvisioned;
private int mStartingChannelImportance;
private boolean mStartedAsBubble;
private boolean mIsBubbleable;
// TODO: remove when launcher api works
@VisibleForTesting
boolean mShowHomeScreen = false;
private @UpdateChannelRunnable.Action int mSelectedAction = -1;
private @Action int mSelectedAction = -1;
private OnSnoozeClickListener mOnSnoozeClickListener;
private OnSettingsClickListener mOnSettingsClickListener;
private OnAppSettingsClickListener mAppSettingsClickListener;
private NotificationGuts mGutsContainer;
private BubbleController mBubbleController;
@VisibleForTesting
boolean mSkipPost = false;
@Retention(SOURCE)
@IntDef({ACTION_BUBBLE, ACTION_HOME, ACTION_FAVORITE, ACTION_SNOOZE, ACTION_MUTE})
private @interface Action {}
static final int ACTION_BUBBLE = 0;
static final int ACTION_HOME = 1;
static final int ACTION_FAVORITE = 2;
static final int ACTION_SNOOZE = 3;
static final int ACTION_MUTE = 4;
static final int ACTION_SETTINGS = 5;
static final int ACTION_UNBUBBLE = 6;
private OnClickListener mOnBubbleClick = v -> {
mSelectedAction = mStartedAsBubble ? ACTION_UNBUBBLE : ACTION_BUBBLE;
if (mStartedAsBubble) {
@@ -136,12 +137,14 @@ public class NotificationConversationInfo extends LinearLayout implements
private OnClickListener mOnHomeClick = v -> {
mSelectedAction = ACTION_HOME;
mShortcutManager.requestPinShortcut(mShortcutInfo, null);
mShadeController.animateCollapsePanels();
closeControls(v, true);
};
private OnClickListener mOnFavoriteClick = v -> {
mSelectedAction = ACTION_FAVORITE;
closeControls(v, true);
updateChannel();
};
private OnClickListener mOnSnoozeClick = v -> {
@@ -151,13 +154,8 @@ public class NotificationConversationInfo extends LinearLayout implements
};
private OnClickListener mOnMuteClick = v -> {
mSelectedAction = ACTION_MUTE;
closeControls(v, true);
};
private OnClickListener mOnDemoteClick = v -> {
mSelectedAction = ACTION_DEMOTE;
closeControls(v, true);
mSelectedAction = ACTION_MUTE;
updateChannel();
};
public NotificationConversationInfo(Context context, AttributeSet attrs) {
@@ -197,15 +195,14 @@ public class NotificationConversationInfo extends LinearLayout implements
mEntry = entry;
mSbn = entry.getSbn();
mPm = pm;
mAppSettingsClickListener = onAppSettingsClick;
mAppName = mPackageName;
mOnSettingsClickListener = onSettingsClick;
mNotificationChannel = notificationChannel;
mStartingChannelImportance = mNotificationChannel.getImportance();
mAppUid = mSbn.getUid();
mDelegatePkg = mSbn.getOpPkg();
mIsDeviceProvisioned = isDeviceProvisioned;
mOnSnoozeClickListener = onSnoozeClickListener;
mShadeController = Dependency.get(ShadeController.class);
mShortcutManager = shortcutManager;
mLauncherApps = launcherApps;
@@ -251,9 +248,6 @@ public class NotificationConversationInfo extends LinearLayout implements
mNotificationChannel = mINotificationManager.getConversationNotificationChannel(
mContext.getOpPackageName(), UserHandle.getUserId(mAppUid), mPackageName,
mNotificationChannel.getId(), false, mConversationId);
// TODO: ask LA to pin the shortcut once api exists for pinning one shortcut at a
// time
} catch (RemoteException e) {
Slog.e(TAG, "Could not create conversation channel", e);
}
@@ -274,40 +268,24 @@ public class NotificationConversationInfo extends LinearLayout implements
Button home = findViewById(R.id.home);
home.setOnClickListener(mOnHomeClick);
home.setVisibility(mShowHomeScreen && mShortcutInfo != null
home.setVisibility(mShortcutInfo != null
&& mShortcutManager.isRequestPinShortcutSupported()
? VISIBLE : GONE);
Button favorite = findViewById(R.id.fave);
View favorite = findViewById(R.id.fave);
favorite.setOnClickListener(mOnFavoriteClick);
if (mNotificationChannel.isImportantConversation()) {
favorite.setText(R.string.notification_conversation_unfavorite);
favorite.setCompoundDrawablesRelative(
mContext.getDrawable(R.drawable.ic_star), null, null, null);
} else {
favorite.setText(R.string.notification_conversation_favorite);
favorite.setCompoundDrawablesRelative(
mContext.getDrawable(R.drawable.ic_star_border), null, null, null);
}
Button snooze = findViewById(R.id.snooze);
snooze.setOnClickListener(mOnSnoozeClick);
Button mute = findViewById(R.id.mute);
View mute = findViewById(R.id.mute);
mute.setOnClickListener(mOnMuteClick);
if (mStartingChannelImportance >= IMPORTANCE_DEFAULT
|| mStartingChannelImportance == IMPORTANCE_UNSPECIFIED) {
mute.setText(R.string.notification_conversation_mute);
favorite.setCompoundDrawablesRelative(
mContext.getDrawable(R.drawable.ic_notifications_silence), null, null, null);
} else {
mute.setText(R.string.notification_conversation_unmute);
favorite.setCompoundDrawablesRelative(
mContext.getDrawable(R.drawable.ic_notifications_alert), null, null, null);
}
ImageButton demote = findViewById(R.id.demote);
demote.setOnClickListener(mOnDemoteClick);
final View settingsButton = findViewById(R.id.info);
settingsButton.setOnClickListener(getSettingsOnClickListener());
settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);
updateToggleActions();
}
private void bindHeader() {
@@ -315,26 +293,6 @@ public class NotificationConversationInfo extends LinearLayout implements
// Delegate
bindDelegate();
// Set up app settings link (i.e. Customize)
View settingsLinkView = findViewById(R.id.app_settings);
Intent settingsIntent = getAppSettingsIntent(mPm, mPackageName,
mNotificationChannel,
mSbn.getId(), mSbn.getTag());
if (settingsIntent != null
&& !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
settingsLinkView.setVisibility(VISIBLE);
settingsLinkView.setOnClickListener((View view) -> {
mAppSettingsClickListener.onClick(view, settingsIntent);
});
} else {
settingsLinkView.setVisibility(View.GONE);
}
// System Settings button.
final View settingsButton = findViewById(R.id.info);
settingsButton.setOnClickListener(getSettingsOnClickListener());
settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);
}
private OnClickListener getSettingsOnClickListener() {
@@ -424,15 +382,12 @@ public class NotificationConversationInfo extends LinearLayout implements
private void bindDelegate() {
TextView delegateView = findViewById(R.id.delegate_name);
TextView dividerView = findViewById(R.id.pkg_divider);
if (!TextUtils.equals(mPackageName, mDelegatePkg)) {
// this notification was posted by a delegate!
delegateView.setVisibility(View.VISIBLE);
dividerView.setVisibility(View.VISIBLE);
} else {
delegateView.setVisibility(View.GONE);
dividerView.setVisibility(View.GONE);
}
}
@@ -492,26 +447,37 @@ public class NotificationConversationInfo extends LinearLayout implements
}
}
private Intent getAppSettingsIntent(PackageManager pm, String packageName,
NotificationChannel channel, int id, String tag) {
Intent intent = new Intent(Intent.ACTION_MAIN)
.addCategory(Notification.INTENT_CATEGORY_NOTIFICATION_PREFERENCES)
.setPackage(packageName);
final List<ResolveInfo> resolveInfos = pm.queryIntentActivities(
intent,
PackageManager.MATCH_DEFAULT_ONLY
);
if (resolveInfos == null || resolveInfos.size() == 0 || resolveInfos.get(0) == null) {
return null;
private void updateToggleActions() {
ImageButton favorite = findViewById(R.id.fave);
if (mNotificationChannel.isImportantConversation()) {
favorite.setContentDescription(
mContext.getString(R.string.notification_conversation_favorite));
favorite.setImageResource(R.drawable.ic_important);
} else {
favorite.setContentDescription(
mContext.getString(R.string.notification_conversation_unfavorite));
favorite.setImageResource(R.drawable.ic_important_outline);
}
final ActivityInfo activityInfo = resolveInfos.get(0).activityInfo;
intent.setClassName(activityInfo.packageName, activityInfo.name);
if (channel != null) {
intent.putExtra(Notification.EXTRA_CHANNEL_ID, channel.getId());
ImageButton mute = findViewById(R.id.mute);
if (mNotificationChannel.getImportance() >= IMPORTANCE_DEFAULT
|| mNotificationChannel.getImportance() == IMPORTANCE_UNSPECIFIED) {
mute.setContentDescription(
mContext.getString(R.string.notification_conversation_unmute));
mute.setImageResource(R.drawable.ic_notifications_alert);
} else {
mute.setContentDescription(
mContext.getString(R.string.notification_conversation_mute));
mute.setImageResource(R.drawable.ic_notifications_silence);
}
intent.putExtra(Notification.EXTRA_NOTIFICATION_ID, id);
intent.putExtra(Notification.EXTRA_NOTIFICATION_TAG, tag);
return intent;
}
private void updateChannel() {
Handler bgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
bgHandler.post(
new UpdateChannelRunnable(mINotificationManager, mPackageName,
mAppUid, mSelectedAction, mNotificationChannel));
mVisualStabilityManager.temporarilyAllowReordering();
}
/**
@@ -556,11 +522,7 @@ public class NotificationConversationInfo extends LinearLayout implements
@Override
public boolean handleCloseControls(boolean save, boolean force) {
if (save && mSelectedAction > -1) {
Handler bgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
bgHandler.post(
new UpdateChannelRunnable(mINotificationManager, mPackageName,
mAppUid, mSelectedAction, mNotificationChannel));
mVisualStabilityManager.temporarilyAllowReordering();
updateChannel();
}
return false;
}
@@ -575,19 +537,7 @@ public class NotificationConversationInfo extends LinearLayout implements
return false;
}
static class UpdateChannelRunnable implements Runnable {
@Retention(SOURCE)
@IntDef({ACTION_BUBBLE, ACTION_HOME, ACTION_FAVORITE, ACTION_SNOOZE, ACTION_MUTE,
ACTION_DEMOTE})
private @interface Action {}
static final int ACTION_BUBBLE = 0;
static final int ACTION_HOME = 1;
static final int ACTION_FAVORITE = 2;
static final int ACTION_SNOOZE = 3;
static final int ACTION_MUTE = 4;
static final int ACTION_DEMOTE = 5;
static final int ACTION_UNBUBBLE = 6;
class UpdateChannelRunnable implements Runnable {
private final INotificationManager mINotificationManager;
private final String mAppPkg;
@@ -633,10 +583,6 @@ public class NotificationConversationInfo extends LinearLayout implements
mChannelToUpdate.getOriginalImportance(), IMPORTANCE_DEFAULT));
}
break;
case ACTION_DEMOTE:
mChannelToUpdate.setDemoted(!mChannelToUpdate.isDemoted());
break;
}
if (channelSettingChanged) {
@@ -646,13 +592,7 @@ public class NotificationConversationInfo extends LinearLayout implements
} catch (RemoteException e) {
Log.e(TAG, "Unable to update notification channel", e);
}
ThreadUtils.postOnMainThread(() -> updateToggleActions());
}
}
@Retention(SOURCE)
@IntDef({BEHAVIOR_ALERTING, BEHAVIOR_SILENT, BEHAVIOR_BUBBLE})
private @interface AlertingBehavior {}
private static final int BEHAVIOR_ALERTING = 0;
private static final int BEHAVIOR_SILENT = 1;
private static final int BEHAVIOR_BUBBLE = 2;
}

View File

@@ -58,6 +58,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -384,6 +385,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
guts.resetFalsingCheck();
mOnSettingsClickListener.onSettingsClick(sbn.getKey());
startAppNotificationSettingsActivity(packageName, appUid, channel, row);
notificationInfoView.closeControls(v, false);
};
}

View File

@@ -75,6 +75,7 @@ import com.android.systemui.statusbar.SbnBuilder;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.phone.ShadeController;
import org.junit.Before;
import org.junit.Rule;
@@ -131,6 +132,8 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
private ShortcutManager mShortcutManager;
@Mock
private NotificationGuts mNotificationGuts;
@Mock
private ShadeController mShadeController;
@Before
public void setUp() throws Exception {
@@ -139,12 +142,12 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
mDependency.injectTestDependency(BubbleController.class, mBubbleController);
mDependency.injectTestDependency(ShadeController.class, mShadeController);
// Inflate the layout
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
mNotificationInfo = (NotificationConversationInfo) layoutInflater.inflate(
R.layout.notification_conversation_info,
null);
mNotificationInfo.mShowHomeScreen = true;
mNotificationInfo.setGutsParent(mNotificationGuts);
doAnswer((Answer<Object>) invocation -> {
mNotificationInfo.handleCloseControls(true, false);
@@ -173,7 +176,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
when(mShortcutInfo.getShortLabel()).thenReturn("Convo name");
List<ShortcutInfo> shortcuts = Arrays.asList(mShortcutInfo);
when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
mImage = mContext.getDrawable(R.drawable.ic_star);
mImage = mContext.getDrawable(R.drawable.ic_remove);
when(mLauncherApps.getShortcutBadgedIconDrawable(eq(mShortcutInfo),
anyInt())).thenReturn(mImage);
@@ -333,8 +336,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
true);
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
assertEquals(GONE, nameView.getVisibility());
final TextView dividerView = mNotificationInfo.findViewById(R.id.pkg_divider);
assertEquals(GONE, dividerView.getVisibility());
}
@Test
@@ -364,8 +365,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
final TextView nameView = mNotificationInfo.findViewById(R.id.delegate_name);
assertEquals(VISIBLE, nameView.getVisibility());
assertTrue(nameView.getText().toString().contains("Proxied"));
final TextView dividerView = mNotificationInfo.findViewById(R.id.pkg_divider);
assertEquals(VISIBLE, dividerView.getVisibility());
}
@Test
@@ -502,6 +501,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
verify(mShortcutManager, times(1)).requestPinShortcut(mShortcutInfo, null);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
verify(mShadeController).animateCollapsePanels();
}
@Test
@@ -644,9 +644,9 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
true);
Button fave = mNotificationInfo.findViewById(R.id.fave);
assertEquals(mContext.getString(R.string.notification_conversation_favorite),
fave.getText().toString());
ImageButton fave = mNotificationInfo.findViewById(R.id.fave);
assertEquals(mContext.getString(R.string.notification_conversation_unfavorite),
fave.getContentDescription().toString());
fave.performClick();
mTestableLooper.processAllMessages();
@@ -677,9 +677,9 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
true);
Button fave = mNotificationInfo.findViewById(R.id.fave);
assertEquals(mContext.getString(R.string.notification_conversation_unfavorite),
fave.getText().toString());
ImageButton fave = mNotificationInfo.findViewById(R.id.fave);
assertEquals(mContext.getString(R.string.notification_conversation_favorite),
fave.getContentDescription().toString());
fave.performClick();
mTestableLooper.processAllMessages();
@@ -691,34 +691,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
assertFalse(captor.getValue().isImportantConversation());
}
@Test
public void testDemote() throws Exception {
mNotificationInfo.bindNotification(
mShortcutManager,
mLauncherApps,
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
null,
null,
null,
true);
ImageButton demote = mNotificationInfo.findViewById(R.id.demote);
demote.performClick();
mTestableLooper.processAllMessages();
ArgumentCaptor<NotificationChannel> captor =
ArgumentCaptor.forClass(NotificationChannel.class);
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
anyString(), anyInt(), captor.capture());
assertTrue(captor.getValue().isDemoted());
}
@Test
public void testMute_mute() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
@@ -738,9 +710,9 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
true);
Button mute = mNotificationInfo.findViewById(R.id.mute);
assertEquals(mContext.getString(R.string.notification_conversation_mute),
mute.getText().toString());
ImageButton mute = mNotificationInfo.findViewById(R.id.mute);
assertEquals(mContext.getString(R.string.notification_conversation_unmute),
mute.getContentDescription().toString());
mute.performClick();
mTestableLooper.processAllMessages();
@@ -774,9 +746,9 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
true);
Button mute = mNotificationInfo.findViewById(R.id.mute);
assertEquals(mContext.getString(R.string.notification_conversation_unmute),
mute.getText().toString());
ImageButton mute = mNotificationInfo.findViewById(R.id.mute);
assertEquals(mContext.getString(R.string.notification_conversation_mute),
mute.getContentDescription().toString());
mute.performClick();
mTestableLooper.processAllMessages();