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

Commit 6b45c741 authored by Yasin Kilicdere's avatar Yasin Kilicdere
Browse files

Call onBeforeUserSwitching event in callbacks' executor.

In SystemUI.UserTrackerImpl, onBeforeUserSwitching is called in the
current thread, not in the callback's executor. This causes a FATAL
exception in SystemUI process in this flow:

1. UserTrackerImpl.onBeforeUserSwitching
2. UserTrackerImpl.handleBeforeUserSwitching
	Assert.isNotMainThread()
3. NotificationShadeWindowControllerImpl.onBeforeUserSwitching
4. NotificationShadeWindowControllerImpl.setIsSwitchingUsers
5. NotificationShadeWindowControllerImpl.apply
6. NotificationShadeWindowControllerImpl.notifyStateChangedCallbacks
7. SystemActions.onStateChanged
8. SystemActions.registerOrUnregisterDismissNotificationShadeAction
	Assert.isMainThread();

This two asserts contradict with each other since the callback is
called on the same thread, but it should be in the given executor.

This CL fixes this issue.

Bug: 326068767
Test: None
Flag: None
Change-Id: I7a494f741218bebdd52f19feafdf8f9f30ada920
parent e8dbefd4
Loading
Loading
Loading
Loading
+12 −11
Original line number Diff line number Diff line
@@ -121,7 +121,6 @@ open class UserTrackerImpl internal constructor(
    @GuardedBy("callbacks")
    private val callbacks: MutableList<DataItem> = ArrayList()

    private var beforeUserSwitchingJob: Job? = null
    private var userSwitchingJob: Job? = null
    private var afterUserSwitchingJob: Job? = null

@@ -194,15 +193,8 @@ open class UserTrackerImpl internal constructor(
    private fun registerUserSwitchObserver() {
        iActivityManager.registerUserSwitchObserver(object : UserSwitchObserver() {
            override fun onBeforeUserSwitching(newUserId: Int) {
                if (isBackgroundUserSwitchEnabled) {
                    beforeUserSwitchingJob?.cancel()
                    beforeUserSwitchingJob = appScope.launch(backgroundContext) {
                        handleBeforeUserSwitching(newUserId)
                    }
                } else {
                handleBeforeUserSwitching(newUserId)
            }
            }

            override fun onUserSwitching(newUserId: Int, reply: IRemoteCallback?) {
                if (isBackgroundUserSwitchEnabled) {
@@ -233,16 +225,25 @@ open class UserTrackerImpl internal constructor(

    @WorkerThread
    protected open fun handleBeforeUserSwitching(newUserId: Int) {
        Assert.isNotMainThread()
        setUserIdInternal(newUserId)

        val list = synchronized(callbacks) {
            callbacks.toList()
        }
        val latch = CountDownLatch(list.size)
        list.forEach {
            it.callback.get()?.onBeforeUserSwitching(newUserId)
            val callback = it.callback.get()
            if (callback != null) {
                it.executor.execute {
                    callback.onBeforeUserSwitching(newUserId)
                    latch.countDown()
                }
            } else {
                latch.countDown()
            }
        }
        latch.await()
    }

    @WorkerThread
    protected open fun handleUserSwitching(newUserId: Int) {
+0 −1
Original line number Diff line number Diff line
@@ -371,7 +371,6 @@ class UserTrackerImplTest : SysuiTestCase() {

        val captor = ArgumentCaptor.forClass(IUserSwitchObserver::class.java)
        verify(iActivityManager).registerUserSwitchObserver(capture(captor), anyString())
        captor.value.onBeforeUserSwitching(newID)
        captor.value.onUserSwitching(newID, userSwitchingReply)

        assertThat(callback.calledOnUserChanging).isEqualTo(0)