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

Commit d8061104 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge changes I41959627,Iba316772 into rvc-dev am: 9a979fb2

Change-Id: I329855dcce4a467a83f62c6af1e437a59a4d7a08
parents c0d784e0 9a979fb2
Loading
Loading
Loading
Loading
+20 −13
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.dagger.StatusBarModule;
import com.android.systemui.statusbar.dagger.StatusBarModule;
import com.android.systemui.statusbar.notification.DynamicChildBindController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
@@ -59,11 +60,12 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle


    private final Handler mHandler;
    private final Handler mHandler;


    //TODO: change this top <Entry, List<Entry>>?
    /** Re-usable map of notifications to their sorted children.*/
    private final HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>>
    private final HashMap<NotificationEntry, List<NotificationEntry>> mTmpChildOrderMap =
            mTmpChildOrderMap = new HashMap<>();
            new HashMap<>();


    // Dependencies:
    // Dependencies:
    private final DynamicChildBindController mDynamicChildBindController;
    protected final NotificationLockscreenUserManager mLockscreenUserManager;
    protected final NotificationLockscreenUserManager mLockscreenUserManager;
    protected final NotificationGroupManager mGroupManager;
    protected final NotificationGroupManager mGroupManager;
    protected final VisualStabilityManager mVisualStabilityManager;
    protected final VisualStabilityManager mVisualStabilityManager;
@@ -105,7 +107,8 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
            KeyguardBypassController bypassController,
            KeyguardBypassController bypassController,
            BubbleController bubbleController,
            BubbleController bubbleController,
            DynamicPrivacyController privacyController,
            DynamicPrivacyController privacyController,
            ForegroundServiceSectionController fgsSectionController) {
            ForegroundServiceSectionController fgsSectionController,
            DynamicChildBindController dynamicChildBindController) {
        mContext = context;
        mContext = context;
        mHandler = mainHandler;
        mHandler = mainHandler;
        mLockscreenUserManager = notificationLockscreenUserManager;
        mLockscreenUserManager = notificationLockscreenUserManager;
@@ -121,6 +124,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
        mBubbleController = bubbleController;
        mBubbleController = bubbleController;
        mDynamicPrivacyController = privacyController;
        mDynamicPrivacyController = privacyController;
        privacyController.addListener(this);
        privacyController.addListener(this);
        mDynamicChildBindController = dynamicChildBindController;
    }
    }


    public void setUpWithPresenter(NotificationPresenter presenter,
    public void setUpWithPresenter(NotificationPresenter presenter,
@@ -175,13 +179,12 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
            ent.getRow().setNeedsRedaction(needsRedaction);
            ent.getRow().setNeedsRedaction(needsRedaction);
            if (mGroupManager.isChildInGroupWithSummary(ent.getSbn())) {
            if (mGroupManager.isChildInGroupWithSummary(ent.getSbn())) {
                NotificationEntry summary = mGroupManager.getGroupSummary(ent.getSbn());
                NotificationEntry summary = mGroupManager.getGroupSummary(ent.getSbn());
                List<ExpandableNotificationRow> orderedChildren =
                List<NotificationEntry> orderedChildren = mTmpChildOrderMap.get(summary);
                        mTmpChildOrderMap.get(summary.getRow());
                if (orderedChildren == null) {
                if (orderedChildren == null) {
                    orderedChildren = new ArrayList<>();
                    orderedChildren = new ArrayList<>();
                    mTmpChildOrderMap.put(summary.getRow(), orderedChildren);
                    mTmpChildOrderMap.put(summary, orderedChildren);
                }
                }
                orderedChildren.add(ent.getRow());
                orderedChildren.add(ent);
            } else {
            } else {
                toShow.add(ent.getRow());
                toShow.add(ent.getRow());
            }
            }
@@ -260,6 +263,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle


        }
        }


        mDynamicChildBindController.updateChildContentViews(mTmpChildOrderMap);
        mVisualStabilityManager.onReorderingFinished();
        mVisualStabilityManager.onReorderingFinished();
        // clear the map again for the next usage
        // clear the map again for the next usage
        mTmpChildOrderMap.clear();
        mTmpChildOrderMap.clear();
