Merge "Reduce hardware render sizes for ExpandableNotificationRow." into sc-v2-dev
This commit is contained in:
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.notification;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to let views that have an alpha not apply the HARDWARE layer type directly, and instead
|
||||||
|
* delegate that to specific children. This is useful if we want to fake not having overlapping
|
||||||
|
* rendering to avoid layer trashing, when fading out a view that is also changing.
|
||||||
|
*/
|
||||||
|
public interface NotificationFadeAware {
|
||||||
|
/**
|
||||||
|
* Calls {@link View#setLayerType} with {@link View#LAYER_TYPE_HARDWARE} if faded and
|
||||||
|
* {@link View#LAYER_TYPE_NONE} otherwise.
|
||||||
|
*/
|
||||||
|
static void setLayerTypeForFaded(@Nullable View view, boolean faded) {
|
||||||
|
if (view != null) {
|
||||||
|
int newLayerType = faded ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE;
|
||||||
|
view.setLayerType(newLayerType, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used like {@link View#setLayerType} with {@link View#LAYER_TYPE_HARDWARE} or
|
||||||
|
* {@link View#LAYER_TYPE_NONE} except that instead of necessarily affecting this view
|
||||||
|
* specifically, this may delegate the call to child views.
|
||||||
|
*
|
||||||
|
* When set to <code>true</code>, the view has two possible paths:
|
||||||
|
* 1. If a hardware layer is required to ensure correct appearance of this view, then
|
||||||
|
* set that layer type.
|
||||||
|
* 2. Otherwise, delegate this call to children, who might make that call for themselves.
|
||||||
|
*
|
||||||
|
* When set to <code>false</code>, the view should undo the above, typically by calling
|
||||||
|
* {@link View#setLayerType} with {@link View#LAYER_TYPE_NONE} on itself and children, and
|
||||||
|
* delegating to this method on children where implemented.
|
||||||
|
*
|
||||||
|
* When this delegates to {@link View#setLayerType} on this view or a subview, `null` will be
|
||||||
|
* passed for the `paint` argument of that call.
|
||||||
|
*/
|
||||||
|
void setNotificationFaded(boolean faded);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for the top level notification view that fades and optimizes that through deep
|
||||||
|
* awareness of individual components.
|
||||||
|
*/
|
||||||
|
interface FadeOptimizedNotification extends NotificationFadeAware {
|
||||||
|
/** Top-level feature switch */
|
||||||
|
boolean FADE_LAYER_OPTIMIZATION_ENABLED = true;
|
||||||
|
|
||||||
|
/** Determine if the notification is currently faded. */
|
||||||
|
boolean isNotificationFaded();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,6 +87,7 @@ import com.android.systemui.statusbar.RemoteInputController;
|
|||||||
import com.android.systemui.statusbar.StatusBarIconView;
|
import com.android.systemui.statusbar.StatusBarIconView;
|
||||||
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
|
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
|
||||||
import com.android.systemui.statusbar.notification.ExpandAnimationParameters;
|
import com.android.systemui.statusbar.notification.ExpandAnimationParameters;
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
|
import com.android.systemui.statusbar.notification.NotificationLaunchAnimatorController;
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
@@ -125,7 +126,8 @@ import java.util.function.Consumer;
|
|||||||
* the group summary (which contains 1 or more child notifications).
|
* the group summary (which contains 1 or more child notifications).
|
||||||
*/
|
*/
|
||||||
public class ExpandableNotificationRow extends ActivatableNotificationView
|
public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||||
implements PluginListener<NotificationMenuRowPlugin>, SwipeableView {
|
implements PluginListener<NotificationMenuRowPlugin>, SwipeableView,
|
||||||
|
NotificationFadeAware.FadeOptimizedNotification {
|
||||||
|
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
|
private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
|
||||||
@@ -138,6 +140,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
private boolean mUpdateBackgroundOnUpdate;
|
private boolean mUpdateBackgroundOnUpdate;
|
||||||
private boolean mNotificationTranslationFinished = false;
|
private boolean mNotificationTranslationFinished = false;
|
||||||
private boolean mIsSnoozed;
|
private boolean mIsSnoozed;
|
||||||
|
private boolean mIsFaded;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener for when {@link ExpandableNotificationRow} is laid out.
|
* Listener for when {@link ExpandableNotificationRow} is laid out.
|
||||||
@@ -2753,17 +2756,112 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
|||||||
// alphas are reset
|
// alphas are reset
|
||||||
if (mChildrenContainer != null) {
|
if (mChildrenContainer != null) {
|
||||||
mChildrenContainer.setAlpha(1.0f);
|
mChildrenContainer.setAlpha(1.0f);
|
||||||
mChildrenContainer.setLayerType(LAYER_TYPE_NONE, null);
|
|
||||||
}
|
}
|
||||||
for (NotificationContentView l : mLayouts) {
|
for (NotificationContentView l : mLayouts) {
|
||||||
l.setAlpha(1.0f);
|
l.setAlpha(1.0f);
|
||||||
l.setLayerType(LAYER_TYPE_NONE, null);
|
}
|
||||||
|
if (FADE_LAYER_OPTIMIZATION_ENABLED) {
|
||||||
|
setNotificationFaded(false);
|
||||||
|
} else {
|
||||||
|
setNotificationFadedOnChildren(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setHeadsUpAnimatingAway(false);
|
setHeadsUpAnimatingAway(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the last value set with {@link #setNotificationFaded(boolean)} */
|
||||||
|
@Override
|
||||||
|
public boolean isNotificationFaded() {
|
||||||
|
return mIsFaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class needs to delegate the faded state set on it by
|
||||||
|
* {@link com.android.systemui.statusbar.notification.stack.ViewState} to its children.
|
||||||
|
* Having each notification use layerType of HARDWARE anytime it fades in/out can result in
|
||||||
|
* extremely large layers (in the case of groups, it can even exceed the device height).
|
||||||
|
* Because these large renders can cause serious jank when rendering, we instead have
|
||||||
|
* notifications return false from {@link #hasOverlappingRendering()} and delegate the
|
||||||
|
* layerType to child views which really need it in order to render correctly, such as icon
|
||||||
|
* views or the conversation face pile.
|
||||||
|
*
|
||||||
|
* Another compounding factor for notifications is that we change clipping on each frame of the
|
||||||
|
* animation, so the hardware layer isn't able to do any caching at the top level, but the
|
||||||
|
* individual elements we render with hardware layers (e.g. icons) cache wonderfully because we
|
||||||
|
* never invalidate them.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setNotificationFaded(boolean faded) {
|
||||||
|
mIsFaded = faded;
|
||||||
|
if (childrenRequireOverlappingRendering()) {
|
||||||
|
// == Simple Scenario ==
|
||||||
|
// If a child (like remote input) needs this to have overlapping rendering, then set
|
||||||
|
// the layerType of this view and reset the children to render as if the notification is
|
||||||
|
// not fading.
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(this, faded);
|
||||||
|
setNotificationFadedOnChildren(false);
|
||||||
|
} else {
|
||||||
|
// == Delegating Scenario ==
|
||||||
|
// This is the new normal for alpha: Explicitly reset this view's layer type to NONE,
|
||||||
|
// and require that all children use their own hardware layer if they have bad
|
||||||
|
// overlapping rendering.
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(this, false);
|
||||||
|
setNotificationFadedOnChildren(faded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Private helper for iterating over the layouts and children containers to set faded state */
|
||||||
|
private void setNotificationFadedOnChildren(boolean faded) {
|
||||||
|
delegateNotificationFaded(mChildrenContainer, faded);
|
||||||
|
for (NotificationContentView layout : mLayouts) {
|
||||||
|
delegateNotificationFaded(layout, faded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void delegateNotificationFaded(@Nullable View view, boolean faded) {
|
||||||
|
if (FADE_LAYER_OPTIMIZATION_ENABLED && view instanceof NotificationFadeAware) {
|
||||||
|
((NotificationFadeAware) view).setNotificationFaded(faded);
|
||||||
|
} else {
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(view, faded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only declare overlapping rendering if independent children of the view require it.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean hasOverlappingRendering() {
|
||||||
|
return super.hasOverlappingRendering() && childrenRequireOverlappingRendering();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Because RemoteInputView is designed to be an opaque view that overlaps the Actions row, the
|
||||||
|
* row should require overlapping rendering to ensure that the overlapped view doesn't bleed
|
||||||
|
* through when alpha fading.
|
||||||
|
*
|
||||||
|
* Note that this currently works for top-level notifications which squish their height down
|
||||||
|
* while collapsing the shade, but does not work for children inside groups, because the
|
||||||
|
* accordion affect does not apply to those views, so super.hasOverlappingRendering() will
|
||||||
|
* always return false to avoid the clipping caused when the view's measured height is less than
|
||||||
|
* the 'actual height'.
|
||||||
|
*/
|
||||||
|
private boolean childrenRequireOverlappingRendering() {
|
||||||
|
if (!FADE_LAYER_OPTIMIZATION_ENABLED) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// The colorized background is another layer with which all other elements overlap
|
||||||
|
if (getEntry().getSbn().getNotification().isColorized()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Check if the showing layout has a need for overlapping rendering.
|
||||||
|
// NOTE: We could check both public and private layouts here, but becuause these states
|
||||||
|
// don't animate well, there are bigger visual artifacts if we start changing the shown
|
||||||
|
// layout during shade expansion.
|
||||||
|
NotificationContentView showingLayout = getShowingLayout();
|
||||||
|
return showingLayout != null && showingLayout.requireRowToHaveOverlappingRendering();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getExtraBottomPadding() {
|
public int getExtraBottomPadding() {
|
||||||
if (mIsSummaryWithChildren && isGroupExpanded()) {
|
if (mIsSummaryWithChildren && isGroupExpanded()) {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import com.android.internal.widget.ConversationLayout;
|
import com.android.internal.widget.ConversationLayout;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hybrid view which may contain information about one ore more conversations.
|
* A hybrid view which may contain information about one ore more conversations.
|
||||||
@@ -138,4 +139,14 @@ public class HybridConversationNotificationView extends HybridNotificationView {
|
|||||||
lp.height = size;
|
lp.height = size;
|
||||||
view.setLayoutParams(lp);
|
view.setLayoutParams(lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the faded state as a layer type change to the face pile view which needs to have
|
||||||
|
* overlapping contents render precisely.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setNotificationFaded(boolean faded) {
|
||||||
|
super.setNotificationFaded(faded);
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(mConversationFacePile, faded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,13 +28,14 @@ import com.android.systemui.R;
|
|||||||
import com.android.systemui.statusbar.CrossFadeHelper;
|
import com.android.systemui.statusbar.CrossFadeHelper;
|
||||||
import com.android.systemui.statusbar.TransformableView;
|
import com.android.systemui.statusbar.TransformableView;
|
||||||
import com.android.systemui.statusbar.ViewTransformationHelper;
|
import com.android.systemui.statusbar.ViewTransformationHelper;
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.TransformState;
|
import com.android.systemui.statusbar.notification.TransformState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hybrid view which may contain information about one ore more notifications.
|
* A hybrid view which may contain information about one ore more notifications.
|
||||||
*/
|
*/
|
||||||
public class HybridNotificationView extends AlphaOptimizedLinearLayout
|
public class HybridNotificationView extends AlphaOptimizedLinearLayout
|
||||||
implements TransformableView {
|
implements TransformableView, NotificationFadeAware {
|
||||||
|
|
||||||
protected final ViewTransformationHelper mTransformationHelper = new ViewTransformationHelper();
|
protected final ViewTransformationHelper mTransformationHelper = new ViewTransformationHelper();
|
||||||
protected TextView mTitleView;
|
protected TextView mTitleView;
|
||||||
@@ -148,4 +149,7 @@ public class HybridNotificationView extends AlphaOptimizedLinearLayout
|
|||||||
setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
|
setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
|
||||||
mTransformationHelper.setVisible(visible);
|
mTransformationHelper.setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNotificationFaded(boolean faded) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
|
|||||||
import com.android.systemui.statusbar.RemoteInputController;
|
import com.android.systemui.statusbar.RemoteInputController;
|
||||||
import com.android.systemui.statusbar.SmartReplyController;
|
import com.android.systemui.statusbar.SmartReplyController;
|
||||||
import com.android.systemui.statusbar.TransformableView;
|
import com.android.systemui.statusbar.TransformableView;
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
|
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
|
||||||
@@ -71,7 +72,7 @@ import java.util.List;
|
|||||||
* expanded and heads up layout. This class is responsible for clipping the content and and
|
* expanded and heads up layout. This class is responsible for clipping the content and and
|
||||||
* switching between the expanded, contracted and the heads up view depending on its clipped size.
|
* switching between the expanded, contracted and the heads up view depending on its clipped size.
|
||||||
*/
|
*/
|
||||||
public class NotificationContentView extends FrameLayout {
|
public class NotificationContentView extends FrameLayout implements NotificationFadeAware {
|
||||||
|
|
||||||
private static final String TAG = "NotificationContentView";
|
private static final String TAG = "NotificationContentView";
|
||||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||||
@@ -1994,4 +1995,39 @@ public class NotificationContentView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
return Notification.COLOR_INVALID;
|
return Notification.COLOR_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegate the faded state to the notification content views which actually
|
||||||
|
* need to have overlapping contents render precisely.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setNotificationFaded(boolean faded) {
|
||||||
|
if (mContractedWrapper != null) {
|
||||||
|
mContractedWrapper.setNotificationFaded(faded);
|
||||||
|
}
|
||||||
|
if (mHeadsUpWrapper != null) {
|
||||||
|
mHeadsUpWrapper.setNotificationFaded(faded);
|
||||||
|
}
|
||||||
|
if (mExpandedWrapper != null) {
|
||||||
|
mExpandedWrapper.setNotificationFaded(faded);
|
||||||
|
}
|
||||||
|
if (mSingleLineView != null) {
|
||||||
|
mSingleLineView.setNotificationFaded(faded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if a visible view has a remote input active, as this requires that the entire
|
||||||
|
* row report that it has overlapping rendering.
|
||||||
|
*/
|
||||||
|
public boolean requireRowToHaveOverlappingRendering() {
|
||||||
|
// This inexpensive check is done on both states to avoid state invalidating the result.
|
||||||
|
if (mHeadsUpRemoteInput != null && mHeadsUpRemoteInput.isActive()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (mExpandedRemoteInput != null && mExpandedRemoteInput.isActive()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.view.View
|
|||||||
import com.android.internal.widget.CachingIconView
|
import com.android.internal.widget.CachingIconView
|
||||||
import com.android.internal.widget.CallLayout
|
import com.android.internal.widget.CallLayout
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils
|
import com.android.systemui.statusbar.notification.NotificationUtils
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
||||||
|
|
||||||
@@ -37,6 +38,7 @@ class NotificationCallTemplateViewWrapper constructor(
|
|||||||
NotificationUtils.getFontScaledHeight(ctx, R.dimen.notification_max_height)
|
NotificationUtils.getFontScaledHeight(ctx, R.dimen.notification_max_height)
|
||||||
private val callLayout: CallLayout = view as CallLayout
|
private val callLayout: CallLayout = view as CallLayout
|
||||||
|
|
||||||
|
private lateinit var conversationIconContainer: View
|
||||||
private lateinit var conversationIconView: CachingIconView
|
private lateinit var conversationIconView: CachingIconView
|
||||||
private lateinit var conversationBadgeBg: View
|
private lateinit var conversationBadgeBg: View
|
||||||
private lateinit var expandBtn: View
|
private lateinit var expandBtn: View
|
||||||
@@ -45,6 +47,8 @@ class NotificationCallTemplateViewWrapper constructor(
|
|||||||
|
|
||||||
private fun resolveViews() {
|
private fun resolveViews() {
|
||||||
with(callLayout) {
|
with(callLayout) {
|
||||||
|
conversationIconContainer =
|
||||||
|
requireViewById(com.android.internal.R.id.conversation_icon_container)
|
||||||
conversationIconView = requireViewById(com.android.internal.R.id.conversation_icon)
|
conversationIconView = requireViewById(com.android.internal.R.id.conversation_icon)
|
||||||
conversationBadgeBg =
|
conversationBadgeBg =
|
||||||
requireViewById(com.android.internal.R.id.conversation_icon_badge_bg)
|
requireViewById(com.android.internal.R.id.conversation_icon_badge_bg)
|
||||||
@@ -82,4 +86,14 @@ class NotificationCallTemplateViewWrapper constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getMinLayoutHeight(): Int = minHeightWithActions
|
override fun getMinLayoutHeight(): Int = minHeightWithActions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the faded state as a layer type change to the face pile view which needs to have
|
||||||
|
* overlapping contents render precisely.
|
||||||
|
*/
|
||||||
|
override fun setNotificationFaded(faded: Boolean) {
|
||||||
|
// Do not call super
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(expandBtn, faded)
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(conversationIconContainer, faded)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.android.internal.widget.CachingIconView
|
|||||||
import com.android.internal.widget.ConversationLayout
|
import com.android.internal.widget.ConversationLayout
|
||||||
import com.android.internal.widget.MessagingLinearLayout
|
import com.android.internal.widget.MessagingLinearLayout
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils
|
import com.android.systemui.statusbar.notification.NotificationUtils
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
|
||||||
import com.android.systemui.statusbar.notification.row.wrapper.NotificationMessagingTemplateViewWrapper.setCustomImageMessageTransform
|
import com.android.systemui.statusbar.notification.row.wrapper.NotificationMessagingTemplateViewWrapper.setCustomImageMessageTransform
|
||||||
@@ -42,6 +43,7 @@ class NotificationConversationTemplateViewWrapper constructor(
|
|||||||
)
|
)
|
||||||
private val conversationLayout: ConversationLayout = view as ConversationLayout
|
private val conversationLayout: ConversationLayout = view as ConversationLayout
|
||||||
|
|
||||||
|
private lateinit var conversationIconContainer: View
|
||||||
private lateinit var conversationIconView: CachingIconView
|
private lateinit var conversationIconView: CachingIconView
|
||||||
private lateinit var conversationBadgeBg: View
|
private lateinit var conversationBadgeBg: View
|
||||||
private lateinit var expandBtn: View
|
private lateinit var expandBtn: View
|
||||||
@@ -59,6 +61,8 @@ class NotificationConversationTemplateViewWrapper constructor(
|
|||||||
messagingLinearLayout = conversationLayout.messagingLinearLayout
|
messagingLinearLayout = conversationLayout.messagingLinearLayout
|
||||||
imageMessageContainer = conversationLayout.imageMessageContainer
|
imageMessageContainer = conversationLayout.imageMessageContainer
|
||||||
with(conversationLayout) {
|
with(conversationLayout) {
|
||||||
|
conversationIconContainer =
|
||||||
|
requireViewById(com.android.internal.R.id.conversation_icon_container)
|
||||||
conversationIconView = requireViewById(com.android.internal.R.id.conversation_icon)
|
conversationIconView = requireViewById(com.android.internal.R.id.conversation_icon)
|
||||||
conversationBadgeBg =
|
conversationBadgeBg =
|
||||||
requireViewById(com.android.internal.R.id.conversation_icon_badge_bg)
|
requireViewById(com.android.internal.R.id.conversation_icon_badge_bg)
|
||||||
@@ -136,4 +140,10 @@ class NotificationConversationTemplateViewWrapper constructor(
|
|||||||
minHeightWithActions
|
minHeightWithActions
|
||||||
else
|
else
|
||||||
super.getMinLayoutHeight()
|
super.getMinLayoutHeight()
|
||||||
|
|
||||||
|
override fun setNotificationFaded(faded: Boolean) {
|
||||||
|
// Do not call super
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(expandBtn, faded)
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(conversationIconContainer, faded)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.view.View;
|
|||||||
|
|
||||||
import com.android.internal.graphics.ColorUtils;
|
import com.android.internal.graphics.ColorUtils;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,4 +87,14 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper {
|
|||||||
public boolean shouldClipToRounding(boolean topRounded, boolean bottomRounded) {
|
public boolean shouldClipToRounding(boolean topRounded, boolean bottomRounded) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the faded state as a layer type change to the custom view which needs to have
|
||||||
|
* overlapping contents render precisely.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setNotificationFaded(boolean faded) {
|
||||||
|
super.setNotificationFaded(faded);
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(mView, faded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.content.Context;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -67,4 +68,14 @@ public class NotificationDecoratedCustomViewWrapper extends NotificationTemplate
|
|||||||
}
|
}
|
||||||
super.onContentUpdated(row);
|
super.onContentUpdated(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the faded state as a layer type change to the custom view which needs to have
|
||||||
|
* overlapping contents render precisely.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setNotificationFaded(boolean faded) {
|
||||||
|
super.setNotificationFaded(faded);
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(mWrappedView, faded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import com.android.internal.widget.CachingIconView;
|
|||||||
import com.android.settingslib.Utils;
|
import com.android.settingslib.Utils;
|
||||||
import com.android.systemui.statusbar.CrossFadeHelper;
|
import com.android.systemui.statusbar.CrossFadeHelper;
|
||||||
import com.android.systemui.statusbar.TransformableView;
|
import com.android.systemui.statusbar.TransformableView;
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.TransformState;
|
import com.android.systemui.statusbar.notification.TransformState;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
|
|
||||||
@@ -395,4 +396,13 @@ public abstract class NotificationViewWrapper implements TransformableView {
|
|||||||
*/
|
*/
|
||||||
public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
|
public void setRecentlyAudiblyAlerted(boolean audiblyAlerted) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the faded state as a layer type change to the views which need to have overlapping
|
||||||
|
* contents render precisely.
|
||||||
|
*/
|
||||||
|
public void setNotificationFaded(boolean faded) {
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(getIcon(), faded);
|
||||||
|
NotificationFadeAware.setLayerTypeForFaded(getExpandButton(), faded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import com.android.internal.widget.NotificationExpandButton;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.statusbar.CrossFadeHelper;
|
import com.android.systemui.statusbar.CrossFadeHelper;
|
||||||
import com.android.systemui.statusbar.NotificationGroupingUtil;
|
import com.android.systemui.statusbar.NotificationGroupingUtil;
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware;
|
||||||
import com.android.systemui.statusbar.notification.NotificationUtils;
|
import com.android.systemui.statusbar.notification.NotificationUtils;
|
||||||
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
|
||||||
@@ -51,7 +52,8 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* A container containing child notifications
|
* A container containing child notifications
|
||||||
*/
|
*/
|
||||||
public class NotificationChildrenContainer extends ViewGroup {
|
public class NotificationChildrenContainer extends ViewGroup
|
||||||
|
implements NotificationFadeAware {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final int NUMBER_OF_CHILDREN_WHEN_COLLAPSED = 2;
|
static final int NUMBER_OF_CHILDREN_WHEN_COLLAPSED = 2;
|
||||||
@@ -111,6 +113,7 @@ public class NotificationChildrenContainer extends ViewGroup {
|
|||||||
private int mCurrentHeaderTranslation = 0;
|
private int mCurrentHeaderTranslation = 0;
|
||||||
private float mHeaderVisibleAmount = 1.0f;
|
private float mHeaderVisibleAmount = 1.0f;
|
||||||
private int mUntruncatedChildCount;
|
private int mUntruncatedChildCount;
|
||||||
|
private boolean mContainingNotificationIsFaded = false;
|
||||||
|
|
||||||
public NotificationChildrenContainer(Context context) {
|
public NotificationChildrenContainer(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@@ -277,6 +280,7 @@ public class NotificationChildrenContainer extends ViewGroup {
|
|||||||
mDividers.add(newIndex, divider);
|
mDividers.add(newIndex, divider);
|
||||||
|
|
||||||
row.setContentTransformationAmount(0, false /* isLastChild */);
|
row.setContentTransformationAmount(0, false /* isLastChild */);
|
||||||
|
row.setNotificationFaded(mContainingNotificationIsFaded);
|
||||||
// It doesn't make sense to keep old animations around, lets cancel them!
|
// It doesn't make sense to keep old animations around, lets cancel them!
|
||||||
ExpandableViewState viewState = row.getViewState();
|
ExpandableViewState viewState = row.getViewState();
|
||||||
if (viewState != null) {
|
if (viewState != null) {
|
||||||
@@ -301,6 +305,7 @@ public class NotificationChildrenContainer extends ViewGroup {
|
|||||||
});
|
});
|
||||||
|
|
||||||
row.setSystemChildExpanded(false);
|
row.setSystemChildExpanded(false);
|
||||||
|
row.setNotificationFaded(false);
|
||||||
row.setUserLocked(false);
|
row.setUserLocked(false);
|
||||||
if (!row.isRemoved()) {
|
if (!row.isRemoved()) {
|
||||||
mGroupingUtil.restoreChildNotification(row);
|
mGroupingUtil.restoreChildNotification(row);
|
||||||
@@ -1308,4 +1313,18 @@ public class NotificationChildrenContainer extends ViewGroup {
|
|||||||
mNotificationHeaderWrapperLowPriority.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
|
mNotificationHeaderWrapperLowPriority.setRecentlyAudiblyAlerted(audiblyAlertedRecently);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNotificationFaded(boolean faded) {
|
||||||
|
mContainingNotificationIsFaded = faded;
|
||||||
|
if (mNotificationHeaderWrapper != null) {
|
||||||
|
mNotificationHeaderWrapper.setNotificationFaded(faded);
|
||||||
|
}
|
||||||
|
if (mNotificationHeaderWrapperLowPriority != null) {
|
||||||
|
mNotificationHeaderWrapperLowPriority.setNotificationFaded(faded);
|
||||||
|
}
|
||||||
|
for (ExpandableNotificationRow child : mAttachedChildren) {
|
||||||
|
child.setNotificationFaded(faded);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import com.android.systemui.Dumpable;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.animation.Interpolators;
|
import com.android.systemui.animation.Interpolators;
|
||||||
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
||||||
|
import com.android.systemui.statusbar.notification.NotificationFadeAware.FadeOptimizedNotification;
|
||||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||||
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
||||||
import com.android.systemui.statusbar.policy.HeadsUpUtil;
|
import com.android.systemui.statusbar.policy.HeadsUpUtil;
|
||||||
@@ -206,14 +207,26 @@ public class ViewState implements Dumpable {
|
|||||||
} else if (view.getAlpha() != this.alpha) {
|
} else if (view.getAlpha() != this.alpha) {
|
||||||
// apply layer type
|
// apply layer type
|
||||||
boolean becomesFullyVisible = this.alpha == 1.0f;
|
boolean becomesFullyVisible = this.alpha == 1.0f;
|
||||||
boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible
|
boolean becomesFaded = !becomesInvisible && !becomesFullyVisible;
|
||||||
&& view.hasOverlappingRendering();
|
if (FadeOptimizedNotification.FADE_LAYER_OPTIMIZATION_ENABLED
|
||||||
int layerType = view.getLayerType();
|
&& view instanceof FadeOptimizedNotification) {
|
||||||
int newLayerType = newLayerTypeIsHardware
|
// NOTE: A view that's going to utilize this interface to avoid having a hardware
|
||||||
? View.LAYER_TYPE_HARDWARE
|
// layer will have to return false from hasOverlappingRendering(), so we
|
||||||
: View.LAYER_TYPE_NONE;
|
// intentionally do not check that value in this if, even though we do in the else.
|
||||||
if (layerType != newLayerType) {
|
FadeOptimizedNotification fadeOptimizedView = (FadeOptimizedNotification) view;
|
||||||
view.setLayerType(newLayerType, null);
|
boolean isFaded = fadeOptimizedView.isNotificationFaded();
|
||||||
|
if (isFaded != becomesFaded) {
|
||||||
|
fadeOptimizedView.setNotificationFaded(becomesFaded);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
boolean newLayerTypeIsHardware = becomesFaded && view.hasOverlappingRendering();
|
||||||
|
int layerType = view.getLayerType();
|
||||||
|
int newLayerType = newLayerTypeIsHardware
|
||||||
|
? View.LAYER_TYPE_HARDWARE
|
||||||
|
: View.LAYER_TYPE_NONE;
|
||||||
|
if (layerType != newLayerType) {
|
||||||
|
view.setLayerType(newLayerType, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply alpha
|
// apply alpha
|
||||||
|
|||||||
Reference in New Issue
Block a user