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

Commit 3fac1f33 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[SB Refactor] Add logs for view creation and collection.

In the linked bug, it appears as though the MobileIconViewModel has the
correct information but that information isn't being displayed in the
UI. This CL adds some logs around view binding and view updating to
determine at what point viewModel <--> UI the updates are lost.

Bug: 267236367
Test: `adb shell dumpsys activity service
com.android.systemui/.SystemUIService MobileViewLog` -> shows collection
start/stop logs
Test: `adb shell dumpsys activity service
com.android.systemui/.SystemUIService MobileViewLogger` -> shows current
collection status
Test: atest MobileViewLoggerTest

Change-Id: Ic63ada059e82fd06932c8ec076b532228f839ebd
parent 416bbd90
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import com.android.systemui.statusbar.StatusIconDisplayable;
import com.android.systemui.statusbar.connectivity.ui.MobileContextProvider;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState;
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger;
import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView;
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel;
import com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView;
@@ -288,10 +289,14 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da
     * @param mobileContext possibly mcc/mnc overridden mobile context
     * @param subId the subscriptionId for this mobile view
     */
    public void addModernMobileView(Context mobileContext, int subId) {
    public void addModernMobileView(
            Context mobileContext,
            MobileViewLogger mobileViewLogger,
            int subId) {
        Log.d(TAG, "addModernMobileView (subId=" + subId + ")");
        ModernStatusBarMobileView view = ModernStatusBarMobileView.constructAndBind(
                mobileContext,
                mobileViewLogger,
                "mobile",
                mMobileIconsViewModel.viewModelForSub(subId, mLocation)
        );
+5 −1
Original line number Diff line number Diff line
@@ -569,7 +569,10 @@ public interface StatusBarIconController {
            mGroup.addView(view, index, onCreateLayoutParams());

            if (mIsInDemoMode) {
                mDemoStatusIcons.addModernMobileView(mContext, subId);
                mDemoStatusIcons.addModernMobileView(
                        mContext,
                        mMobileIconsViewModel.getLogger(),
                        subId);
            }

            return view;
@@ -601,6 +604,7 @@ public interface StatusBarIconController {
            return ModernStatusBarMobileView
                    .constructAndBind(
                            mobileContext,
                            mMobileIconsViewModel.getLogger(),
                            slot,
                            mMobileIconsViewModel.viewModelForSub(subId, mLocation)
                        );
+71 −2
Original line number Diff line number Diff line
@@ -17,17 +17,30 @@
package com.android.systemui.statusbar.pipeline.mobile.ui

import android.view.View
import androidx.annotation.VisibleForTesting
import com.android.systemui.Dumpable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogLevel
import com.android.systemui.statusbar.pipeline.dagger.MobileViewLog
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
import java.io.PrintWriter
import javax.inject.Inject

/** Logs for changes with the new mobile views. */
@SysUISingleton
class MobileViewLogger @Inject constructor(
class MobileViewLogger
@Inject
constructor(
    @MobileViewLog private val buffer: LogBuffer,
) {
    dumpManager: DumpManager,
) : Dumpable {
    init {
        dumpManager.registerNormalDumpable(this)
    }

    private val collectionStatuses = mutableMapOf<String, Boolean>()

    fun logUiAdapterSubIdsUpdated(subs: List<Int>) {
        buffer.log(
@@ -46,6 +59,62 @@ class MobileViewLogger @Inject constructor(
            { "Sub IDs in MobileUiAdapter being sent to icon controller: $str1" },
        )
    }

    fun logNewViewBinding(view: View, viewModel: LocationBasedMobileViewModel) {
        buffer.log(
            TAG,
            LogLevel.INFO,
            {
                str1 = view.getIdForLogging()
                str2 = viewModel.getIdForLogging()
                str3 = viewModel.locationName
            },
            { "New view binding. viewId=$str1, viewModelId=$str2, viewModelLocation=$str3" },
        )
    }

    fun logCollectionStarted(view: View, viewModel: LocationBasedMobileViewModel) {
        collectionStatuses[view.getIdForLogging()] = true
        buffer.log(
            TAG,
            LogLevel.INFO,
            {
                str1 = view.getIdForLogging()
                str2 = viewModel.getIdForLogging()
                str3 = viewModel.locationName
            },
            { "Collection started. viewId=$str1, viewModelId=$str2, viewModelLocation=$str3" },
        )
    }

    fun logCollectionStopped(view: View, viewModel: LocationBasedMobileViewModel) {
        collectionStatuses[view.getIdForLogging()] = false
        buffer.log(
            TAG,
            LogLevel.INFO,
            {
                str1 = view.getIdForLogging()
                str2 = viewModel.getIdForLogging()
                str3 = viewModel.locationName
            },
            { "Collection stopped. viewId=$str1, viewModelId=$str2, viewModelLocation=$str3" },
        )
    }

    override fun dump(pw: PrintWriter, args: Array<out String>) {
        pw.println("Collection statuses per view:---")
        collectionStatuses.forEach { viewId, isCollecting ->
            pw.println("viewId=$viewId, isCollecting=$isCollecting")
        }
    }

    companion object {
        @VisibleForTesting
        internal fun Any.getIdForLogging(): String {
            // The identityHashCode is guaranteed to be constant for the lifetime of the object.
            return Integer.toHexString(System.identityHashCode(this))
        }
    }
}

private const val TAG = "MobileViewLogger"
+19 −0
Original line number Diff line number Diff line
@@ -36,8 +36,10 @@ import com.android.systemui.statusbar.StatusBarIconView
import com.android.systemui.statusbar.StatusBarIconView.STATE_DOT
import com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN
import com.android.systemui.statusbar.StatusBarIconView.STATE_ICON
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
@@ -48,6 +50,7 @@ object MobileIconBinder {
    fun bind(
        view: ViewGroup,
        viewModel: LocationBasedMobileViewModel,
        logger: MobileViewLogger,
    ): ModernStatusBarViewBinding {
        val mobileGroupView = view.requireViewById<ViewGroup>(R.id.mobile_group)
        val activityContainer = view.requireViewById<View>(R.id.inout_container)
@@ -70,8 +73,13 @@ object MobileIconBinder {
        val iconTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)
        val decorTint: MutableStateFlow<Int> = MutableStateFlow(viewModel.defaultColor)

        var isCollecting: Boolean = false

        view.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                logger.logCollectionStarted(view, viewModel)
                isCollecting = true

                launch {
                    visibilityState.collect { state ->
                        when (state) {
@@ -150,6 +158,13 @@ object MobileIconBinder {
                }

                launch { decorTint.collect { tint -> dotView.setDecorColor(tint) } }

                try {
                    awaitCancellation()
                } finally {
                    isCollecting = false
                    logger.logCollectionStopped(view, viewModel)
                }
            }
        }

@@ -175,6 +190,10 @@ object MobileIconBinder {
                }
                decorTint.value = newTint
            }

            override fun isCollecting(): Boolean {
                return isCollecting
            }
        }
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import com.android.systemui.R
import com.android.systemui.statusbar.StatusBarIconView.getVisibleStateString
import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
import com.android.systemui.statusbar.pipeline.mobile.ui.binder.MobileIconBinder
import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.LocationBasedMobileViewModel
import com.android.systemui.statusbar.pipeline.shared.ui.view.ModernStatusBarView
@@ -36,6 +37,7 @@ class ModernStatusBarMobileView(
        return "ModernStatusBarMobileView(" +
            "slot='$slot', " +
            "subId=$subId, " +
            "isCollecting=${binding.isCollecting()}, " +
            "visibleState=${getVisibleStateString(visibleState)}); " +
            "viewString=${super.toString()}"
    }
@@ -49,6 +51,7 @@ class ModernStatusBarMobileView(
        @JvmStatic
        fun constructAndBind(
            context: Context,
            logger: MobileViewLogger,
            slot: String,
            viewModel: LocationBasedMobileViewModel,
        ): ModernStatusBarMobileView {
@@ -57,7 +60,8 @@ class ModernStatusBarMobileView(
                    as ModernStatusBarMobileView)
                .also {
                    it.subId = viewModel.subscriptionId
                    it.initView(slot) { MobileIconBinder.bind(it, viewModel) }
                    it.initView(slot) { MobileIconBinder.bind(it, viewModel, logger) }
                    logger.logNewViewBinding(it, viewModel)
                }
        }
    }
Loading