@@ -274,6 +278,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
    private void addNotificationChildrenAndSort() {
    private void addNotificationChildrenAndSort() {
        // Let's now add all notification children which are missing
        // Let's now add all notification children which are missing
        boolean orderChanged = false;
        boolean orderChanged = false;
        ArrayList<ExpandableNotificationRow> orderedRows = new ArrayList<>();
        for (int i = 0; i < mListContainer.getContainerChildCount(); i++) {
        for (int i = 0; i < mListContainer.getContainerChildCount(); i++) {
            View view = mListContainer.getContainerChildAt(i);
            View view = mListContainer.getContainerChildAt(i);
            if (!(view instanceof ExpandableNotificationRow)) {
            if (!(view instanceof ExpandableNotificationRow)) {
@@ -283,11 +288,11 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle


            ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
            ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
            List<ExpandableNotificationRow> children = parent.getNotificationChildren();
            List<ExpandableNotificationRow> children = parent.getNotificationChildren();
            List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
            List<NotificationEntry> orderedChildren = mTmpChildOrderMap.get(parent.getEntry());


            for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
            for (int childIndex = 0; orderedChildren != null && childIndex < orderedChildren.size();
                    childIndex++) {
                    childIndex++) {
                ExpandableNotificationRow childView = orderedChildren.get(childIndex);
                ExpandableNotificationRow childView = orderedChildren.get(childIndex).getRow();
                if (children == null || !children.contains(childView)) {
                if (children == null || !children.contains(childView)) {
                    if (childView.getParent() != null) {
                    if (childView.getParent() != null) {
                        Log.wtf(TAG, "trying to add a notification child that already has " +
                        Log.wtf(TAG, "trying to add a notification child that already has " +
@@ -300,11 +305,13 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
                    parent.addChildNotification(childView, childIndex);
                    parent.addChildNotification(childView, childIndex);
                    mListContainer.notifyGroupChildAdded(childView);
                    mListContainer.notifyGroupChildAdded(childView);
                }
                }
                orderedRows.add(childView);
            }
            }


            // Finally after removing and adding has been performed we can apply the order.
            // Finally after removing and adding has been performed we can apply the order.
            orderChanged |= parent.applyChildOrder(orderedChildren, mVisualStabilityManager,
            orderChanged |= parent.applyChildOrder(orderedRows, mVisualStabilityManager,
                    mEntryManager);
                    mEntryManager);
            orderedRows.clear();
        }
        }
        if (orderChanged) {
        if (orderChanged) {
            mListContainer.generateChildOrderChangedEvent();
            mListContainer.generateChildOrderChangedEvent();
@@ -323,13 +330,13 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle


            ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
            ExpandableNotificationRow parent = (ExpandableNotificationRow) view;
            List<ExpandableNotificationRow> children = parent.getNotificationChildren();
            List<ExpandableNotificationRow> children = parent.getNotificationChildren();
            List<ExpandableNotificationRow> orderedChildren = mTmpChildOrderMap.get(parent);
            List<NotificationEntry> orderedChildren = mTmpChildOrderMap.get(parent.getEntry());


            if (children != null) {
            if (children != null) {
                toRemove.clear();
                toRemove.clear();
                for (ExpandableNotificationRow childRow : children) {
                for (ExpandableNotificationRow childRow : children) {
                    if ((orderedChildren == null
                    if ((orderedChildren == null
                            || !orderedChildren.contains(childRow))
                            || !orderedChildren.contains(childRow.getEntry()))
                            && !childRow.keepInParent()) {
                            && !childRow.keepInParent()) {
                        toRemove.add(childRow);
                        toRemove.add(childRow);
                    }
                    }
+5 −2
Original line number Original line Diff line number Diff line
@@ -32,6 +32,7 @@ import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.DynamicChildBindController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
@@ -138,7 +139,8 @@ public interface StatusBarDependenciesModule {
            KeyguardBypassController bypassController,
            KeyguardBypassController bypassController,
            BubbleController bubbleController,
            BubbleController bubbleController,
            DynamicPrivacyController privacyController,
            DynamicPrivacyController privacyController,
            ForegroundServiceSectionController fgsSectionController) {
            ForegroundServiceSectionController fgsSectionController,
            DynamicChildBindController dynamicChildBindController) {
        return new NotificationViewHierarchyManager(
        return new NotificationViewHierarchyManager(
                context,
                context,
                mainHandler,
                mainHandler,
@@ -150,7 +152,8 @@ public interface StatusBarDependenciesModule {
                bypassController,
                bypassController,
                bubbleController,
                bubbleController,
                privacyController,
                privacyController,
                fgsSectionController);
                fgsSectionController,
                dynamicChildBindController);
    }
    }


    /**
    /**
+118 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2019 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 static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;

import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.RowContentBindParams;
import com.android.systemui.statusbar.notification.row.RowContentBindStage;

import java.util.List;
import java.util.Map;

import javax.inject.Inject;

/**
 * Controller that binds/unbinds views content views on notification group children.
 *
 * We currently only show a limited number of notification children even if more exist, so we
 * can save memory by freeing content views when they're not visible and binding them again when
 * they get close to being visible.
 *
 * Eventually, when {@link NotifPipeline} takes over as the new notification pipeline, we'll have
 * more control over which notifications even make it to inflation in the first place and be able
 * to enforce this at an earlier stage at the level of the {@link ExpandableNotificationRow}, but
 * for now, we're just doing it at the level of content views.
 */
public class DynamicChildBindController {
    private final RowContentBindStage mStage;
    private final int mChildBindCutoff;

    @Inject
    public DynamicChildBindController(RowContentBindStage stage) {
        this(stage, CHILD_BIND_CUTOFF);
    }

    /**
     * @param childBindCutoff the cutoff where we no longer bother having content views bound
     */
    DynamicChildBindController(
            RowContentBindStage stage,
            int childBindCutoff) {
        mStage = stage;
        mChildBindCutoff = childBindCutoff;
    }

    /**
     * Update the child content views, unbinding content views on children that won't be visible
     * and binding content views on children that will be visible eventually.
     *
     * @param groupNotifs map of notification summaries to their children
     */
    public void updateChildContentViews(
            Map<NotificationEntry, List<NotificationEntry>> groupNotifs) {
        for (NotificationEntry entry : groupNotifs.keySet()) {
            List<NotificationEntry> children = groupNotifs.get(entry);
            for (int j = 0; j < children.size(); j++) {
                NotificationEntry childEntry = children.get(j);
                if (j >= mChildBindCutoff) {
                    if (hasChildContent(childEntry)) {
                        freeChildContent(childEntry);
                    }
                } else {
                    if (!hasChildContent(childEntry)) {
                        bindChildContent(childEntry);
                    }
                }
            }
        }
    }

    private boolean hasChildContent(NotificationEntry entry) {
        ExpandableNotificationRow row = entry.getRow();
        return row.getPrivateLayout().getContractedChild() != null
                || row.getPrivateLayout().getExpandedChild() != null;
    }

    private void freeChildContent(NotificationEntry entry) {
        RowContentBindParams params = mStage.getStageParams(entry);
        params.freeContentViews(FLAG_CONTENT_VIEW_CONTRACTED);
        params.freeContentViews(FLAG_CONTENT_VIEW_EXPANDED);
        mStage.requestRebind(entry, null);
    }

    private void bindChildContent(NotificationEntry entry) {
        RowContentBindParams params = mStage.getStageParams(entry);
        params.requireContentViews(FLAG_CONTENT_VIEW_CONTRACTED);
        params.requireContentViews(FLAG_CONTENT_VIEW_EXPANDED);
        mStage.requestRebind(entry, null);
    }

    /**
     * How big the buffer of extra views we keep around to be ready to show when we do need to
     * dynamically inflate.
     */
    private static final int EXTRA_VIEW_BUFFER_COUNT = 1;

    private static final int CHILD_BIND_CUTOFF =
            NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED + EXTRA_VIEW_BUFFER_COUNT;
}
+11 −0
Original line number Original line Diff line number Diff line
@@ -18,7 +18,10 @@ package com.android.systemui.statusbar.notification.row;


import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_HEADS_UP;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;
import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_PUBLIC;


@@ -467,6 +470,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
            }
            }
        };
        };
        switch (inflationFlag) {
        switch (inflationFlag) {
            case FLAG_CONTENT_VIEW_CONTRACTED:
                getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_CONTRACTED,
                        freeViewRunnable);
                break;
            case FLAG_CONTENT_VIEW_EXPANDED:
                getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_EXPANDED,
                        freeViewRunnable);
                break;
            case FLAG_CONTENT_VIEW_HEADS_UP:
            case FLAG_CONTENT_VIEW_HEADS_UP:
                getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_HEADSUP,
                getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_HEADSUP,
                        freeViewRunnable);
                        freeViewRunnable);
+13 −2
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.row;


import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;


import android.annotation.NonNull;
import android.annotation.NonNull;
@@ -191,6 +192,18 @@ public class NotificationContentInflater implements NotificationRowContentBinder
    private void freeNotificationView(NotificationEntry entry, ExpandableNotificationRow row,
    private void freeNotificationView(NotificationEntry entry, ExpandableNotificationRow row,
            @InflationFlag int inflateFlag) {
            @InflationFlag int inflateFlag) {
        switch (inflateFlag) {
        switch (inflateFlag) {
            case FLAG_CONTENT_VIEW_CONTRACTED:
                if (row.getPrivateLayout().isContentViewInactive(VISIBLE_TYPE_CONTRACTED)) {
                    row.getPrivateLayout().setContractedChild(null);
                    mRemoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_CONTRACTED);
                }
                break;
            case FLAG_CONTENT_VIEW_EXPANDED:
                if (row.getPrivateLayout().isContentViewInactive(VISIBLE_TYPE_EXPANDED)) {
                    row.getPrivateLayout().setExpandedChild(null);
                    mRemoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_EXPANDED);
                }
                break;
            case FLAG_CONTENT_VIEW_HEADS_UP:
            case FLAG_CONTENT_VIEW_HEADS_UP:
                if (row.getPrivateLayout().isContentViewInactive(VISIBLE_TYPE_HEADSUP)) {
                if (row.getPrivateLayout().isContentViewInactive(VISIBLE_TYPE_HEADSUP)) {
                    row.getPrivateLayout().setHeadsUpChild(null);
                    row.getPrivateLayout().setHeadsUpChild(null);
@@ -204,8 +217,6 @@ public class NotificationContentInflater implements NotificationRowContentBinder
                    mRemoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_PUBLIC);
                    mRemoteViewCache.removeCachedView(entry, FLAG_CONTENT_VIEW_PUBLIC);
                }
                }
                break;
                break;
            case FLAG_CONTENT_VIEW_CONTRACTED:
            case FLAG_CONTENT_VIEW_EXPANDED:
            default:
            default:
                break;
                break;
        }
        }
Loading