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

Commit f152f9d2 authored by Dave Mankoff's avatar Dave Mankoff Committed by Steve Elliott
Browse files

Add NotificationShelfController.

This moves injection from NotificationShelf into its controller,
creating a subcomponent for the view.

This is a relatively light-weight version of this change. Very little
logic is actually moved into the controller, with a handful of public
methods on the controller simply acting as proxies to the view for
now.

Bug: 147245740
Test: manual && atest SystemUITests
Change-Id: Ic74dc6a2ef83bcc2e1a86080d77b156b2b3e8c15
parent 18c3a478
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.Notifica
import com.android.systemui.statusbar.notification.people.PeopleHubModule;
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
@@ -72,7 +73,8 @@ import dagger.Provides;
        subcomponents = {StatusBarComponent.class,
                NotificationRowComponent.class,
                DozeComponent.class,
                ExpandableNotificationRowComponent.class})
                ExpandableNotificationRowComponent.class,
                NotificationShelfComponent.class})
public abstract class SystemUIModule {

    @Binds
+7 −39
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar;

import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE;
import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;

import android.content.Context;
import android.content.res.Configuration;
@@ -26,7 +25,6 @@ import android.content.res.Resources;
import android.graphics.Rect;
import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
import android.view.DisplayCutout;
import android.view.View;
@@ -36,10 +34,8 @@ import android.view.WindowInsets;
import android.view.accessibility.AccessibilityNodeInfo;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -50,12 +46,8 @@ import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.ViewState;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationIconContainer;

import javax.inject.Inject;
import javax.inject.Named;

/**
 * A notification shelf view that is placed inside the notification scroller. It manages the
 * overflow icons that don't fit into the regular list anymore.
@@ -69,7 +61,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
            = SystemProperties.getBoolean("debug.icon_scroll_animations", true);
    private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag;
    private static final String TAG = "NotificationShelf";
    private final KeyguardBypassController mBypassController;

    private NotificationIconContainer mShelfIcons;
    private int[] mTmp = new int[2];
@@ -77,7 +68,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
    private int mIconAppearTopPadding;
    private float mHiddenShelfIconSize;
    private int mStatusBarHeight;
    private int mStatusBarPaddingStart;
    private AmbientState mAmbientState;
    private NotificationStackScrollLayout mHostLayout;
    private int mMaxLayoutHeight;
@@ -88,7 +78,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
    private int mScrollFastThreshold;
    private int mIconSize;
    private int mStatusBarState;
    private float mMaxShelfEnd;
    private int mRelativeOffset;
    private boolean mInteractive;
    private float mOpenedAmount;
@@ -99,13 +88,10 @@ public class NotificationShelf extends ActivatableNotificationView implements
    private Rect mClipRect = new Rect();
    private int mCutoutHeight;
    private int mGapHeight;
    private NotificationShelfController mController;

    @Inject
    public NotificationShelf(@Named(VIEW_CONTEXT) Context context,
            AttributeSet attrs,
            KeyguardBypassController keyguardBypassController) {
    public NotificationShelf(Context context, AttributeSet attrs) {
        super(context, attrs);
        mBypassController = keyguardBypassController;
    }

    @Override
@@ -128,19 +114,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
        initDimens();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
                .addCallback(this, SysuiStatusBarStateController.RANK_SHELF);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        Dependency.get(StatusBarStateController.class).removeCallback(this);
    }

    public void bind(AmbientState ambientState, NotificationStackScrollLayout hostLayout) {
        mAmbientState = ambientState;
        mHostLayout = hostLayout;
@@ -150,7 +123,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
        Resources res = getResources();
        mIconAppearTopPadding = res.getDimensionPixelSize(R.dimen.notification_icon_appear_padding);
        mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
        mStatusBarPaddingStart = res.getDimensionPixelOffset(R.dimen.status_bar_padding_start);
        mPaddingBetweenElements = res.getDimensionPixelSize(R.dimen.notification_divider_height);

        ViewGroup.LayoutParams layoutParams = getLayoutParams();
@@ -315,9 +287,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
                    transitionAmount = inShelfAmount;
                }
                // We don't want to modify the color if the notification is hun'd
                boolean canModifyColor = mAmbientState.isShadeExpanded()
                        && !(mAmbientState.isOnKeyguard() && mBypassController.getBypassEnabled());
                if (isLastChild && canModifyColor) {
                if (isLastChild && mController.canModifyColorOfNotifications()) {
                    if (colorOfViewBeforeLast == NO_COLOR) {
                        colorOfViewBeforeLast = ownColorUntinted;
                    }
@@ -999,10 +969,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
        return mInteractive;
    }

    public void setMaxShelfEnd(float maxShelfEnd) {
        mMaxShelfEnd = maxShelfEnd;
    }

    public void setAnimationsEnabled(boolean enabled) {
        mAnimationsEnabled = enabled;
        if (!enabled) {
@@ -1044,6 +1010,10 @@ public class NotificationShelf extends ActivatableNotificationView implements
        updateBackgroundColors();
    }

    public void setController(NotificationShelfController notificationShelfController) {
        mController = notificationShelfController;
    }

    private class ShelfState extends ExpandableViewState {
        private float openedAmount;
        private boolean hasItemsInStableShelf;
@@ -1056,7 +1026,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
            }

            super.applyToView(view);
            setMaxShelfEnd(maxShelfEnd);
            setOpenedAmount(openedAmount);
            updateAppearance();
            setHasItemsInStableShelf(hasItemsInStableShelf);
@@ -1070,7 +1039,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
            }

            super.animateTo(child, properties);
            setMaxShelfEnd(maxShelfEnd);
            setOpenedAmount(openedAmount);
            updateAppearance();
            setHasItemsInStableShelf(hasItemsInStableShelf);
+122 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar;

import android.view.View;

import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
import com.android.systemui.statusbar.notification.stack.AmbientState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationIconContainer;
import com.android.systemui.statusbar.phone.StatusBarNotificationPresenter;

import javax.inject.Inject;

/**
 * Controller class for {@link NotificationShelf}.
 */
@NotificationRowScope
public class NotificationShelfController {
    private final NotificationShelf mView;
    private final ActivatableNotificationViewController mActivatableNotificationViewController;
    private final KeyguardBypassController mKeyguardBypassController;
    private final SysuiStatusBarStateController mStatusBarStateController;
    private final View.OnAttachStateChangeListener mOnAttachStateChangeListener;
    private AmbientState mAmbientState;

