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

Commit a987ab28 authored by Steve Elliott's avatar Steve Elliott Committed by Android (Google) Code Review
Browse files

Merge "ViewModel+Binder for NotificationStackScrollLayout" into udc-dev

parents e0d73107 84989e0a
Loading
Loading
Loading
Loading
+23 −42
Original line number Diff line number Diff line
@@ -33,12 +33,9 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.phone.NotificationIconAreaController
import com.android.systemui.statusbar.phone.NotificationIconContainer
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
import com.android.systemui.util.kotlin.getValue
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch

/**
 * Controller class for [NotificationShelf]. This implementation serves as a temporary wrapper
@@ -47,39 +44,12 @@ import kotlinx.coroutines.flow.onEach
 * removed, this class can go away and the ViewBinder can be used directly.
 */
@CentralSurfacesScope
class NotificationShelfViewBinderWrapperControllerImpl
@Inject
constructor(
    private val shelf: NotificationShelf,
    private val viewModel: NotificationShelfViewModel,
    featureFlags: FeatureFlags,
    private val falsingManager: FalsingManager,
    hostControllerLazy: Lazy<NotificationStackScrollLayoutController>,
    private val notificationIconAreaController: NotificationIconAreaController,
) : NotificationShelfController {

    private val hostController: NotificationStackScrollLayoutController by hostControllerLazy
class NotificationShelfViewBinderWrapperControllerImpl @Inject constructor() :
    NotificationShelfController {

    override val view: NotificationShelf
        get() = unsupported

    init {
        shelf.apply {
            setRefactorFlagEnabled(featureFlags.isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR))
            useRoundnessSourceTypes(featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES))
            setSensitiveRevealAnimEndabled(featureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM))
        }
    }

    fun init() {
        NotificationShelfViewBinder.bind(viewModel, shelf, falsingManager)
        hostController.setShelf(shelf)
        hostController.setOnNotificationRemovedListener { child, _ ->
            view.requestRoundnessResetFor(child)
        }
        notificationIconAreaController.setShelfIcons(shelf.shelfIcons)
    }

    override val intrinsicHeight: Int
        get() = unsupported

@@ -99,24 +69,35 @@ constructor(
        get() = NotificationShelfController.throwIllegalFlagStateError(expected = true)
}

