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

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

Merge "Remove Controller usage from NotificationShelf" into udc-dev

parents ce3bd36b 3f3c6244
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -92,6 +92,9 @@ interface DeviceEntryFaceAuthRepository {
    /** Current state of whether face authentication is running. */
    val isAuthRunning: Flow<Boolean>

    /** Whether bypass is currently enabled */
    val isBypassEnabled: Flow<Boolean>

    /**
     * Trigger face authentication.
     *
@@ -166,7 +169,7 @@ constructor(
    override val isAuthenticated: Flow<Boolean>
        get() = _isAuthenticated

    private val bypassEnabled: Flow<Boolean> =
    override val isBypassEnabled: Flow<Boolean> =
        keyguardBypassController?.let {
            conflatedCallbackFlow {
                val callback =
@@ -222,7 +225,7 @@ constructor(
        // & detection is supported & biometric unlock is not allowed.
        listOf(
                canFaceAuthOrDetectRun(),
                logAndObserve(bypassEnabled, "bypassEnabled"),
                logAndObserve(isBypassEnabled, "isBypassEnabled"),
                logAndObserve(
                    biometricSettingsRepository.isNonStrongBiometricAllowed.isFalse(),
                    "nonStrongBiometricIsNotAllowed"
+37 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.res.Resources;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MathUtils;
import android.view.View;
import android.view.ViewGroup;
@@ -96,6 +97,8 @@ public class NotificationShelf extends ActivatableNotificationView implements St
    private NotificationShelfController mController;
    private float mActualWidth = -1;
    private boolean mSensitiveRevealAnimEndabled;
    private boolean mShelfRefactorFlagEnabled;
    private boolean mCanModifyColorOfNotifications;

    public NotificationShelf(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -425,7 +428,7 @@ public class NotificationShelf extends ActivatableNotificationView implements St
                    transitionAmount = inShelfAmount;
                }
                // We don't want to modify the color if the notification is hun'd
                if (isLastChild && mController.canModifyColorOfNotifications()) {
                if (isLastChild && canModifyColorOfNotifications()) {
                    if (colorOfViewBeforeLast == NO_COLOR) {
                        colorOfViewBeforeLast = ownColorUntinted;
                    }
@@ -490,6 +493,14 @@ public class NotificationShelf extends ActivatableNotificationView implements St
        }
    }

    private boolean canModifyColorOfNotifications() {
        if (mShelfRefactorFlagEnabled) {
            return mCanModifyColorOfNotifications && mAmbientState.isShadeExpanded();
        } else {
            return mController.canModifyColorOfNotifications();
        }
    }

    private void updateCornerRoundnessOnScroll(
            ActivatableNotificationView anv,
            float viewStart,
@@ -959,10 +970,31 @@ public class NotificationShelf extends ActivatableNotificationView implements St
        return false;
    }

    private void assertRefactorFlagDisabled() {
        if (mShelfRefactorFlagEnabled) {
            throw new IllegalStateException(
                    "Code path not supported when Flags.NOTIFICATION_SHELF_REFACTOR is enabled.");
        }
    }

    private boolean checkRefactorFlagEnabled() {
        if (!mShelfRefactorFlagEnabled) {
            Log.wtf(TAG,
                    "Code path not supported when Flags.NOTIFICATION_SHELF_REFACTOR is disabled.");
        }
        return mShelfRefactorFlagEnabled;
    }

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

    public void setCanModifyColorOfNotifications(boolean canModifyColorOfNotifications) {
        if (!checkRefactorFlagEnabled()) return;
        mCanModifyColorOfNotifications = canModifyColorOfNotifications;
    }

    public void setIndexOfFirstViewInShelf(ExpandableView firstViewInShelf) {
        mIndexOfFirstViewInShelf = mHostLayoutController.indexOfChild(firstViewInShelf);
    }
@@ -975,6 +1007,10 @@ public class NotificationShelf extends ActivatableNotificationView implements St
        mSensitiveRevealAnimEndabled = enabled;
    }

    public void setRefactorFlagEnabled(boolean enabled) {
        mShelfRefactorFlagEnabled = enabled;
    }

    /**
     * This method resets the OnScroll roundness of a view to 0f
     * <p>
+44 −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.shelf.domain.interactor

import com.android.systemui.keyguard.data.repository.DeviceEntryFaceAuthRepository
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.statusbar.NotificationShelf
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine

/** Interactor for the [NotificationShelf] */
@CentralSurfacesComponent.CentralSurfacesScope
class NotificationShelfInteractor
@Inject
constructor(
    private val keyguardRepository: KeyguardRepository,
    private val deviceEntryFaceAuthRepository: DeviceEntryFaceAuthRepository,
) {
    /** Is the system in a state where the shelf is just a static display of notification icons? */
    val isShelfStatic: Flow<Boolean>
        get() =
            combine(
                keyguardRepository.isKeyguardShowing,
                deviceEntryFaceAuthRepository.isBypassEnabled,
            ) { isKeyguardShowing, isBypassEnabled ->
                isKeyguardShowing && isBypassEnabled
            }
}
+25 −30
Original line number Diff line number Diff line
@@ -14,14 +14,17 @@
 * limitations under the License.
 */

package com.android.systemui.statusbar.notification.shelf.view
package com.android.systemui.statusbar.notification.shelf.ui.viewbinder

import android.view.View
import android.view.View.OnAttachStateChangeListener
import android.view.accessibility.AccessibilityManager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.LegacyNotificationShelfControllerImpl
import com.android.systemui.statusbar.NotificationShelf
@@ -31,21 +34,16 @@ import com.android.systemui.statusbar.notification.row.ActivatableNotificationVi
import com.android.systemui.statusbar.notification.row.ActivatableNotificationViewController
import com.android.systemui.statusbar.notification.row.ExpandableOutlineViewController
import com.android.systemui.statusbar.notification.row.ExpandableViewController
import com.android.systemui.statusbar.notification.shelf.ui.viewmodel.NotificationShelfViewModel
import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.NotificationIconContainer
import com.android.systemui.statusbar.phone.NotificationTapHelper
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
import dagger.Binds
import dagger.Module
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import javax.inject.Inject

/** Binds a [NotificationShelf] to its backend. */
interface NotificationShelfViewBinder {
    fun bind(shelf: NotificationShelf)
}

/**
 * Controller class for [NotificationShelf]. This implementation serves as a temporary wrapper
 * around a [NotificationShelfViewBinder], so that external code can continue to depend on the
@@ -57,8 +55,7 @@ class NotificationShelfViewBinderWrapperControllerImpl
@Inject
constructor(
    private val shelf: NotificationShelf,
    private val viewBinder: NotificationShelfViewBinder,
    private val keyguardBypassController: KeyguardBypassController,
    private val viewModel: NotificationShelfViewModel,
    featureFlags: FeatureFlags,
    private val notifTapHelperFactory: NotificationTapHelper.Factory,
    private val a11yManager: AccessibilityManager,
@@ -67,20 +64,19 @@ constructor(
    private val statusBarStateController: SysuiStatusBarStateController,
) : NotificationShelfController {

    private var ambientState: AmbientState? = null

    override val view: NotificationShelf
        get() = shelf

    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() {
        viewBinder.bind(shelf)
        NotificationShelfViewBinder.bind(viewModel, shelf)

        ActivatableNotificationViewController(
                shelf,
@@ -91,7 +87,6 @@ constructor(
                falsingCollector,
            )
            .init()
        shelf.setController(this)
        val onAttachStateListener =
            object : OnAttachStateChangeListener {
                override fun onViewAttachedToWindow(v: View) {
@@ -117,10 +112,7 @@ constructor(
    override val shelfIcons: NotificationIconContainer
        get() = shelf.shelfIcons

    override fun canModifyColorOfNotifications(): Boolean {
        return (ambientState?.isShadeExpanded == true &&
            !(ambientState?.isOnKeyguard == true && keyguardBypassController.bypassEnabled))
    }
    override fun canModifyColorOfNotifications(): Boolean = unsupported

    override fun setOnActivatedListener(listener: ActivatableNotificationView.OnActivatedListener) {
        shelf.setOnActivatedListener(listener)
@@ -128,25 +120,28 @@ constructor(

    override fun bind(
        ambientState: AmbientState,
        notificationStackScrollLayoutController: NotificationStackScrollLayoutController
        notificationStackScrollLayoutController: NotificationStackScrollLayoutController,
    ) {
        shelf.bind(ambientState, notificationStackScrollLayoutController)
        this.ambientState = ambientState
    }

    override fun setOnClickListener(listener: View.OnClickListener) {
        shelf.setOnClickListener(listener)
    }
}

@Module(includes = [PrivateShelfViewBinderModule::class]) object NotificationShelfViewBinderModule

@Module
private interface PrivateShelfViewBinderModule {
    @Binds fun bindImpl(impl: NotificationShelfViewBinderImpl): NotificationShelfViewBinder
    private val unsupported: Nothing
        get() = error("Code path not supported when Flags.NOTIFICATION_SHELF_REFACTOR is enabled")
}

@CentralSurfacesScope
private class NotificationShelfViewBinderImpl @Inject constructor() : NotificationShelfViewBinder {
    override fun bind(shelf: NotificationShelf) {}
/** Binds a [NotificationShelf] to its backend. */
object NotificationShelfViewBinder {
    fun bind(viewModel: NotificationShelfViewModel, shelf: NotificationShelf) {
        shelf.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.canModifyColorOfNotifications
                    .onEach(shelf::setCanModifyColorOfNotifications)
                    .launchIn(this)
            }
        }
    }
}
+36 −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.shelf.ui.viewmodel

import com.android.systemui.statusbar.NotificationShelf
import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

/** ViewModel for [NotificationShelf]. */
@CentralSurfacesScope
class NotificationShelfViewModel
@Inject
constructor(
    private val interactor: NotificationShelfInteractor,
) {
    /** Is the shelf allowed to modify the color of notifications in the host layout? */
    val canModifyColorOfNotifications: Flow<Boolean>
        get() = interactor.isShelfStatic.map { static -> !static }
}
Loading