    @Inject
    public NotificationShelfController(NotificationShelf notificationShelf,
            ActivatableNotificationViewController activatableNotificationViewController,
            KeyguardBypassController keyguardBypassController,
            SysuiStatusBarStateController statusBarStateController) {
        mView = notificationShelf;
        mActivatableNotificationViewController = activatableNotificationViewController;
        mKeyguardBypassController = keyguardBypassController;
        mStatusBarStateController = statusBarStateController;
        mOnAttachStateChangeListener = new View.OnAttachStateChangeListener() {
            @Override
            public void onViewAttachedToWindow(View v) {
                mStatusBarStateController.addCallback(
                        mView, SysuiStatusBarStateController.RANK_SHELF);
            }

            @Override
            public void onViewDetachedFromWindow(View v) {
                mStatusBarStateController.removeCallback(mView);
            }
        };
    }

    public void init() {
        mActivatableNotificationViewController.init();
        mView.setController(this);
        mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
        if (mView.isAttachedToWindow()) {
            mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
        }
    }

    public NotificationShelf getView() {
        return mView;
    }

    public boolean canModifyColorOfNotifications() {
        return mAmbientState.isShadeExpanded()
                && !(mAmbientState.isOnKeyguard() && mKeyguardBypassController.getBypassEnabled());
    }

    public NotificationIconContainer getShelfIcons() {
        return mView.getShelfIcons();
    }

    public void setCollapsedIcons(NotificationIconContainer notificationIcons) {
        mView.setCollapsedIcons(notificationIcons);
    }

    public void bind(AmbientState ambientState,
            NotificationStackScrollLayout notificationStackScrollLayout) {
        mView.bind(ambientState, notificationStackScrollLayout);
        mAmbientState = ambientState;
    }

    public int getHeight() {
        return mView.getHeight();
    }

    public void updateState(AmbientState ambientState) {
        mAmbientState = ambientState;
        mView.updateState(ambientState);
    }

    public int getIntrinsicHeight() {
        return mView.getIntrinsicHeight();
    }

    public void setOnActivatedListener(StatusBarNotificationPresenter presenter) {
        mView.setOnActivatedListener(presenter);
    }

    public void setOnClickListener(View.OnClickListener onClickListener) {
        mView.setOnClickListener(onClickListener);
    }

