diff options
14 files changed, 167 insertions, 9 deletions
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml index ea22b15..94bbec8 100644 --- a/core/res/res/layout/notification_template_material_base.xml +++ b/core/res/res/layout/notification_template_material_base.xml @@ -19,6 +19,7 @@ android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="64dp" + android:tag="base" > <include layout="@layout/notification_template_icon_group" android:layout_width="@dimen/notification_large_icon_width" diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml index 2a3ee90..a13dc85 100644 --- a/core/res/res/layout/notification_template_material_big_base.xml +++ b/core/res/res/layout/notification_template_material_big_base.xml @@ -19,6 +19,7 @@ android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="wrap_content" + android:tag="big" > <include layout="@layout/notification_template_icon_group" android:layout_width="@dimen/notification_large_icon_width" diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml index 93acdbf..7fd93de 100644 --- a/core/res/res/layout/notification_template_material_big_media.xml +++ b/core/res/res/layout/notification_template_material_big_media.xml @@ -20,6 +20,7 @@ android:layout_width="match_parent" android:layout_height="128dp" android:background="#00000000" + android:tag="bigMedia" > <include layout="@layout/notification_template_icon_group" android:layout_width="@dimen/notification_large_icon_width" diff --git a/core/res/res/layout/notification_template_material_big_media_narrow.xml b/core/res/res/layout/notification_template_material_big_media_narrow.xml index 21e5ff8..807cfaf 100644 --- a/core/res/res/layout/notification_template_material_big_media_narrow.xml +++ b/core/res/res/layout/notification_template_material_big_media_narrow.xml @@ -21,6 +21,7 @@ android:layout_width="match_parent" android:layout_height="128dp" android:background="#00000000" + android:tag="bigMediaNarrow" > <ImageView android:id="@+id/icon" android:layout_width="128dp" diff --git a/core/res/res/layout/notification_template_material_big_picture.xml b/core/res/res/layout/notification_template_material_big_picture.xml index f1a9549..f3768b5 100644 --- a/core/res/res/layout/notification_template_material_big_picture.xml +++ b/core/res/res/layout/notification_template_material_big_picture.xml @@ -19,6 +19,7 @@ android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="match_parent" + android:tag="bigPicture" > <ImageView android:id="@+id/big_picture" diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml index f657f04..b677a98 100644 --- a/core/res/res/layout/notification_template_material_big_text.xml +++ b/core/res/res/layout/notification_template_material_big_text.xml @@ -19,6 +19,7 @@ android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="wrap_content" + android:tag="bigText" > <include layout="@layout/notification_template_icon_group" android:layout_width="@dimen/notification_large_icon_width" diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml index a8d2ee3..c109225 100644 --- a/core/res/res/layout/notification_template_material_inbox.xml +++ b/core/res/res/layout/notification_template_material_inbox.xml @@ -19,6 +19,7 @@ android:id="@+id/status_bar_latest_event_content" android:layout_width="match_parent" android:layout_height="wrap_content" + android:tag="inbox" > <include layout="@layout/notification_template_icon_group" android:layout_width="@dimen/notification_large_icon_width" diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml index 0292d28..f6c22c8 100644 --- a/core/res/res/layout/notification_template_material_media.xml +++ b/core/res/res/layout/notification_template_material_media.xml @@ -21,6 +21,7 @@ android:layout_height="64dp" android:orientation="horizontal" android:background="#00000000" + android:tag="media" > <include layout="@layout/notification_template_icon_group" android:layout_width="@dimen/notification_large_icon_width" diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 354e99d..139462d 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -42,6 +42,10 @@ <!-- Whether to use cheap, less good looking shadows for recents --> <bool name="config_recents_fake_shadows">false</bool> + <!-- Whether to clip notification contents with a rounded rectangle. Might be expensive on + certain GPU's and thus can be turned off with only minimal visual impact. --> + <bool name="config_notifications_round_rect_clipping">true</bool> + <!-- The theme to use for RecentsActivity. --> <item type="style" name="config_recents_activity_theme">@style/RecentsTheme.Wallpaper</item> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBigMediaNarrowViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBigMediaNarrowViewWrapper.java new file mode 100644 index 0000000..91e5404 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBigMediaNarrowViewWrapper.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2015 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 + */ + +package com.android.systemui.statusbar; + +import android.content.Context; +import android.view.View; + +/** + * Wraps a big media narrow notification template layout. + */ +public class NotificationBigMediaNarrowViewWrapper extends NotificationMediaViewWrapper { + + protected NotificationBigMediaNarrowViewWrapper(Context ctx, + View view) { + super(ctx, view); + } + + @Override + public boolean needsRoundRectClipping() { + return true; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBigPictureViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBigPictureViewWrapper.java new file mode 100644 index 0000000..ffe0cd1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBigPictureViewWrapper.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2015 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 + */ + +package com.android.systemui.statusbar; + +import android.content.Context; +import android.view.View; + +/** + * Wraps a notification view inflated from a big picture style template. + */ +public class NotificationBigPictureViewWrapper extends NotificationTemplateViewWrapper { + + protected NotificationBigPictureViewWrapper(Context ctx, View view) { + super(ctx, view); + } + + @Override + public boolean needsRoundRectClipping() { + return true; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index 110b14c..dec2fc7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar; import android.content.Context; +import android.graphics.Outline; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; @@ -24,6 +25,7 @@ import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; +import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; @@ -46,21 +48,26 @@ public class NotificationContentView extends FrameLayout { private final Rect mClipBounds = new Rect(); private final int mSmallHeight; private final int mHeadsUpHeight; + private final int mRoundRectRadius; private final Interpolator mLinearInterpolator = new LinearInterpolator(); + private final boolean mRoundRectClippingEnabled; private View mContractedChild; private View mExpandedChild; private View mHeadsUpChild; private NotificationViewWrapper mContractedWrapper; + private NotificationViewWrapper mExpandedWrapper; + private NotificationViewWrapper mHeadsUpWrapper; private int mClipTopAmount; private int mContentHeight; + private int mUnrestrictedContentHeight; private int mVisibleType = VISIBLE_TYPE_CONTRACTED; private boolean mDark; private final Paint mFadePaint = new Paint(); private boolean mAnimate; private boolean mIsHeadsUp; - private ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener + private final ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { @@ -70,12 +77,25 @@ public class NotificationContentView extends FrameLayout { } }; + private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() { + @Override + public void getOutline(View view, Outline outline) { + outline.setRoundRect(0, 0, view.getWidth(), mUnrestrictedContentHeight, + mRoundRectRadius); + } + }; + public NotificationContentView(Context context, AttributeSet attrs) { super(context, attrs); mFadePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD)); mSmallHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height); mHeadsUpHeight = getResources().getDimensionPixelSize(R.dimen.notification_mid_height); + mRoundRectRadius = getResources().getDimensionPixelSize( + R.dimen.notification_material_rounded_rect_radius); + mRoundRectClippingEnabled = getResources().getBoolean( + R.bool.config_notifications_round_rect_clipping); reset(true); + setOutlineProvider(mOutlineProvider); } @Override @@ -127,6 +147,7 @@ public class NotificationContentView extends FrameLayout { protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); updateClipping(); + invalidateOutline(); } @Override @@ -177,6 +198,7 @@ public class NotificationContentView extends FrameLayout { mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child); selectLayout(false /* animate */, true /* force */); mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */); + updateRoundRectClipping(); } public void setExpandedChild(View child) { @@ -186,7 +208,9 @@ public class NotificationContentView extends FrameLayout { } addView(child); mExpandedChild = child; + mExpandedWrapper = NotificationViewWrapper.wrap(getContext(), child); selectLayout(false /* animate */, true /* force */); + updateRoundRectClipping(); } public void setHeadsUpChild(View child) { @@ -196,7 +220,9 @@ public class NotificationContentView extends FrameLayout { } addView(child); mHeadsUpChild = child; + mHeadsUpWrapper = NotificationViewWrapper.wrap(getContext(), child); selectLayout(false /* animate */, true /* force */); + updateRoundRectClipping(); } @Override @@ -222,10 +248,11 @@ public class NotificationContentView extends FrameLayout { } public void setContentHeight(int contentHeight) { - contentHeight = Math.max(Math.min(contentHeight, getHeight()), getMinHeight()); - mContentHeight = contentHeight; + mContentHeight = Math.max(Math.min(contentHeight, getHeight()), getMinHeight());; + mUnrestrictedContentHeight = Math.max(contentHeight, getMinHeight()); selectLayout(mAnimate /* animate */, false /* force */); updateClipping(); + invalidateOutline(); } public int getContentHeight() { @@ -250,6 +277,27 @@ public class NotificationContentView extends FrameLayout { updateClipping(); } + private void updateRoundRectClipping() { + boolean enabled = needsRoundRectClipping(); + setClipToOutline(enabled); + } + + private boolean needsRoundRectClipping() { + if (!mRoundRectClippingEnabled) { + return false; + } + boolean needsForContracted = mContractedChild != null + && mContractedChild.getVisibility() == View.VISIBLE + && mContractedWrapper.needsRoundRectClipping(); + boolean needsForExpanded = mExpandedChild != null + && mExpandedChild.getVisibility() == View.VISIBLE + && mExpandedWrapper.needsRoundRectClipping(); + boolean needsForHeadsUp = mExpandedChild != null + && mExpandedChild.getVisibility() == View.VISIBLE + && mExpandedWrapper.needsRoundRectClipping(); + return needsForContracted || needsForExpanded || needsForHeadsUp; + } + private void updateClipping() { mClipBounds.set(0, mClipTopAmount, getWidth(), mContentHeight); setClipBounds(mClipBounds); @@ -290,6 +338,7 @@ public class NotificationContentView extends FrameLayout { mHeadsUpChild.setLayerType(LAYER_TYPE_NONE, null); } setLayerType(LAYER_TYPE_NONE, null); + updateRoundRectClipping(); } private void runSwitchAnimation(int visibleType) { @@ -315,6 +364,7 @@ public class NotificationContentView extends FrameLayout { updateViewVisibilities(mVisibleType); } }); + updateRoundRectClipping(); } /** @@ -358,6 +408,10 @@ public class NotificationContentView extends FrameLayout { mContractedWrapper.notifyContentUpdated(); mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */); } + if (mExpandedChild != null) { + mExpandedWrapper.notifyContentUpdated(); + } + updateRoundRectClipping(); } public boolean isContentExpandable() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationCustomViewWrapper.java index 0702d7e..6fd341b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationCustomViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationCustomViewWrapper.java @@ -41,4 +41,9 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper { mInvertHelper.update(dark); } } + + @Override + public boolean needsRoundRectClipping() { + return true; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java index 44e8b85..b362a29 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewWrapper.java @@ -25,15 +25,23 @@ import android.view.View; */ public abstract class NotificationViewWrapper { + private static final String TAG_BIG_MEDIA_NARROW = "bigMediaNarrow"; + private static final String TAG_MEDIA = "media"; + private static final String TAG_BIG_PICTURE = "bigPicture"; + protected final View mView; public static NotificationViewWrapper wrap(Context ctx, View v) { - - // TODO: Figure out a better way to find out which template the view is. - if (v.findViewById(com.android.internal.R.id.media_actions) != null) { - return new NotificationMediaViewWrapper(ctx, v); - } else if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) { - return new NotificationTemplateViewWrapper(ctx, v); + if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) { + if (TAG_BIG_MEDIA_NARROW.equals(v.getTag())) { + return new NotificationBigMediaNarrowViewWrapper(ctx, v); + } else if (TAG_MEDIA.equals(v.getTag())) { + return new NotificationMediaViewWrapper(ctx, v); + } else if (TAG_BIG_PICTURE.equals(v.getTag())) { + return new NotificationBigMediaNarrowViewWrapper(ctx, v); + } else { + return new NotificationTemplateViewWrapper(ctx, v); + } } else { return new NotificationCustomViewWrapper(v); } @@ -56,4 +64,12 @@ public abstract class NotificationViewWrapper { * Notifies this wrapper that the content of the view might have changed. */ public void notifyContentUpdated() {} + + /** + * @return true if this template might need to be clipped with a round rect to make it look + * nice, false otherwise + */ + public boolean needsRoundRectClipping() { + return false; + } } |