/** Binds a [NotificationShelf] to its backend. */
/** Binds a [NotificationShelf] to its [view model][NotificationShelfViewModel]. */
object NotificationShelfViewBinder {
    fun bind(
        viewModel: NotificationShelfViewModel,
        shelf: NotificationShelf,
        viewModel: NotificationShelfViewModel,
        falsingManager: FalsingManager,
        featureFlags: FeatureFlags,
        notificationIconAreaController: NotificationIconAreaController,
    ) {
        ActivatableNotificationViewBinder.bind(viewModel, shelf, falsingManager)
        shelf.repeatWhenAttached {
        shelf.apply {
            setRefactorFlagEnabled(true)
            useRoundnessSourceTypes(featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES))
            setSensitiveRevealAnimEndabled(featureFlags.isEnabled(Flags.SENSITIVE_REVEAL_ANIM))
            // TODO(278765923): Replace with eventual NotificationIconContainerViewBinder#bind()
            notificationIconAreaController.setShelfIcons(shelfIcons)
            repeatWhenAttached {
                repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.canModifyColorOfNotifications
                    .onEach(shelf::setCanModifyColorOfNotifications)
                    .launchIn(this)
                viewModel.isClickable.onEach(shelf::setCanInteract).launchIn(this)
                    launch {
                        viewModel.canModifyColorOfNotifications.collect(
                            ::setCanModifyColorOfNotifications
                        )
                    }
                    launch { viewModel.isClickable.collect(::setCanInteract) }
                    registerViewListenersWhileAttached(shelf, viewModel)
                }
            }
        }
    }

    private suspend fun registerViewListenersWhileAttached(
        shelf: NotificationShelf,
+9 −4
Original line number Diff line number Diff line
@@ -2839,6 +2839,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
     * @param listener callback for notification removed
     */
    public void setOnNotificationRemovedListener(OnNotificationRemovedListener listener) {
        NotificationShelfController.assertRefactorFlagDisabled(mAmbientState.getFeatureFlags());
        mOnNotificationRemovedListener = listener;
    }

@@ -2852,12 +2853,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
        if (!mChildTransferInProgress) {
            onViewRemovedInternal(expandableView, this);
        }
        if (mAmbientState.getFeatureFlags().isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR)) {
            mShelf.requestRoundnessResetFor(expandableView);
        } else {
            if (mOnNotificationRemovedListener != null) {
                mOnNotificationRemovedListener.onNotificationRemoved(
                        expandableView,
                        mChildTransferInProgress);
            }
        }
    }

    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
    public void cleanUpViewStateForEntry(NotificationEntry entry) {
+18 −2
Original line number Diff line number Diff line
@@ -105,11 +105,14 @@ import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.NotificationGuts;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.NotificationSnooze;
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.NotificationListViewBinder;
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModel;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -122,16 +125,17 @@ import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.Compile;
import com.android.systemui.util.settings.SecureSettings;

import kotlin.Unit;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

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

import kotlin.Unit;

/**
 * Controller for {@link NotificationStackScrollLayout}.
 */
@@ -151,6 +155,8 @@ public class NotificationStackScrollLayoutController {
    private final ConfigurationController mConfigurationController;
    private final ZenModeController mZenModeController;
    private final MetricsLogger mMetricsLogger;
    private final Optional<NotificationListViewModel> mViewModel;

    private final DumpManager mDumpManager;
    private final FalsingCollector mFalsingCollector;
    private final FalsingManager mFalsingManager;
@@ -175,6 +181,8 @@ public class NotificationStackScrollLayoutController {
    private final NotificationStackSizeCalculator mNotificationStackSizeCalculator;
    private final StackStateLogger mStackStateLogger;
    private final NotificationStackScrollLogger mLogger;
    private final NotificationIconAreaController mNotifIconAreaController;

    private final GroupExpansionManager mGroupExpansionManager;
    private final NotifPipelineFlags mNotifPipelineFlags;
    private final SeenNotificationsProvider mSeenNotificationsProvider;
@@ -642,6 +650,7 @@ public class NotificationStackScrollLayoutController {
            KeyguardBypassController keyguardBypassController,
            ZenModeController zenModeController,
            NotificationLockscreenUserManager lockscreenUserManager,
            Optional<NotificationListViewModel> nsslViewModel,
            MetricsLogger metricsLogger,
            DumpManager dumpManager,
            FalsingCollector falsingCollector,
@@ -665,6 +674,7 @@ public class NotificationStackScrollLayoutController {
            StackStateLogger stackLogger,
            NotificationStackScrollLogger logger,
            NotificationStackSizeCalculator notificationStackSizeCalculator,
            NotificationIconAreaController notifIconAreaController,
            FeatureFlags featureFlags,
            NotificationTargetsHelper notificationTargetsHelper,
            SecureSettings secureSettings,
@@ -686,6 +696,7 @@ public class NotificationStackScrollLayoutController {
        mKeyguardBypassController = keyguardBypassController;
        mZenModeController = zenModeController;
        mLockscreenUserManager = lockscreenUserManager;
        mViewModel = nsslViewModel;
        mMetricsLogger = metricsLogger;
        mDumpManager = dumpManager;
        mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
@@ -707,6 +718,7 @@ public class NotificationStackScrollLayoutController {
        mVisibilityLocationProviderDelegator = visibilityLocationProviderDelegator;
        mSeenNotificationsProvider = seenNotificationsProvider;
        mShadeController = shadeController;
        mNotifIconAreaController = notifIconAreaController;
        mFeatureFlags = featureFlags;
        mUseRoundnessSourceTypes = featureFlags.isEnabled(Flags.USE_ROUNDNESS_SOURCETYPES);
        mNotificationTargetsHelper = notificationTargetsHelper;
@@ -820,6 +832,10 @@ public class NotificationStackScrollLayoutController {

        mGroupExpansionManager.registerGroupExpansionChangeListener(
                (changedRow, expanded) -> mView.onGroupExpandChanged(changedRow, expanded));

        mViewModel.ifPresent(
                vm -> NotificationListViewBinder
                        .bind(mView, vm, mFalsingManager, mFeatureFlags, mNotifIconAreaController));
    }

    private boolean isInVisibleLocation(NotificationEntry entry) {
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.stack.ui.viewbinder

import android.view.LayoutInflater
import com.android.systemui.R
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.NotificationShelf
import com.android.systemui.statusbar.notification.shelf.ui.viewbinder.NotificationShelfViewBinder
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationListViewModel
import com.android.systemui.statusbar.phone.NotificationIconAreaController

/** Binds a [NotificationStackScrollLayout] to its [view model][NotificationListViewModel]. */
object NotificationListViewBinder {
    @JvmStatic
    fun bind(
        view: NotificationStackScrollLayout,
        viewModel: NotificationListViewModel,
        falsingManager: FalsingManager,
        featureFlags: FeatureFlags,
        iconAreaController: NotificationIconAreaController,
    ) {
        val shelf =
            LayoutInflater.from(view.context)
                .inflate(R.layout.status_bar_notification_shelf, view, false) as NotificationShelf
        NotificationShelfViewBinder.bind(
            shelf,
            viewModel.shelf,
            falsingManager,
            featureFlags,
            iconAreaController
        )
        view.setShelf(shelf)
    }
}
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.stack.ui.viewmodel

import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.NotificationShelfViewModel
import dagger.Module
import dagger.Provides
import java.util.Optional
import javax.inject.Provider

/** ViewModel for the list of notifications. */
class NotificationListViewModel(
    val shelf: NotificationShelfViewModel,
)

@Module
object NotificationListViewModelModule {
    @JvmStatic
    @Provides
    fun maybeProvideViewModel(
        featureFlags: FeatureFlags,
        shelfViewModel: Provider<NotificationShelfViewModel>,
    ): Optional<NotificationListViewModel> =
        if (featureFlags.isEnabled(Flags.NOTIFICATION_SHELF_REFACTOR)) {
            Optional.of(NotificationListViewModel(shelfViewModel.get()))
        } else {
            Optional.empty()
        }
}
Loading