Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41f94e58 authored by Alex Mang's avatar Alex Mang Committed by Android (Google) Code Review
Browse files

Merge changes from topic "feedback"

* changes:
  Flag guarding all notification feedback UI
  Adding automatic option in long press menu
  Adding notification guts to feedback icon
  Add notification feedback indicator icon.
parents b593816a f2a3160b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -5153,6 +5153,7 @@ public class Notification implements Parcelable
            bindProfileBadge(contentView, p);
            bindAlertedIcon(contentView, p);
            bindActivePermissions(contentView, p);
            bindFeedbackIcon(contentView, p);
            bindExpandButton(contentView, p);
            mN.mUsesStandardHeader = true;
        }
@@ -5164,6 +5165,11 @@ public class Notification implements Parcelable
            contentView.setDrawableTint(R.id.overlay, false, color, PorterDuff.Mode.SRC_ATOP);
        }

        private void bindFeedbackIcon(RemoteViews contentView, StandardTemplateParams p) {
            int color = getNeutralColor(p);
            contentView.setDrawableTint(R.id.feedback, false, color, PorterDuff.Mode.SRC_ATOP);
        }

        private void bindExpandButton(RemoteViews contentView, StandardTemplateParams p) {
            int color = isColorized(p) ? getPrimaryTextColor(p) : getSecondaryTextColor(p);
            contentView.setDrawableTint(R.id.expand_button, false, color,
+10 −0
Original line number Diff line number Diff line
@@ -8700,6 +8700,16 @@ public final class Settings {
        public static final String BUBBLE_IMPORTANT_CONVERSATIONS
                = "bubble_important_conversations";
        /**
         * When enabled, notifications the notification assistant service has modified will show an
         * indicator. When tapped, this indicator will describe the adjustment made and solicit
         * feedback. This flag will also add a "automatic" option to the long press menu.
         *
         * The value 1 - enable, 0 - disable
         * @hide
         */
        public static final String NOTIFICATION_FEEDBACK_ENABLED = "notification_feedback_enabled";
        /**
         * Whether notifications are dismissed by a right-to-left swipe (instead of a left-to-right
         * swipe).
+22 −1
Original line number Diff line number Diff line
@@ -53,12 +53,14 @@ public class NotificationHeaderView extends ViewGroup {
    private View mSecondaryHeaderText;
    private OnClickListener mExpandClickListener;
    private OnClickListener mAppOpsListener;
    private OnClickListener mFeedbackListener;
    private HeaderTouchListener mTouchListener = new HeaderTouchListener();
    private LinearLayout mTransferChip;
    private NotificationExpandButton mExpandButton;
    private CachingIconView mIcon;
    private View mProfileBadge;
    private View mAppOps;
    private View mFeedbackIcon;
    private boolean mExpanded;
    private boolean mShowExpandButtonAtEnd;
    private boolean mShowWorkBadgeAtEnd;
@@ -116,6 +118,7 @@ public class NotificationHeaderView extends ViewGroup {
        mIcon = findViewById(com.android.internal.R.id.icon);
        mProfileBadge = findViewById(com.android.internal.R.id.profile_badge);
        mAppOps = findViewById(com.android.internal.R.id.app_ops);
        mFeedbackIcon = findViewById(com.android.internal.R.id.feedback);
    }

    @Override
@@ -144,6 +147,7 @@ public class NotificationHeaderView extends ViewGroup {
            if ((child == mExpandButton && mShowExpandButtonAtEnd)
                    || child == mProfileBadge
                    || child == mAppOps
                    || child == mFeedbackIcon
                    || child == mTransferChip) {
                iconWidth += lp.leftMargin + lp.rightMargin + child.getMeasuredWidth();
            } else {
@@ -209,6 +213,7 @@ public class NotificationHeaderView extends ViewGroup {
            if ((child == mExpandButton && mShowExpandButtonAtEnd)
                    || child == mProfileBadge
                    || child == mAppOps
                    || child == mFeedbackIcon
                    || child == mTransferChip) {
                if (end == getMeasuredWidth()) {
                    layoutRight = end - mContentEndMargin;
@@ -277,7 +282,7 @@ public class NotificationHeaderView extends ViewGroup {
    }

    private void updateTouchListener() {
        if (mExpandClickListener == null && mAppOpsListener == null) {
        if (mExpandClickListener == null && mAppOpsListener == null && mFeedbackListener == null) {
            setOnTouchListener(null);
            return;
        }
@@ -293,6 +298,15 @@ public class NotificationHeaderView extends ViewGroup {
        updateTouchListener();
    }

    /**
     * Sets onclick listener for feedback icon.
     */
    public void setFeedbackOnClickListener(OnClickListener l) {
        mFeedbackListener = l;
        mFeedbackIcon.setOnClickListener(mFeedbackListener);
        updateTouchListener();
    }

    @Override
    public void setOnClickListener(@Nullable OnClickListener l) {
        mExpandClickListener = l;
@@ -381,6 +395,7 @@ public class NotificationHeaderView extends ViewGroup {
        private final ArrayList<Rect> mTouchRects = new ArrayList<>();
        private Rect mExpandButtonRect;
        private Rect mAppOpsRect;
        private Rect mFeedbackRect;
        private int mTouchSlop;
        private boolean mTrackGesture;
        private float mDownX;
@@ -394,6 +409,7 @@ public class NotificationHeaderView extends ViewGroup {
            addRectAroundView(mIcon);
            mExpandButtonRect = addRectAroundView(mExpandButton);
            mAppOpsRect = addRectAroundView(mAppOps);
            mFeedbackRect = addRectAroundView(mFeedbackIcon);
            setTouchDelegate(new TouchDelegate(mAppOpsRect, mAppOps));
            addWidthRect();
            mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
@@ -459,6 +475,11 @@ public class NotificationHeaderView extends ViewGroup {
                                || mAppOpsRect.contains((int) mDownX, (int) mDownY))) {
                            mAppOps.performClick();
                            return true;
                        } else if (mFeedbackIcon.isVisibleToUser()
                                && (mFeedbackRect.contains((int) x, (int) y))
                                || mFeedbackRect.contains((int) mDownX, (int) mDownY)) {
                            mFeedbackIcon.performClick();
                            return true;
                        }
                        mExpandButton.performClick();
                    }
+78 −8
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.RemotableViewMethod;
import android.view.TouchDelegate;
import android.view.View;
@@ -169,10 +170,13 @@ public class ConversationLayout extends FrameLayout
    private TextView mUnreadBadge;
    private ViewGroup mAppOps;
    private Rect mAppOpsTouchRect = new Rect();
    private View mFeedbackIcon;
    private float mMinTouchSize;
    private Icon mConversationIcon;
    private Icon mShortcutIcon;
    private View mAppNameDivider;
    private TouchDelegateComposite mTouchDelegate = new TouchDelegateComposite(this);
    private int mNotificationHeaderSeparatingMargin;

    public ConversationLayout(@NonNull Context context) {
        super(context);
@@ -212,6 +216,7 @@ public class ConversationLayout extends FrameLayout
        mConversationIconContainer = findViewById(R.id.conversation_icon_container);
        mIcon = findViewById(R.id.icon);
        mAppOps = findViewById(com.android.internal.R.id.app_ops);
        mFeedbackIcon = findViewById(com.android.internal.R.id.feedback);
        mMinTouchSize = 48 * getResources().getDisplayMetrics().density;
        mImportanceRingView = findViewById(R.id.conversation_icon_badge_ring);
        mConversationIconBadge = findViewById(R.id.conversation_icon_badge);
@@ -314,6 +319,8 @@ public class ConversationLayout extends FrameLayout
        mInternalButtonPadding
                = getResources().getDimensionPixelSize(R.dimen.button_padding_horizontal_material)
                + getResources().getDimensionPixelSize(R.dimen.button_inset_horizontal_material);
        mNotificationHeaderSeparatingMargin = getResources().getDimensionPixelSize(
                R.dimen.notification_header_separating_margin);
    }

    private void animateViewForceHidden(CachingIconView view, boolean forceHidden) {
@@ -1167,6 +1174,7 @@ public class ConversationLayout extends FrameLayout
                }
            });
        }
        mTouchDelegate.clear();
        if (mAppOps.getWidth() > 0) {

            // Let's increase the touch size of the app ops view if it's here
@@ -1198,16 +1206,49 @@ public class ConversationLayout extends FrameLayout
            }
            mAppOpsTouchRect.inset(0, -heightIncrease);

            // Let's adjust the hitrect since app ops isn't a direct child
            ViewGroup viewGroup = (ViewGroup) mAppOps.getParent();
            getRelativeTouchRect(mAppOpsTouchRect, mAppOps);

            // Extend the size of the app opps to be at least 48dp
            mTouchDelegate.add(new TouchDelegate(mAppOpsTouchRect, mAppOps));

        }
        if (mFeedbackIcon.getVisibility() == VISIBLE) {
            updateFeedbackIconMargins();
            float width = Math.max(mMinTouchSize, mFeedbackIcon.getWidth());
            float height = Math.max(mMinTouchSize, mFeedbackIcon.getHeight());
            final Rect feedbackTouchRect = new Rect();
            feedbackTouchRect.left = (int) ((mFeedbackIcon.getLeft() + mFeedbackIcon.getRight())
                    / 2.0f - width / 2.0f);
            feedbackTouchRect.top = (int) ((mFeedbackIcon.getTop() + mFeedbackIcon.getBottom())
                    / 2.0f - height / 2.0f);
            feedbackTouchRect.bottom = (int) (feedbackTouchRect.top + height);
            feedbackTouchRect.right = (int) (feedbackTouchRect.left + width);

            getRelativeTouchRect(feedbackTouchRect, mFeedbackIcon);
            mTouchDelegate.add(new TouchDelegate(feedbackTouchRect, mFeedbackIcon));
        }

        setTouchDelegate(mTouchDelegate);
    }

    private void getRelativeTouchRect(Rect touchRect, View view) {
        ViewGroup viewGroup = (ViewGroup) view.getParent();
        while (viewGroup != this) {
                mAppOpsTouchRect.offset(viewGroup.getLeft(), viewGroup.getTop());
            touchRect.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));
    }

    private void updateFeedbackIconMargins() {
        MarginLayoutParams lp = (MarginLayoutParams) mFeedbackIcon.getLayoutParams();
        if (mAppOps.getWidth() == 0) {
            lp.setMarginStart(mNotificationHeaderSeparatingMargin);
        } else {
            float width = Math.max(mMinTouchSize, mFeedbackIcon.getWidth());
            int horizontalMargin = (int) ((width - mFeedbackIcon.getWidth()) / 2);
            lp.setMarginStart(horizontalMargin);
        }
        mFeedbackIcon.setLayoutParams(lp);
    }

    public MessagingLinearLayout getMessagingLinearLayout() {
@@ -1354,4 +1395,33 @@ public class ConversationLayout extends FrameLayout
    public Icon getConversationIcon() {
        return mConversationIcon;
    }

    private static class TouchDelegateComposite extends TouchDelegate {
        private final ArrayList<TouchDelegate> mDelegates = new ArrayList<>();

        private TouchDelegateComposite(View view) {
            super(new Rect(), view);
        }

        public void add(TouchDelegate delegate) {
            mDelegates.add(delegate);
        }

        public void clear() {
            mDelegates.clear();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();
            for (TouchDelegate delegate: mDelegates) {
                event.setLocation(x, y);
                if (delegate.onTouchEvent(event)) {
                    return true;
                }
            }
            return false;
        }
    }
}
+24 −0
Original line number Diff line number Diff line
<!--
  ~ 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"
        android:viewportHeight="24">
    <path
        android:fillColor="@android:color/white"
        android:pathData="M15.6 0L4 13.88h8.75L10.04 24L21 10.35h-8.25z" />
</vector>
Loading