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

Commit 0f770e6d authored by Orhan Uysal's avatar Orhan Uysal
Browse files

Use the userId to create context.

When a profile app is dragged to desktop and we try to launch the home
using the id of the profile, pm resolves this intent as using a work
profile app outside of work profile thus launches as a secondary
activtiy during drag to desktop which crashes the system.

Instead of using the profileId of the task, we can get the user that
profile belongs to and use the userId of that user instead to launch the
home task.

Bug: 394020242
Test: Use drag to desktop on work profile app in non-HSUM and verify no
crashes
Test: Use drag to desktop on any app in HSUM and verify no crashes
Flag: EXEMPT Bugfix

Change-Id: I7638c16ab848310e9c18d43c809f286b45ad6c19
parent af9d3ada
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ import dagger.Binds;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;

import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.ExperimentalCoroutinesApi;
import kotlinx.coroutines.MainCoroutineDispatcher;
@@ -913,12 +914,15 @@ public abstract class WMShellModule {
            Context context,
            Transitions transitions,
            RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
            @DynamicOverride DesktopUserRepositories desktopUserRepositories,
            InteractionJankMonitor interactionJankMonitor) {
        return ENABLE_DESKTOP_WINDOWING_ENTER_TRANSITIONS_BUGFIX.isTrue()
                ? new SpringDragToDesktopTransitionHandler(
                        context, transitions, rootTaskDisplayAreaOrganizer, interactionJankMonitor)
                context, transitions, rootTaskDisplayAreaOrganizer, desktopUserRepositories,
                interactionJankMonitor)
                : new DefaultDragToDesktopTransitionHandler(
                        context, transitions, rootTaskDisplayAreaOrganizer, interactionJankMonitor);
                        context, transitions, rootTaskDisplayAreaOrganizer, desktopUserRepositories,
                        interactionJankMonitor);
    }

    @WMSingleton
