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:
26
packages/SystemUI/res/drawable/ic_important.xml
Normal file
26
packages/SystemUI/res/drawable/ic_important.xml
Normal 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>
|
||||
27
packages/SystemUI/res/drawable/ic_important_outline.xml
Normal file
27
packages/SystemUI/res/drawable/ic_important_outline.xml
Normal 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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"/>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user