diff options
13 files changed, 203 insertions, 19 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 4587f2899e16..df9b64cb7b86 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -2742,6 +2742,11 @@ public class Notification implements Parcelable private int mBackgroundColor = COLOR_INVALID; private int mForegroundColor = COLOR_INVALID; private int mBackgroundColorHint = COLOR_INVALID; + /** + * A temporary location where actions are stored. If != null the view originally has action + * but doesn't have any for this inflation. + */ + private ArrayList<Action> mOriginalActions; private boolean mRebuildStyledRemoteViews; /** @@ -4054,7 +4059,53 @@ public class Notification implements Parcelable contentView.setViewLayoutMarginEndDimen(R.id.line1, endMargin); contentView.setViewLayoutMarginEndDimen(R.id.text, endMargin); contentView.setViewLayoutMarginEndDimen(R.id.progress, endMargin); + // Bind the reply action + Action action = findReplyAction(); + contentView.setViewVisibility(R.id.reply_icon_action, action != null + ? View.VISIBLE + : View.GONE); + + if (action != null) { + int contrastColor = resolveContrastColor(); + contentView.setDrawableParameters(R.id.reply_icon_action, + true /* targetBackground */, + -1, + contrastColor, + PorterDuff.Mode.SRC_ATOP, -1); + int iconColor = NotificationColorUtil.isColorLight(contrastColor) + ? Color.BLACK : Color.WHITE; + contentView.setDrawableParameters(R.id.reply_icon_action, + false /* targetBackground */, + -1, + iconColor, + PorterDuff.Mode.SRC_ATOP, -1); + contentView.setOnClickPendingIntent(R.id.right_icon, + action.actionIntent); + contentView.setOnClickPendingIntent(R.id.reply_icon_action, + action.actionIntent); + contentView.setRemoteInputs(R.id.right_icon, action.mRemoteInputs); + contentView.setRemoteInputs(R.id.reply_icon_action, action.mRemoteInputs); + + } } + contentView.setViewVisibility(R.id.right_icon_container, mN.mLargeIcon != null + ? View.VISIBLE + : View.GONE); + } + + private Action findReplyAction() { + ArrayList<Action> actions = mActions; + if (mOriginalActions != null) { + actions = mOriginalActions; + } + int numActions = actions.size(); + for (int i = 0; i < numActions; i++) { + Action action = actions.get(i); + if (hasValidRemoteInput(action)) { + return action; + } + } + return null; } private void bindNotificationHeader(RemoteViews contentView, boolean ambient) { @@ -5604,10 +5655,11 @@ public class Notification implements Parcelable @Override public RemoteViews makeContentView(boolean increasedHeight) { if (increasedHeight) { - ArrayList<Action> actions = mBuilder.mActions; + mBuilder.mOriginalActions = mBuilder.mActions; mBuilder.mActions = new ArrayList<>(); RemoteViews remoteViews = makeBigContentView(); - mBuilder.mActions = actions; + mBuilder.mActions = mBuilder.mOriginalActions; + mBuilder.mOriginalActions = null; return remoteViews; } return super.makeContentView(increasedHeight); @@ -5891,10 +5943,11 @@ public class Notification implements Parcelable return mBuilder.applyStandardTemplate(mBuilder.getBaseLayoutResource(), mBuilder.mParams.reset().hasProgress(false).title(title).text(text)); } else { - ArrayList<Action> actions = mBuilder.mActions; + mBuilder.mOriginalActions = mBuilder.mActions; mBuilder.mActions = new ArrayList<>(); RemoteViews remoteViews = makeBigContentView(); - mBuilder.mActions = actions; + mBuilder.mActions = mBuilder.mOriginalActions; + mBuilder.mOriginalActions = null; return remoteViews; } } diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 985584e7d7ab..49e1d4486cf8 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -2191,7 +2191,7 @@ public class RemoteViews implements Parcelable, Filter { @Override public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { - final TextView target = (TextView) root.findViewById(viewId); + final View target = root.findViewById(viewId); if (target == null) return; target.setTagInternal(R.id.remote_input_tag, remoteInputs); diff --git a/core/res/res/drawable/ic_reply_notification.xml b/core/res/res/drawable/ic_reply_notification.xml new file mode 100644 index 000000000000..88b8c5b7ddef --- /dev/null +++ b/core/res/res/drawable/ic_reply_notification.xml @@ -0,0 +1,27 @@ +<!-- + ~ Copyright (C) 2017 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="10dp" + android:height="10dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FFFFFFFF" + android:pathData="M10.0,9.0L10.0,5.0l-7.0,7.0 7.0,7.0l0.0,-4.1c5.0,0.0 8.5,1.6 11.0,5.1 -1.0,-5.0 -4.0,-10.0 -11.0,-11.0z"/> + <path + android:pathData="M0 0h24v24H0z" + android:fillColor="#00000000"/> +</vector> diff --git a/core/res/res/drawable/notification_reply_background.xml b/core/res/res/drawable/notification_reply_background.xml new file mode 100644 index 000000000000..08e22f2f9729 --- /dev/null +++ b/core/res/res/drawable/notification_reply_background.xml @@ -0,0 +1,24 @@ +<!-- + ~ Copyright (C) 2017 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 + --> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="oval"> + <solid + android:color="#ff757575"/> + <size + android:width="16dp" + android:height="16dp"/> +</shape> diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml index 65a5015f8094..aa4e05b15d19 100644 --- a/core/res/res/layout/notification_template_right_icon.xml +++ b/core/res/res/layout/notification_template_right_icon.xml @@ -15,13 +15,27 @@ ~ limitations under the License --> -<ImageView android:id="@+id/right_icon" xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="40dp" - android:layout_height="40dp" - android:layout_marginEnd="@dimen/notification_content_margin_end" - android:layout_marginTop="36dp" - android:layout_gravity="top|end" - android:scaleType="centerCrop" - /> - +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/right_icon_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="top|end"> + <ImageView android:id="@+id/right_icon" + android:layout_width="40dp" + android:layout_height="40dp" + android:layout_gravity="top|end" + android:layout_marginTop="36dp" + android:layout_marginEnd="@dimen/notification_content_margin_end" + android:scaleType="centerCrop"/> + <ImageView android:id="@+id/reply_icon_action" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_gravity="top|end" + android:layout_marginTop="64dp" + android:layout_marginEnd="12dp" + android:background="@drawable/notification_reply_background" + android:src="@drawable/ic_reply_notification" + android:scaleType="center" + visiblity="gone"/> +</FrameLayout> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index d56c3ee104d9..80b72fa46605 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2942,6 +2942,8 @@ <java-symbol type="string" name="config_defaultTrustAgent" /> <!-- Time picker --> + <java-symbol type="id" name="right_icon_container"/> + <java-symbol type="id" name="reply_icon_action"/> <java-symbol type="id" name="toggle_mode"/> <java-symbol type="id" name="input_mode"/> <java-symbol type="id" name="input_header"/> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 4a5f83f6b1ed..7f2f5f62add6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -1487,6 +1487,10 @@ public class ExpandableNotificationRow extends ActivatableNotificationView mHasUserChangedExpansion = true; mUserExpanded = userExpanded; onExpansionChanged(true /* userAction */, wasExpanded); + if (!wasExpanded && isExpanded() + && getActualHeight() != getIntrinsicHeight()) { + notifyHeightChanged(true /* needsAnimation */); + } } public void resetUserExpansion() { @@ -2097,8 +2101,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView float x = event.getX(); float y = event.getY(); NotificationHeaderView header = getVisibleNotificationHeader(); - if (header != null) { - return header.isInTouchRect(x - getTranslation(), y); + if (header != null && header.isInTouchRect(x - getTranslation(), y)) { + return true; + } + if ((!mIsSummaryWithChildren || mShowingPublic) + && getShowingLayout().disallowSingleClick(x, y)) { + return true; } return super.disallowSingleClick(event); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index baf0c2cce2e0..15f3908f735b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -1440,4 +1440,15 @@ public class NotificationContentView extends FrameLayout { } return true; } + + /** + * Should a single click be disallowed on this view when on the keyguard? + */ + public boolean disallowSingleClick(float x, float y) { + NotificationViewWrapper visibleWrapper = getVisibleWrapper(getVisibleType()); + if (visibleWrapper != null) { + return visibleWrapper.disallowSingleClick(x, y); + } + return false; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java index e6b3fb86abe4..c891418a5b29 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageTransformState.java @@ -48,10 +48,13 @@ public class ImageTransformState extends TransformState { @Override protected boolean sameAs(TransformState otherState) { + if (super.sameAs(otherState)) { + return true; + } if (otherState instanceof ImageTransformState) { return mIcon != null && mIcon.sameAs(((ImageTransformState) otherState).getIcon()); } - return super.sameAs(otherState); + return false; } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java index f0b6b2e89e9f..f5f92c81df54 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification; import android.content.Context; import android.graphics.Color; +import android.graphics.Rect; import android.service.notification.StatusBarNotification; import android.view.View; import android.widget.ImageView; @@ -41,6 +42,8 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp private TextView mTitle; private TextView mText; private View mActionsContainer; + private View mReplyAction; + private Rect mTmpRect = new Rect(); private int mContentHeight; private int mMinHeightHint; @@ -130,6 +133,29 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp mProgressBar = null; } mActionsContainer = mView.findViewById(com.android.internal.R.id.actions_container); + mReplyAction = mView.findViewById(com.android.internal.R.id.reply_icon_action); + } + + @Override + public boolean disallowSingleClick(float x, float y) { + if (mReplyAction != null && mReplyAction.getVisibility() == View.VISIBLE) { + if (isOnView(mReplyAction, x, y) || isOnView(mPicture, x, y)) { + return true; + } + } + return super.disallowSingleClick(x, y); + } + + private boolean isOnView(View view, float x, float y) { + View searchView = (View) view.getParent(); + while (searchView != null && !(searchView instanceof ExpandableNotificationRow)) { + searchView.getHitRect(mTmpRect); + x -= mTmpRect.left; + y -= mTmpRect.top; + searchView = (View) searchView.getParent(); + } + view.getHitRect(mTmpRect); + return mTmpRect.contains((int) x,(int) y); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java index 5cc39cc27b26..07f50449fd68 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java @@ -182,4 +182,8 @@ public abstract class NotificationViewWrapper implements TransformableView { public boolean isDimmable() { return true; } + + public boolean disallowSingleClick(float x, float y) { + return false; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java index 6fe5756ea9f8..fb4e2eccadc0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java @@ -41,6 +41,9 @@ public class TextViewTransformState extends TransformState { @Override protected boolean sameAs(TransformState otherState) { + if (super.sameAs(otherState)) { + return true; + } if (otherState instanceof TextViewTransformState) { TextViewTransformState otherTvs = (TextViewTransformState) otherState; if(TextUtils.equals(otherTvs.mText.getText(), mText.getText())) { @@ -50,7 +53,7 @@ public class TextViewTransformState extends TransformState { && getInnerHeight(mText) == getInnerHeight(otherTvs.mText); } } - return super.sameAs(otherState); + return false; } private int getInnerHeight(TextView text) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java index c3f1cb1c7a93..a77dd4ee8c43 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java @@ -54,6 +54,7 @@ public class TransformState { protected View mTransformedView; private int[] mOwnPosition = new int[2]; + private boolean mSameAsAny; private float mTransformationEndY = UNDEFINED; private float mTransformationEndX = UNDEFINED; @@ -418,7 +419,7 @@ public class TransformState { } protected boolean sameAs(TransformState otherState) { - return false; + return mSameAsAny; } public void appear(float transformationAmount, TransformableView otherView) { @@ -449,6 +450,9 @@ public class TransformState { if (view instanceof ImageView) { ImageTransformState result = ImageTransformState.obtain(); result.initFrom(view); + if (view.getId() == com.android.internal.R.id.reply_icon_action) { + ((TransformState) result).setIsSameAsAnyView(true); + } return result; } if (view instanceof ProgressBar) { @@ -461,6 +465,10 @@ public class TransformState { return result; } + private void setIsSameAsAnyView(boolean sameAsAny) { + mSameAsAny = sameAsAny; + } + public void recycle() { reset(); if (getClass() == TransformState.class) { @@ -514,6 +522,7 @@ public class TransformState { protected void reset() { mTransformedView = null; + mSameAsAny = false; mTransformationEndX = UNDEFINED; mTransformationEndY = UNDEFINED; } |