+5 −0
Original line number Diff line number Diff line
@@ -90,6 +90,11 @@ class DesktopUserRepositories(
        return desktopRepoByUserId.getOrCreate(profileId)
    }

    fun getUserIdForProfile(profileId: Int): Int {
        if (userIdToProfileIdsMap[userId]?.contains(profileId) == true) return userId
        else return profileId
    }

    /** Dumps [DesktopRepository] for each user. */
    fun dump(pw: PrintWriter, prefix: String) {
        desktopRepoByUserId.forEach { key, value ->
+11 −3
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ sealed class DragToDesktopTransitionHandler(
    private val context: Context,
    private val transitions: Transitions,
    private val taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
    private val desktopUserRepositories: DesktopUserRepositories,
    protected val interactionJankMonitor: InteractionJankMonitor,
    protected val transactionSupplier: Supplier<SurfaceControl.Transaction>,
) : TransitionHandler {
@@ -127,15 +128,18 @@ sealed class DragToDesktopTransitionHandler(
                pendingIntentCreatorBackgroundActivityStartMode =
                    ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
            }
        val taskUser = UserHandle.of(taskInfo.userId)
        // If we are launching home for a profile of a user, just use the [userId] of that user
        // instead of the [profileId] to create the context.
        val userToLaunchWith =
            UserHandle.of(desktopUserRepositories.getUserIdForProfile(taskInfo.userId))
        val pendingIntent =
            PendingIntent.getActivityAsUser(
                context.createContextAsUser(taskUser, /* flags= */ 0),
                context.createContextAsUser(userToLaunchWith, /* flags= */ 0),
                /* requestCode= */ 0,
                launchHomeIntent,
                FLAG_MUTABLE or FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT or FILL_IN_COMPONENT,
                options.toBundle(),
                taskUser,
                userToLaunchWith,
            )
        val wct = WindowContainerTransaction()
        // The app that is being dragged into desktop mode might cause new transitions, make this
@@ -881,6 +885,7 @@ constructor(
    context: Context,
    transitions: Transitions,
    taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
    desktopUserRepositories: DesktopUserRepositories,
    interactionJankMonitor: InteractionJankMonitor,
    transactionSupplier: Supplier<SurfaceControl.Transaction> = Supplier {
        SurfaceControl.Transaction()
@@ -890,6 +895,7 @@ constructor(
        context,
        transitions,
        taskDisplayAreaOrganizer,
        desktopUserRepositories,
        interactionJankMonitor,
        transactionSupplier,
    ) {
@@ -917,6 +923,7 @@ constructor(
    context: Context,
    transitions: Transitions,
    taskDisplayAreaOrganizer: RootTaskDisplayAreaOrganizer,
    desktopUserRepositories: DesktopUserRepositories,
    interactionJankMonitor: InteractionJankMonitor,
    transactionSupplier: Supplier<SurfaceControl.Transaction> = Supplier {
        SurfaceControl.Transaction()
@@ -926,6 +933,7 @@ constructor(
        context,
        transitions,
        taskDisplayAreaOrganizer,
        desktopUserRepositories,
        interactionJankMonitor,
        transactionSupplier,
    ) {
+18 −0
Original line number Diff line number Diff line
@@ -123,8 +123,26 @@ class DesktopUserRepositoriesTest : ShellTestCase() {
        assertThat(desktopRepository.userId).isEqualTo(PROFILE_ID_2)
    }

    @Test
    @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_HSUM)
    fun getUserForProfile_flagEnabled_returnsUserIdForProfile() {
        userRepositories.onUserChanged(USER_ID_2, mock())
        val profiles: MutableList<UserInfo> =
            mutableListOf(
                UserInfo(USER_ID_2, "User profile", 0),
                UserInfo(PROFILE_ID_1, "Work profile", 0),
            )
        userRepositories.onUserProfilesChanged(profiles)

        val userIdForProfile = userRepositories.getUserIdForProfile(PROFILE_ID_1)

        assertThat(userIdForProfile).isEqualTo(USER_ID_2)
    }

    private companion object {
        const val USER_ID_1 = 7
        const val USER_ID_2 = 8
        const val PROFILE_ID_1 = 4
        const val PROFILE_ID_2 = 5
    }
}
+22 −12
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
    @Mock private lateinit var mockInteractionJankMonitor: InteractionJankMonitor
    @Mock private lateinit var draggedTaskLeash: SurfaceControl
    @Mock private lateinit var homeTaskLeash: SurfaceControl
    @Mock private lateinit var desktopUserRepositories: DesktopUserRepositories

    private val transactionSupplier = Supplier { mock<SurfaceControl.Transaction>() }

@@ -84,6 +85,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
                    context,
                    transitions,
                    taskDisplayAreaOrganizer,
                    desktopUserRepositories,
                    mockInteractionJankMonitor,
                    transactionSupplier,
                )
@@ -93,6 +95,7 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
                    context,
                    transitions,
                    taskDisplayAreaOrganizer,
                    desktopUserRepositories,
                    mockInteractionJankMonitor,
                    transactionSupplier,
                )
@@ -484,8 +487,13 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
        val mergedFinishTransaction = mock<SurfaceControl.Transaction>()
        val finishCallback = mock<Transitions.TransitionFinishCallback>()
        val task = createTask()
        val startTransition = startDrag(
            springHandler, task, finishTransaction = playingFinishTransaction, homeChange = null)
        val startTransition =
            startDrag(
                springHandler,
                task,
                finishTransaction = playingFinishTransaction,
                homeChange = null,
            )
        springHandler.onTaskResizeAnimationListener = mock()

        springHandler.mergeAnimation(
@@ -723,7 +731,8 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
    private fun createTransitionInfo(
        type: Int,
        draggedTask: RunningTaskInfo,
        homeChange: TransitionInfo.Change? = createHomeChange()) =
        homeChange: TransitionInfo.Change? = createHomeChange(),
    ) =
        TransitionInfo(type, /* flags= */ 0).apply {
            homeChange?.let { addChange(it) }
            addChange( // Dragged Task.
@@ -741,7 +750,8 @@ class DragToDesktopTransitionHandlerTest : ShellTestCase() {
            )
        }

    private fun createHomeChange() = TransitionInfo.Change(mock(), homeTaskLeash).apply {
    private fun createHomeChange() =
        TransitionInfo.Change(mock(), homeTaskLeash).apply {
            parent = null
            taskInfo = TestRunningTaskInfoBuilder().setActivityType(ACTIVITY_TYPE_HOME).build()
            flags = flags or FLAG_IS_WALLPAPER