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

Commit 6eb322c3 authored by Yasin Kilicdere's avatar Yasin Kilicdere Committed by Android (Google) Code Review
Browse files

Merge "Make UserTrackerImpl use UserSwitchObserver instead of broadcast."

parents 53031674 f5c2a526
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -62,12 +62,24 @@ interface UserTracker : UserContentResolverProvider, UserContextProvider {
    fun removeCallback(callback: Callback)

    /**
     * Ćallback for notifying of changes.
     * Callback for notifying of changes.
     */
    interface Callback {

        /**
         * Notifies that the current user is being changed.
         * Override this method to run things while the screen is frozen for the user switch.
         * Please use {@link #onUserChanged} if the task doesn't need to push the unfreezing of the
         * screen further. Please be aware that code executed in this callback will lengthen the
         * user switch duration.
         */
        @JvmDefault
        fun onUserChanging(newUser: Int, userContext: Context) {}

        /**
         * Notifies that the current user has changed.
         * Override this method to run things after the screen is unfrozen for the user switch.
         * Please see {@link #onUserChanging} if you need to hide jank.
         */
        @JvmDefault
        fun onUserChanged(newUser: Int, userContext: Context) {}
+48 −16
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.settings

import android.app.IActivityManager
import android.app.UserSwitchObserver
import android.content.BroadcastReceiver
import android.content.ContentResolver
import android.content.Context
@@ -23,6 +25,7 @@ import android.content.Intent
import android.content.IntentFilter
import android.content.pm.UserInfo
import android.os.Handler
import android.os.IRemoteCallback
import android.os.UserHandle
import android.os.UserManager
import android.util.Log
@@ -33,6 +36,7 @@ import com.android.systemui.dump.DumpManager
import com.android.systemui.util.Assert
import java.io.PrintWriter
import java.lang.ref.WeakReference
import java.util.concurrent.CountDownLatch
import java.util.concurrent.Executor
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
@@ -55,6 +59,7 @@ import kotlin.reflect.KProperty
open class UserTrackerImpl internal constructor(
    private val context: Context,
    private val userManager: UserManager,
    private val iActivityManager: IActivityManager,
    private val dumpManager: DumpManager,
    private val backgroundHandler: Handler
) : UserTracker, Dumpable, BroadcastReceiver() {
@@ -106,7 +111,6 @@ open class UserTrackerImpl internal constructor(
        setUserIdInternal(startingUser)

        val filter = IntentFilter().apply {
            addAction(Intent.ACTION_USER_SWITCHED)
            addAction(Intent.ACTION_USER_INFO_CHANGED)
            // These get called when a managed profile goes in or out of quiet mode.
            addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE)
@@ -117,14 +121,13 @@ open class UserTrackerImpl internal constructor(
        }
        context.registerReceiverForAllUsers(this, filter, null /* permission */, backgroundHandler)

        registerUserSwitchObserver()

        dumpManager.registerDumpable(TAG, this)
    }

    override fun onReceive(context: Context, intent: Intent) {
        when (intent.action) {
            Intent.ACTION_USER_SWITCHED -> {
                handleSwitchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL))
            }
            Intent.ACTION_USER_INFO_CHANGED,
            Intent.ACTION_MANAGED_PROFILE_AVAILABLE,
            Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE,
@@ -156,22 +159,43 @@ open class UserTrackerImpl internal constructor(
        return ctx to profiles
    }

    private fun registerUserSwitchObserver() {
        iActivityManager.registerUserSwitchObserver(object : UserSwitchObserver() {
            override fun onUserSwitching(newUserId: Int, reply: IRemoteCallback?) {
                backgroundHandler.run {
                    handleUserSwitching(newUserId)
                    reply?.sendResult(null)
                }
            }

            override fun onUserSwitchComplete(newUserId: Int) {
                backgroundHandler.run {
                    handleUserSwitchComplete(newUserId)
                }
            }
        }, TAG)
    }

    @WorkerThread
    protected open fun handleSwitchUser(newUser: Int) {
    protected open fun handleUserSwitching(newUserId: Int) {
        Assert.isNotMainThread()
        if (newUser == UserHandle.USER_NULL) {
            Log.w(TAG, "handleSwitchUser - Couldn't get new id from intent")
            return
        }
        Log.i(TAG, "Switching to user $newUserId")

        if (newUser == userId) return
        Log.i(TAG, "Switching to user $newUser")
        setUserIdInternal(newUserId)
        notifySubscribers {
            onUserChanging(newUserId, userContext)
        }.await()
    }

        val (ctx, profiles) = setUserIdInternal(newUser)
    @WorkerThread
    protected open fun handleUserSwitchComplete(newUserId: Int) {
        Assert.isNotMainThread()
        Log.i(TAG, "Switched to user $newUserId")

        setUserIdInternal(newUserId)
        notifySubscribers {
            onUserChanged(newUser, ctx)
            onProfilesChanged(profiles)
            onUserChanged(newUserId, userContext)
            onProfilesChanged(userProfiles)
        }
    }

@@ -200,17 +224,25 @@ open class UserTrackerImpl internal constructor(
        }
    }

    private inline fun notifySubscribers(crossinline action: UserTracker.Callback.() -> Unit) {
    private inline fun notifySubscribers(
            crossinline action: UserTracker.Callback.() -> Unit
    ): CountDownLatch {
        val list = synchronized(callbacks) {
            callbacks.toList()
        }
        val latch = CountDownLatch(list.size)

        list.forEach {
            if (it.callback.get() != null) {
                it.executor.execute {
                    it.callback.get()?.action()
                    latch.countDown()
                }
            } else {
                latch.countDown()
            }
        }
        return latch
    }

    override fun dump(pw: PrintWriter, args: Array<out String>) {
+4 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.settings.dagger;

import android.app.ActivityManager;
import android.app.IActivityManager;
import android.content.Context;
import android.os.Handler;
import android.os.UserManager;
@@ -57,11 +58,13 @@ public abstract class MultiUserUtilsModule {
    static UserTracker provideUserTracker(
            Context context,
            UserManager userManager,
            IActivityManager iActivityManager,
            DumpManager dumpManager,
            @Background Handler handler
    ) {
        int startingUser = ActivityManager.getCurrentUser();
        UserTrackerImpl tracker = new UserTrackerImpl(context, userManager, dumpManager, handler);
        UserTrackerImpl tracker = new UserTrackerImpl(context, userManager, iActivityManager,
                dumpManager, handler);
        tracker.initialize(startingUser);
        return tracker;
    }
+1 −1
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ constructor(

                val callback =
                    object : UserTracker.Callback {
                        override fun onUserChanged(newUser: Int, userContext: Context) {
                        override fun onUserChanging(newUser: Int, userContext: Context) {
                            send()
                        }

+3 −1
Original line number Diff line number Diff line
package com.android.systemui.settings

import android.app.IActivityManager
import android.content.Context
import android.content.Intent
import android.content.pm.UserInfo
@@ -51,6 +52,7 @@ class UserTrackerImplReceiveTest : SysuiTestCase() {

    @Mock private lateinit var context: Context
    @Mock private lateinit var userManager: UserManager
    @Mock private lateinit var iActivityManager: IActivityManager
    @Mock(stubOnly = true) private lateinit var dumpManager: DumpManager
    @Mock(stubOnly = true) private lateinit var handler: Handler

@@ -67,7 +69,7 @@ class UserTrackerImplReceiveTest : SysuiTestCase() {
        `when`(context.user).thenReturn(UserHandle.SYSTEM)
        `when`(context.createContextAsUser(ArgumentMatchers.any(), anyInt())).thenReturn(context)

        tracker = UserTrackerImpl(context, userManager, dumpManager, handler)
        tracker = UserTrackerImpl(context, userManager, iActivityManager, dumpManager, handler)
    }

    @Test
Loading