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

Commit efbf3c9e authored by Shivangi Dubey's avatar Shivangi Dubey Committed by Android (Google) Code Review
Browse files

Merge "Disabled SUBPIXEL_TEXT_FLAG for notification shade while fold unfold" into udc-dev

parents 56fc7e54 32de1c94
Loading
Loading
Loading
Loading
+84 −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.shared.animation

import android.graphics.Paint
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.forEach
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.util.traceSection
import java.lang.ref.WeakReference

/**
 * A listener which disables subpixel flag for all TextView children of a given parent ViewGroup
 * during fold/unfold transitions.
 */
class DisableSubpixelTextTransitionListener(private val rootView: ViewGroup?) :
        TransitionProgressListener {
    private val childrenTextViews: MutableList<WeakReference<TextView>> = mutableListOf()
    private var isTransitionInProgress: Boolean = false

    override fun onTransitionStarted() {
        isTransitionInProgress = true
        traceSection("subpixelFlagSetForTextView") {
            traceSection("subpixelFlagTraverseHierarchy") {
                getAllChildTextView(rootView, childrenTextViews)
            }
            traceSection("subpixelFlagDisableForTextView") {
                childrenTextViews.forEach { child ->
                    val childTextView = child.get() ?: return@forEach
                    childTextView.paintFlags = childTextView.paintFlags or Paint.SUBPIXEL_TEXT_FLAG
                }
            }
        }
    }

    override fun onTransitionFinished() {
        if (!isTransitionInProgress) return
        isTransitionInProgress = false
        traceSection("subpixelFlagEnableForTextView") {
            childrenTextViews.forEach { child ->
                val childTextView = child.get() ?: return@forEach
                childTextView.paintFlags =
                        childTextView.paintFlags and Paint.SUBPIXEL_TEXT_FLAG.inv()
            }
            childrenTextViews.clear()
        }
    }

    /**
     * Populates a list of all TextView children of a given parent ViewGroup
     *
     * @param parent the root ViewGroup for which to retrieve TextView children
     * @param childrenTextViews the list to store the retrieved TextView children
     */
    private fun getAllChildTextView(
            parent: ViewGroup?,
            childrenTextViews: MutableList<WeakReference<TextView>>
    ) {
        parent?.forEach { child ->
            when (child) {
                is ViewGroup -> getAllChildTextView(child, childrenTextViews)
                is TextView -> {
                    if ((child.paintFlags and Paint.SUBPIXEL_TEXT_FLAG) <= 0) {
                        childrenTextViews.add(WeakReference(child))
                    }
                }
            }
        }
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -700,6 +700,11 @@ object Flags {
    val ADVANCED_VPN_ENABLED = releasedFlag(2800, name = "AdvancedVpn__enable_feature",
            namespace = "vpn")

    // TODO(b/277201412): Tracking Bug
    @JvmField
    val SPLIT_SHADE_SUBPIXEL_OPTIMIZATION =
            unreleasedFlag(2805, "split_shade_subpixel_optimization", teamfood = true)

    // TODO(b/278761837): Tracking Bug
    @JvmField
    val USE_NEW_ACTIVITY_STARTER = releasedFlag(2801, name = "use_new_activity_starter")
+11 −1
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransition
import com.android.systemui.multishade.domain.interactor.MultiShadeInteractor;
import com.android.systemui.multishade.domain.interactor.MultiShadeMotionEventInteractor;
import com.android.systemui.multishade.ui.view.MultiShadeView;
import com.android.systemui.shared.animation.DisableSubpixelTextTransitionListener;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationInsetsController;
@@ -68,9 +69,11 @@ import com.android.systemui.statusbar.phone.PhoneStatusBarViewController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
import com.android.systemui.util.time.SystemClock;

import java.io.PrintWriter;
import java.util.Optional;
import java.util.function.Consumer;

import javax.inject.Inject;
@@ -114,7 +117,7 @@ public class NotificationShadeWindowViewController {

    private boolean mIsTrackingBarGesture = false;
    private boolean mIsOcclusionTransitionRunning = false;

    private DisableSubpixelTextTransitionListener mDisableSubpixelTextTransitionListener;
    private final Consumer<TransitionStep> mLockscreenToDreamingTransition =
            (TransitionStep step) -> {
                mIsOcclusionTransitionRunning =
@@ -139,6 +142,7 @@ public class NotificationShadeWindowViewController {
            LockIconViewController lockIconViewController,
            CentralSurfaces centralSurfaces,
            NotificationShadeWindowController controller,
            Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider,
            KeyguardUnlockAnimationController keyguardUnlockAnimationController,
            NotificationInsetsController notificationInsetsController,
            AmbientState ambientState,
@@ -174,6 +178,7 @@ public class NotificationShadeWindowViewController {

        // This view is not part of the newly inflated expanded status bar.
        mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
        mDisableSubpixelTextTransitionListener = new DisableSubpixelTextTransitionListener(mView);
        KeyguardBouncerViewBinder.bind(
                mView.findViewById(R.id.keyguard_bouncer_container),
                keyguardBouncerViewModel,
@@ -184,6 +189,11 @@ public class NotificationShadeWindowViewController {
                mLockscreenToDreamingTransition);

        mClock = clock;
        if (featureFlags.isEnabled(Flags.SPLIT_SHADE_SUBPIXEL_OPTIMIZATION)) {
            unfoldTransitionProgressProvider.ifPresent(
                    progressProvider -> progressProvider.addCallback(
                            mDisableSubpixelTextTransitionListener));
        }
        if (ComposeFacade.INSTANCE.isComposeAvailable()
                && featureFlags.isEnabled(Flags.DUAL_SHADE)) {
            mMultiShadeMotionEventInteractor = multiShadeMotionEventInteractorProvider.get();
+6 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.PhoneStatusBarViewController
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.window.StatusBarWindowStateController
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
import com.android.systemui.util.mockito.any
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -71,6 +72,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
import java.util.Optional

@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@@ -101,6 +103,8 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
    @Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
    @Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
    @Mock lateinit var keyguardSecurityContainerController: KeyguardSecurityContainerController
    @Mock
    private lateinit var unfoldTransitionProgressProvider: Optional<UnfoldTransitionProgressProvider>
    @Mock lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
    @Mock
    lateinit var primaryBouncerToGoneTransitionViewModel: PrimaryBouncerToGoneTransitionViewModel
@@ -129,6 +133,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
        featureFlags.set(Flags.TRACKPAD_GESTURE_COMMON, true)
        featureFlags.set(Flags.TRACKPAD_GESTURE_FEATURES, false)
        featureFlags.set(Flags.DUAL_SHADE, false)
        featureFlags.set(Flags.SPLIT_SHADE_SUBPIXEL_OPTIMIZATION, true)

        val inputProxy = MultiShadeInputProxy()
        testScope = TestScope()
@@ -158,6 +163,7 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
                lockIconViewController,
                centralSurfaces,
                notificationShadeWindowController,
                unfoldTransitionProgressProvider,
                keyguardUnlockAnimationController,
                notificationInsetsController,
                ambientState,
Loading