Merge "Merge changes Ia152bc41,Iae8026e7 into rvc-dev am: 71a6d0bf2b am: 9716d62b4d" into rvc-d1-dev-plus-aosp am: aa5088485c

Change-Id: I6adeeba172df639f7ba8958d13b0225c861ffcd0
This commit is contained in:
Automerger Merge Worker
2020-04-01 21:12:21 +00:00
10 changed files with 224 additions and 64 deletions

View File

@@ -60,11 +60,7 @@ public class NotificationHeaderView extends ViewGroup {
private NotificationExpandButton mExpandButton;
private CachingIconView mIcon;
private View mProfileBadge;
private View mOverlayIcon;
private View mCameraIcon;
private View mMicIcon;
private View mAppOps;
private View mAudiblyAlertedIcon;
private boolean mExpanded;
private boolean mShowExpandButtonAtEnd;
private boolean mShowWorkBadgeAtEnd;
@@ -121,11 +117,7 @@ public class NotificationHeaderView extends ViewGroup {
mExpandButton = findViewById(com.android.internal.R.id.expand_button);
mIcon = findViewById(com.android.internal.R.id.icon);
mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
mCameraIcon = findViewById(com.android.internal.R.id.camera);
mMicIcon = findViewById(com.android.internal.R.id.mic);
mOverlayIcon = findViewById(com.android.internal.R.id.overlay);
mAppOps = findViewById(com.android.internal.R.id.app_ops);
mAudiblyAlertedIcon = findViewById(com.android.internal.R.id.alerted_icon);
}
@Override
@@ -300,10 +292,6 @@ public class NotificationHeaderView extends ViewGroup {
*/
public void setAppOpsOnClickListener(OnClickListener l) {
mAppOpsListener = l;
mAppOps.setOnClickListener(mAppOpsListener);
mCameraIcon.setOnClickListener(mAppOpsListener);
mMicIcon.setOnClickListener(mAppOpsListener);
mOverlayIcon.setOnClickListener(mAppOpsListener);
updateTouchListener();
}
@@ -328,27 +316,6 @@ public class NotificationHeaderView extends ViewGroup {
updateExpandButton();
}
/**
* Shows or hides 'app op in use' icons based on app usage.
*/
public void showAppOpsIcons(ArraySet<Integer> appOps) {
if (mOverlayIcon == null || mCameraIcon == null || mMicIcon == null || appOps == null) {
return;
}
mOverlayIcon.setVisibility(appOps.contains(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
? View.VISIBLE : View.GONE);
mCameraIcon.setVisibility(appOps.contains(AppOpsManager.OP_CAMERA)
? View.VISIBLE : View.GONE);
mMicIcon.setVisibility(appOps.contains(AppOpsManager.OP_RECORD_AUDIO)
? View.VISIBLE : View.GONE);
}
/** Updates icon visibility based on the noisiness of the notification. */
public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
mAudiblyAlertedIcon.setVisibility(audiblyAlerted ? View.VISIBLE : View.GONE);
}
private void updateExpandButton() {
int drawableId;
int contentDescriptionId;

View File

@@ -45,6 +45,7 @@ import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.RemotableViewMethod;
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
@@ -153,6 +154,9 @@ public class ConversationLayout extends FrameLayout
private int mFacePileProtectionWidthExpanded;
private boolean mImportantConversation;
private TextView mUnreadBadge;
private ViewGroup mAppOps;
private Rect mAppOpsTouchRect = new Rect();
private float mMinTouchSize;
public ConversationLayout(@NonNull Context context) {
super(context);
@@ -191,6 +195,8 @@ public class ConversationLayout extends FrameLayout
mConversationIcon = findViewById(R.id.conversation_icon);
mConversationIconContainer = findViewById(R.id.conversation_icon_container);
mIcon = findViewById(R.id.icon);
mAppOps = findViewById(com.android.internal.R.id.app_ops);
mMinTouchSize = 48 * getResources().getDisplayMetrics().density;
mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring);
mConversationIconBadge = findViewById(R.id.conversation_icon_badge);
mConversationIconBadgeBg = findViewById(R.id.conversation_icon_badge_bg);
@@ -871,6 +877,7 @@ public class ConversationLayout extends FrameLayout
@RemotableViewMethod
public void setSenderTextColor(int color) {
mSenderTextColor = color;
mConversationText.setTextColor(color);
}
/**
@@ -1071,6 +1078,47 @@ public class ConversationLayout extends FrameLayout
}
});
}
if (mAppOps.getWidth() > 0) {
// Let's increase the touch size of the app ops view if it's here
mAppOpsTouchRect.set(
mAppOps.getLeft(),
mAppOps.getTop(),
mAppOps.getRight(),
mAppOps.getBottom());
for (int i = 0; i < mAppOps.getChildCount(); i++) {
View child = mAppOps.getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
// Make sure each child has at least a minTouchSize touch target around it
float childTouchLeft = child.getLeft() + child.getWidth() / 2.0f
- mMinTouchSize / 2.0f;
float childTouchRight = childTouchLeft + mMinTouchSize;
mAppOpsTouchRect.left = (int) Math.min(mAppOpsTouchRect.left,
mAppOps.getLeft() + childTouchLeft);
mAppOpsTouchRect.right = (int) Math.max(mAppOpsTouchRect.right,
mAppOps.getLeft() + childTouchRight);
}
// Increase the height
int heightIncrease = 0;
if (mAppOpsTouchRect.height() < mMinTouchSize) {
heightIncrease = (int) Math.ceil((mMinTouchSize - mAppOpsTouchRect.height())
/ 2.0f);
}
mAppOpsTouchRect.inset(0, -heightIncrease);
// Let's adjust the hitrect since app ops isn't a direct child
ViewGroup viewGroup = (ViewGroup) mAppOps.getParent();
while (viewGroup != this) {
mAppOpsTouchRect.offset(viewGroup.getLeft(), viewGroup.getTop());
viewGroup = (ViewGroup) viewGroup.getParent();
}
//
// Extend the size of the app opps to be at least 48dp
setTouchDelegate(new TouchDelegate(mAppOpsTouchRect, mAppOps));
}
}
public MessagingLinearLayout getMessagingLinearLayout() {

View File

@@ -136,6 +136,7 @@
android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
android:textSize="16sp"
android:singleLine="true"
android:layout_weight="1"
/>
<TextView
@@ -165,6 +166,18 @@
android:visibility="gone"
/>
<ImageView
android:id="@+id/alerted_icon"
android:layout_width="@dimen/notification_alerted_size"
android:layout_height="@dimen/notification_alerted_size"
android:layout_gravity="center"
android:layout_marginStart="4dp"
android:paddingTop="2dp"
android:scaleType="fitCenter"
android:visibility="gone"
android:contentDescription="@string/notification_alerted_content_description"
android:src="@drawable/ic_notifications_alerted"/>
<ImageView
android:id="@+id/profile_badge"
android:layout_width="@dimen/notification_badge_size"
@@ -176,6 +189,44 @@
android:visibility="gone"
android:contentDescription="@string/notification_work_profile_content_description"
/>
<LinearLayout
android:id="@+id/app_ops"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingTop="3dp"
android:layout_marginStart="2dp"
android:orientation="horizontal" >
<ImageButton
android:layout_marginStart="4dp"
android:id="@+id/camera"
android:layout_width="?attr/notificationHeaderIconSize"
android:layout_height="?attr/notificationHeaderIconSize"
android:src="@drawable/ic_camera"
android:background="?android:selectableItemBackgroundBorderless"
android:visibility="gone"
android:contentDescription="@string/notification_appops_camera_active"
/>
<ImageButton
android:id="@+id/mic"
android:layout_width="?attr/notificationHeaderIconSize"
android:layout_height="?attr/notificationHeaderIconSize"
android:src="@drawable/ic_mic"
android:background="?android:selectableItemBackgroundBorderless"
android:layout_marginStart="4dp"
android:visibility="gone"
android:contentDescription="@string/notification_appops_microphone_active"
/>
<ImageButton
android:id="@+id/overlay"
android:layout_width="?attr/notificationHeaderIconSize"
android:layout_height="?attr/notificationHeaderIconSize"
android:src="@drawable/ic_alert_window_layer"
android:background="?android:selectableItemBackgroundBorderless"
android:layout_marginStart="4dp"
android:visibility="gone"
android:contentDescription="@string/notification_appops_overlay_active"
/>
</LinearLayout>
</LinearLayout>
<!-- App Name -->

View File

@@ -1669,8 +1669,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
public void showAppOpsIcons(ArraySet<Integer> activeOps) {
if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() != null) {
mChildrenContainer.getHeaderView().showAppOpsIcons(activeOps);
if (mIsSummaryWithChildren) {
mChildrenContainer.showAppOpsIcons(activeOps);
}
mPrivateLayout.showAppOpsIcons(activeOps);
mPublicLayout.showAppOpsIcons(activeOps);
@@ -1697,8 +1697,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private final Runnable mExpireRecentlyAlertedFlag = () -> applyAudiblyAlertedRecently(false);
private void applyAudiblyAlertedRecently(boolean audiblyAlertedRecently) {
if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() != null) {
mChildrenContainer.getHeaderView().setRecentlyAudiblyAlerted(audiblyAlertedRecently);
if (mIsSummaryWithChildren) {
mChildrenContainer.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
}
mPrivateLayout.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
mPublicLayout.setRecentlyAudiblyAlerted(audiblyAlertedRecently);

View File

@@ -1468,27 +1468,27 @@ public class NotificationContentView extends FrameLayout {
}
public void showAppOpsIcons(ArraySet<Integer> activeOps) {
if (mContractedChild != null && mContractedWrapper.getNotificationHeader() != null) {
mContractedWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
if (mContractedChild != null) {
mContractedWrapper.showAppOpsIcons(activeOps);
}
if (mExpandedChild != null && mExpandedWrapper.getNotificationHeader() != null) {
mExpandedWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
if (mExpandedChild != null) {
mExpandedWrapper.showAppOpsIcons(activeOps);
}
if (mHeadsUpChild != null && mHeadsUpWrapper.getNotificationHeader() != null) {
mHeadsUpWrapper.getNotificationHeader().showAppOpsIcons(activeOps);
if (mHeadsUpChild != null) {
mHeadsUpWrapper.showAppOpsIcons(activeOps);
}
}
/** Sets whether the notification being displayed audibly alerted the user. */
public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
if (mContractedChild != null && mContractedWrapper.getNotificationHeader() != null) {
mContractedWrapper.getNotificationHeader().setRecentlyAudiblyAlerted(audiblyAlerted);
if (mContractedChild != null) {
mContractedWrapper.setRecentlyAudiblyAlerted(audiblyAlerted);
}
if (mExpandedChild != null && mExpandedWrapper.getNotificationHeader() != null) {
mExpandedWrapper.getNotificationHeader().setRecentlyAudiblyAlerted(audiblyAlerted);
if (mExpandedChild != null) {
mExpandedWrapper.setRecentlyAudiblyAlerted(audiblyAlerted);
}
if (mHeadsUpChild != null && mHeadsUpWrapper.getNotificationHeader() != null) {
mHeadsUpWrapper.getNotificationHeader().setRecentlyAudiblyAlerted(audiblyAlerted);
if (mHeadsUpChild != null) {
mHeadsUpWrapper.setRecentlyAudiblyAlerted(audiblyAlerted);
}
}

View File

@@ -18,6 +18,8 @@ package com.android.systemui.statusbar.notification.row.wrapper;
import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
import android.annotation.NonNull;
import android.app.AppOpsManager;
import android.app.Notification;
import android.content.Context;
import android.util.ArraySet;
@@ -60,6 +62,11 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
protected NotificationHeaderView mNotificationHeader;
private TextView mHeaderText;
private ImageView mWorkProfileImage;
private View mCameraIcon;
private View mMicIcon;
private View mOverlayIcon;
private View mAppOps;
private View mAudiblyAlertedIcon;
private boolean mIsLowPriority;
private boolean mTransformLowPriorityTitle;
@@ -107,6 +114,11 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
mCameraIcon = mView.findViewById(com.android.internal.R.id.camera);
mMicIcon = mView.findViewById(com.android.internal.R.id.mic);
mOverlayIcon = mView.findViewById(com.android.internal.R.id.overlay);
mAppOps = mView.findViewById(com.android.internal.R.id.app_ops);
mAudiblyAlertedIcon = mView.findViewById(com.android.internal.R.id.alerted_icon);
if (mNotificationHeader != null) {
mNotificationHeader.setShowExpandButtonAtEnd(mShowExpandButtonAtEnd);
mColor = mNotificationHeader.getOriginalIconColor();
@@ -114,8 +126,35 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
}
private void addAppOpsOnClickListener(ExpandableNotificationRow row) {
View.OnClickListener listener = row.getAppOpsOnClickListener();
if (mNotificationHeader != null) {
mNotificationHeader.setAppOpsOnClickListener(row.getAppOpsOnClickListener());
mNotificationHeader.setAppOpsOnClickListener(listener);
}
mAppOps.setOnClickListener(listener);
mCameraIcon.setOnClickListener(listener);
mMicIcon.setOnClickListener(listener);
mOverlayIcon.setOnClickListener(listener);
}
/**
* Shows or hides 'app op in use' icons based on app usage.
*/
@Override
public void showAppOpsIcons(ArraySet<Integer> appOps) {
if (appOps == null) {
return;
}
if (mOverlayIcon != null) {
mOverlayIcon.setVisibility(appOps.contains(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
? View.VISIBLE : View.GONE);
}
if (mCameraIcon != null) {
mCameraIcon.setVisibility(appOps.contains(AppOpsManager.OP_CAMERA)
? View.VISIBLE : View.GONE);
}
if (mMicIcon != null) {
mMicIcon.setVisibility(appOps.contains(AppOpsManager.OP_RECORD_AUDIO)
? View.VISIBLE : View.GONE);
}
}
@@ -184,6 +223,18 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE,
mHeaderText);
}
if (mCameraIcon != null) {
mTransformationHelper.addViewTransformingToSimilar(mCameraIcon);
}
if (mMicIcon != null) {
mTransformationHelper.addViewTransformingToSimilar(mMicIcon);
}
if (mOverlayIcon != null) {
mTransformationHelper.addViewTransformingToSimilar(mOverlayIcon);
}
if (mAudiblyAlertedIcon != null) {
mTransformationHelper.addViewTransformingToSimilar(mAudiblyAlertedIcon);
}
}
@Override
@@ -194,6 +245,13 @@ public class NotificationHeaderViewWrapper extends NotificationViewWrapper {
}
}
@Override
public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
if (mAudiblyAlertedIcon != null) {
mAudiblyAlertedIcon.setVisibility(audiblyAlerted ? View.VISIBLE : View.GONE);
}
}
@Override
public NotificationHeaderView getNotificationHeader() {
return mNotificationHeader;

View File

@@ -29,6 +29,7 @@ import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.ArraySet;
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewGroup;
@@ -95,6 +96,14 @@ public abstract class NotificationViewWrapper implements TransformableView {
public void onContentUpdated(ExpandableNotificationRow row) {
}
/**
* Show a set of app opp icons in the layout.
*
* @param appOps which app ops to show
*/
public void showAppOpsIcons(ArraySet<Integer> appOps) {
}
public void onReinflated() {
if (shouldClearBackgroundOnReapply()) {
mBackgroundColor = 0;
@@ -362,4 +371,10 @@ public abstract class NotificationViewWrapper implements TransformableView {
public int getExtraMeasureHeight() {
return 0;
}
/**
* Set the view to have recently visibly alerted.
*/
public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
}
}

View File

@@ -22,6 +22,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.NotificationHeaderView;
@@ -1265,4 +1266,27 @@ public class NotificationChildrenContainer extends ViewGroup {
mHeaderVisibleAmount = headerVisibleAmount;
mCurrentHeaderTranslation = (int) ((1.0f - headerVisibleAmount) * mTranslationForHeader);
}
/**
* Show a set of app opp icons in the layout.
*
* @param appOps which app ops to show
*/
public void showAppOpsIcons(ArraySet<Integer> appOps) {
if (mNotificationHeaderWrapper != null) {
mNotificationHeaderWrapper.showAppOpsIcons(appOps);
}
if (mNotificationHeaderWrapperLowPriority != null) {
mNotificationHeaderWrapperLowPriority.showAppOpsIcons(appOps);
}
}
public void setRecentlyAudiblyAlerted(boolean audiblyAlertedRecently) {
if (mNotificationHeaderWrapper != null) {
mNotificationHeaderWrapper.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
}
if (mNotificationHeaderWrapperLowPriority != null) {
mNotificationHeaderWrapperLowPriority.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
}
}
}

View File

@@ -229,22 +229,19 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
@Test
public void testShowAppOpsIcons_header() {
NotificationHeaderView mockHeader = mock(NotificationHeaderView.class);
NotificationContentView publicLayout = mock(NotificationContentView.class);
mGroupRow.setPublicLayout(publicLayout);
NotificationContentView privateLayout = mock(NotificationContentView.class);
mGroupRow.setPrivateLayout(privateLayout);
NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
when(mockContainer.getNotificationChildCount()).thenReturn(1);
when(mockContainer.getHeaderView()).thenReturn(mockHeader);
mGroupRow.setChildrenContainer(mockContainer);
ArraySet<Integer> ops = new ArraySet<>();
ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
mGroupRow.showAppOpsIcons(ops);
verify(mockHeader, times(1)).showAppOpsIcons(ops);
verify(mockContainer, times(1)).showAppOpsIcons(ops);
verify(privateLayout, times(1)).showAppOpsIcons(ops);
verify(publicLayout, times(1)).showAppOpsIcons(ops);

View File

@@ -76,14 +76,14 @@ public class NotificationContentViewTest extends SysuiTestCase {
@Test
@UiThreadTest
public void testShowAppOpsIcons() {
NotificationHeaderView mockContracted = mock(NotificationHeaderView.class);
when(mockContracted.findViewById(com.android.internal.R.id.notification_header))
View mockContracted = mock(View.class);
when(mockContracted.findViewById(com.android.internal.R.id.mic))
.thenReturn(mockContracted);
NotificationHeaderView mockExpanded = mock(NotificationHeaderView.class);
when(mockExpanded.findViewById(com.android.internal.R.id.notification_header))
View mockExpanded = mock(View.class);
when(mockExpanded.findViewById(com.android.internal.R.id.mic))
.thenReturn(mockExpanded);
NotificationHeaderView mockHeadsUp = mock(NotificationHeaderView.class);
when(mockHeadsUp.findViewById(com.android.internal.R.id.notification_header))
View mockHeadsUp = mock(View.class);
when(mockHeadsUp.findViewById(com.android.internal.R.id.mic))
.thenReturn(mockHeadsUp);
mView.setContractedChild(mockContracted);
@@ -91,11 +91,11 @@ public class NotificationContentViewTest extends SysuiTestCase {
mView.setHeadsUpChild(mockHeadsUp);
ArraySet<Integer> ops = new ArraySet<>();
ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
ops.add(AppOpsManager.OP_RECORD_AUDIO);
mView.showAppOpsIcons(ops);
verify(mockContracted, times(1)).showAppOpsIcons(ops);
verify(mockExpanded, times(1)).showAppOpsIcons(ops);
verify(mockHeadsUp, times(1)).showAppOpsIcons(any());
verify(mockContracted, times(1)).setVisibility(View.VISIBLE);
verify(mockExpanded, times(1)).setVisibility(View.VISIBLE);
verify(mockHeadsUp, times(1)).setVisibility(View.VISIBLE);
}
}