    public int getNotGoneIndex() {
        return mView.getNotGoneIndex();
    }
}
+20 −18
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ import android.view.LayoutInflater;
import android.view.ViewGroup;

import com.android.systemui.R;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
import com.android.systemui.statusbar.notification.row.dagger.NotificationShelfComponent;
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.LockscreenLockIconController;
import com.android.systemui.statusbar.phone.NotificationPanelView;
@@ -41,22 +41,22 @@ public class SuperStatusBarViewFactory {

    private final Context mContext;
    private final InjectionInflationController mInjectionInflationController;
    private final NotificationRowComponent.Builder mNotificationRowComponentBuilder;
    private final LockscreenLockIconController mLockIconController;
    private final NotificationShelfComponent.Builder mNotificationShelfComponentBuilder;

    private NotificationShadeWindowView mNotificationShadeWindowView;
    private StatusBarWindowView mStatusBarWindowView;
    private NotificationShelf mNotificationShelf;
    private NotificationShelfController mNotificationShelfController;

    @Inject
    public SuperStatusBarViewFactory(Context context,
            InjectionInflationController injectionInflationController,
            NotificationRowComponent.Builder notificationRowComponentBuilder,
            NotificationShelfComponent.Builder notificationShelfComponentBuilder,
            LockscreenLockIconController lockIconController) {
        mContext = context;
        mInjectionInflationController = injectionInflationController;
        mNotificationRowComponentBuilder = notificationRowComponentBuilder;
        mLockIconController = lockIconController;
        mNotificationShelfComponentBuilder = notificationShelfComponentBuilder;
    }

    /**
@@ -114,25 +114,27 @@ public class SuperStatusBarViewFactory {
     *                  isn't immediately attached, but the layout params of this view is used
     *                  during inflation.
     */
    public NotificationShelf getNotificationShelf(ViewGroup container) {
        if (mNotificationShelf != null) {
            return mNotificationShelf;
    public NotificationShelfController getNotificationShelfController(ViewGroup container) {
        if (mNotificationShelfController != null) {
            return mNotificationShelfController;
        }

        mNotificationShelf = (NotificationShelf) mInjectionInflationController.injectable(
                LayoutInflater.from(mContext)).inflate(R.layout.status_bar_notification_shelf,
                container, /* attachToRoot= */ false);
        NotificationShelf view = (NotificationShelf) LayoutInflater.from(mContext)
                .inflate(R.layout.status_bar_notification_shelf, container, /* attachToRoot= */
                        false);

        NotificationRowComponent component = mNotificationRowComponentBuilder
                .activatableNotificationView(mNotificationShelf)
                .build();
        component.getActivatableNotificationViewController().init();

        if (mNotificationShelf == null) {
        if (view == null) {
            throw new IllegalStateException(
                    "R.layout.status_bar_notification_shelf could not be properly inflated");
        }
        return mNotificationShelf;

        NotificationShelfComponent component = mNotificationShelfComponentBuilder
                .notificationShelf(view)
                .build();
        mNotificationShelfController = component.getNotificationShelfController();
        mNotificationShelfController.init();

        return mNotificationShelfController;
    }

    public NotificationPanelView getNotificationPanelView() {
+60 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.statusbar.notification.row.dagger;

import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;

import dagger.Binds;
import dagger.BindsInstance;
import dagger.Module;
import dagger.Subcomponent;

/**
 * Dagger subcomponent for NotificationShelf.
 */
@Subcomponent(modules = {ActivatableNotificationViewModule.class,
        NotificationShelfComponent.NotificationShelfModule.class})
@NotificationRowScope
public interface NotificationShelfComponent {
    /**
     * Builder for {@link NotificationShelfComponent}.
     */
    @Subcomponent.Builder
    interface Builder {
        @BindsInstance
        Builder notificationShelf(NotificationShelf view);
        NotificationShelfComponent build();
    }

    /**
     * Creates a NotificationShelfController.
     */
    @NotificationRowScope
    NotificationShelfController getNotificationShelfController();
    /**
     * Dagger Module that extracts interesting properties from a NotificationShelf.
     */
    @Module
    abstract class NotificationShelfModule {

        /** NotificationShelf is provided as an instance of ActivatableNotificationView. */
        @Binds
        abstract ActivatableNotificationView bindNotificationShelf(NotificationShelf view);
    }
}
Loading