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

Commit 0b881acf authored by Joe Antonetti's avatar Joe Antonetti Committed by Android (Google) Code Review
Browse files

Merge "[Handoff][3/N] Serialize Handoff Enablement in RunningTaskFetcher" into main

parents e7aac2a6 b42916d3
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.content.Context;
import android.os.RemoteException;
import android.util.Slog;

import com.android.server.LocalServices;
import com.android.server.companion.datatransfer.continuity.connectivity.TaskContinuityMessenger;
import com.android.server.companion.datatransfer.continuity.messages.ContinuityDeviceConnected;
import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskAddedMessage;
@@ -32,6 +33,7 @@ import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskR
import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskUpdatedMessage;
import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskInfo;
import com.android.server.companion.datatransfer.continuity.tasks.RunningTaskFetcher;
import com.android.server.wm.ActivityTaskManagerInternal;

import java.util.List;
import java.util.Objects;
@@ -41,11 +43,13 @@ import java.util.Objects;
 *
 * other devices via {@link CompanionDeviceManager}.
 */
class TaskBroadcaster extends TaskStackListener {
class TaskBroadcaster
    extends TaskStackListener implements ActivityTaskManagerInternal.HandoffEnablementListener {

    private static final String TAG = "TaskBroadcaster";

    private final ActivityTaskManager mActivityTaskManager;
    private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
    private final TaskContinuityMessenger mTaskContinuityMessenger;
    private final RunningTaskFetcher mRunningTaskFetcher;

@@ -57,16 +61,19 @@ class TaskBroadcaster extends TaskStackListener {
        this(
            Objects.requireNonNull(taskContinuityMessenger),
            Objects.requireNonNull(context).getSystemService(ActivityTaskManager.class),
            Objects.requireNonNull(LocalServices.getService(ActivityTaskManagerInternal.class)),
            new RunningTaskFetcher(Objects.requireNonNull(context)));
    }

    public TaskBroadcaster(
        @NonNull TaskContinuityMessenger taskContinuityMessenger,
        @NonNull ActivityTaskManager activityTaskManager,
        @NonNull ActivityTaskManagerInternal activityTaskManagerInternal,
        @NonNull RunningTaskFetcher runningTaskFetcher) {

        mTaskContinuityMessenger = Objects.requireNonNull(taskContinuityMessenger);
        mActivityTaskManager = Objects.requireNonNull(activityTaskManager);
        mActivityTaskManagerInternal = Objects.requireNonNull(activityTaskManagerInternal);
        mRunningTaskFetcher = Objects.requireNonNull(runningTaskFetcher);
    }

@@ -79,6 +86,7 @@ class TaskBroadcaster extends TaskStackListener {
        synchronized (this) {
            if (!mIsListeningToActivityTaskManager) {
                mActivityTaskManager.registerTaskStackListener(this);
                mActivityTaskManagerInternal.registerHandoffEnablementListener(this);
                mIsListeningToActivityTaskManager = true;
            }
        }
@@ -88,6 +96,7 @@ class TaskBroadcaster extends TaskStackListener {
        synchronized (this) {
            if (mIsListeningToActivityTaskManager) {
                mActivityTaskManager.unregisterTaskStackListener(this);
                mActivityTaskManagerInternal.unregisterHandoffEnablementListener(this);
                mIsListeningToActivityTaskManager = false;
            }
        }
@@ -116,9 +125,21 @@ class TaskBroadcaster extends TaskStackListener {
    public void onTaskMovedToFront(RunningTaskInfo taskInfo) throws RemoteException {
        Slog.v(TAG, "onTaskMovedToFront: taskId=" + taskInfo.taskId);

        RemoteTaskInfo remoteTaskInfo = mRunningTaskFetcher.getRunningTaskById(taskInfo.taskId);
        sendTaskUpdatedMessage(taskInfo.taskId);
    }

    @Override
    public void onHandoffEnabledChanged(int taskId, boolean isHandoffEnabled) {
        Slog.v(TAG, "onHandoffEnabledChanged: taskId=" + taskId
                + ", isHandoffEnabled=" + isHandoffEnabled);

        sendTaskUpdatedMessage(taskId);
    }

    private void sendTaskUpdatedMessage(int taskId) {
        RemoteTaskInfo remoteTaskInfo = mRunningTaskFetcher.getRunningTaskById(taskId);
        if (remoteTaskInfo == null) {
            Slog.w(TAG, "Could not create RemoteTaskInfo for task: " + taskInfo.taskId);
            Slog.w(TAG, "Could not create RemoteTaskInfo for task: " + taskId);
            return;
        }

+10 −1
Original line number Diff line number Diff line
@@ -25,9 +25,11 @@ import android.content.Context;
import android.content.Intent;
import android.util.Slog;

import com.android.server.LocalServices;
import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskInfo;
import com.android.server.companion.datatransfer.continuity.tasks.PackageMetadata;
import com.android.server.companion.datatransfer.continuity.tasks.PackageMetadataCache;
import com.android.server.wm.ActivityTaskManagerInternal;

import java.util.ArrayList;
import java.util.List;
@@ -43,22 +45,26 @@ public class RunningTaskFetcher {
    private static final String TAG = "RunningTaskFetcher";

    private final ActivityTaskManager mActivityTaskManager;
    private final ActivityTaskManagerInternal mActivityTaskManagerInternal;
    private final PackageManager mPackageManager;
    private final PackageMetadataCache mPackageMetadataCache;

    public RunningTaskFetcher(@NonNull Context context) {
        this(
            Objects.requireNonNull(context).getSystemService(ActivityTaskManager.class),
            Objects.requireNonNull(LocalServices.getService(ActivityTaskManagerInternal.class)),
            Objects.requireNonNull(context).getPackageManager(),
            new PackageMetadataCache(Objects.requireNonNull(context).getPackageManager()));
    }

    public RunningTaskFetcher(
        @NonNull ActivityTaskManager activityTaskManager,
        @NonNull ActivityTaskManagerInternal activityTaskManagerInternal,
        @NonNull PackageManager packageManager,
        @NonNull PackageMetadataCache packageMetadataCache) {

        mActivityTaskManager = Objects.requireNonNull(activityTaskManager);
        mActivityTaskManagerInternal = Objects.requireNonNull(activityTaskManagerInternal);
        mPackageManager = Objects.requireNonNull(packageManager);
        mPackageMetadataCache = Objects.requireNonNull(packageMetadataCache);
    }
@@ -107,12 +113,15 @@ public class RunningTaskFetcher {
            return null;
        }

        boolean isHandoffEnabled
            = mActivityTaskManagerInternal.isHandoffEnabledForTask(taskInfo.taskId);

        return new RemoteTaskInfo(
            taskInfo.taskId,
            packageMetadata.label(),
            taskInfo.lastActiveTime,
            packageMetadata.icon(),
            false);
            isHandoffEnabled);
    }

    @NonNull
+30 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskI
import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskRemovedMessage;
import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskUpdatedMessage;
import com.android.server.companion.datatransfer.continuity.tasks.RunningTaskFetcher;
import com.android.server.wm.ActivityTaskManagerInternal;

import org.junit.Before;
import org.junit.Test;
@@ -54,6 +55,7 @@ import java.util.List;
public class TaskBroadcasterTest {

    @Mock private ActivityTaskManager mMockActivityTaskManager;
    @Mock private ActivityTaskManagerInternal mMockActivityTaskManagerInternal;
    @Mock private RunningTaskFetcher mMockRunningTaskFetcher;
    @Mock private TaskContinuityMessenger mMockTaskContinuityMessenger;

@@ -65,6 +67,7 @@ public class TaskBroadcasterTest {
        mTaskBroadcaster = new TaskBroadcaster(
            mMockTaskContinuityMessenger,
            mMockActivityTaskManager,
            mMockActivityTaskManagerInternal,
            mMockRunningTaskFetcher);
    }

@@ -72,6 +75,8 @@ public class TaskBroadcasterTest {
    public void testOnAllDevicesDisconnected_doesNothingIfNoDeviceConnected() {
        mTaskBroadcaster.onAllDevicesDisconnected();
        verify(mMockActivityTaskManager, never()).registerTaskStackListener(mTaskBroadcaster);
        verify(mMockActivityTaskManagerInternal, never())
            .registerHandoffEnablementListener(mTaskBroadcaster);
    }

    @Test
@@ -79,10 +84,14 @@ public class TaskBroadcasterTest {
        // Connect a device, verify the listener is registered.
        mTaskBroadcaster.onDeviceConnected(1);
        verify(mMockActivityTaskManager, times(1)).registerTaskStackListener(mTaskBroadcaster);
        verify(mMockActivityTaskManagerInternal, times(1))
            .registerHandoffEnablementListener(mTaskBroadcaster);

        // Disconnect all devices, verify the listener is unregistered.
        mTaskBroadcaster.onAllDevicesDisconnected();
        verify(mMockActivityTaskManager, times(1)).unregisterTaskStackListener(mTaskBroadcaster);
        verify(mMockActivityTaskManagerInternal, times(1))
            .unregisterHandoffEnablementListener(mTaskBroadcaster);
    }

    @Test
@@ -151,6 +160,27 @@ public class TaskBroadcasterTest {
        verify(mMockTaskContinuityMessenger, times(1)).sendMessage(eq(expectedMessage));
    }

    @Test
    public void testOnHandoffEnabledChanged_sendsMessageToAllAssociations() throws RemoteException {
        RemoteTaskInfo expectedRemoteTaskInfo = new RemoteTaskInfo(
            1 /* taskId */,
            "task" /* label */,
            100 /* lastActiveTime */,
            new byte[0] /* icon */,
            true /* isHandoffEnabled */);
        when(mMockRunningTaskFetcher.getRunningTaskById(expectedRemoteTaskInfo.id()))
            .thenReturn(expectedRemoteTaskInfo);
        RunningTaskInfo taskInfo = new RunningTaskInfo();
        taskInfo.taskId = expectedRemoteTaskInfo.id();

        mTaskBroadcaster.onHandoffEnabledChanged(expectedRemoteTaskInfo.id(), true);

        // Verify sendMessage is called for each association.
        RemoteTaskUpdatedMessage expectedMessage
            = new RemoteTaskUpdatedMessage(expectedRemoteTaskInfo);
       verify(mMockTaskContinuityMessenger, times(1)).sendMessage(eq(expectedMessage));
    }

    @Test
    public void testOnTaskMovedToFront_sendsMessageToAllAssociations() throws RemoteException {
        RemoteTaskInfo expectedRemoteTaskInfo = new RemoteTaskInfo(
+62 −14
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.platform.test.annotations.Presubmit;
import android.testing.AndroidTestingRunner;

import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskInfo;
import com.android.server.wm.ActivityTaskManagerInternal;

import org.junit.Before;
import org.junit.Test;
@@ -50,6 +51,7 @@ public class RunningTaskFetcherTest {
    private static final String LAUNCHER_PACKAGE_NAME = "com.example.launcher";

    @Mock private ActivityTaskManager mockActivityTaskManager;
    @Mock private ActivityTaskManagerInternal mockActivityTaskManagerInternal;
    @Mock private PackageManager mockPackageManager;
    @Mock private PackageMetadataCache mockPackageMetadataCache;

@@ -66,15 +68,33 @@ public class RunningTaskFetcherTest {
            .thenReturn(launcherResolveInfo);

        runningTaskFetcher = new RunningTaskFetcher(
            mockActivityTaskManager, mockPackageManager, mockPackageMetadataCache);
            mockActivityTaskManager,
            mockActivityTaskManagerInternal,
            mockPackageManager,
            mockPackageMetadataCache);
    }

    @Test
    public void testGetRunningTasks_returnsRunningTasks() {
        FakeTask[] tasks = {
            new FakeTask(1, "com.example.app1", 100, new PackageMetadata("app1", new byte[0])),
            new FakeTask(2, "com.example.app2", 200, new PackageMetadata("app2", new byte[0])),
            new FakeTask(3, LAUNCHER_PACKAGE_NAME, 300, new PackageMetadata("app3", new byte[0]))
            new FakeTask(
                1,
                "com.example.app1",
                100,
                new PackageMetadata("app1", new byte[0]),
                true),
            new FakeTask(
                2,
                "com.example.app2",
                200,
                new PackageMetadata("app2", new byte[0]),
                false),
            new FakeTask(
                3,
                LAUNCHER_PACKAGE_NAME,
                300,
                new PackageMetadata("app3", new byte[0]),
                true)
        };
        setupRunningTasks(tasks);

@@ -90,8 +110,13 @@ public class RunningTaskFetcherTest {
    @Test
    public void testGetRunningTasks_filtersTasksWithoutPackageMetadata() {
        FakeTask[] tasks = {
            new FakeTask(1, "com.example.app1", 100, new PackageMetadata("app1", new byte[0])),
            new FakeTask(2, "com.example.app2", 200, null),
            new FakeTask(
                1,
                "com.example.app1",
                100,
                new PackageMetadata("app1", new byte[0]),
                true),
            new FakeTask(2, "com.example.app2", 200, null, true),
        };
        setupRunningTasks(tasks);

@@ -105,8 +130,18 @@ public class RunningTaskFetcherTest {
    @Test
    public void testGetRunningTaskById_returnsRunningTask() {
        FakeTask[] tasks = {
            new FakeTask(1, "com.example.app1", 100, new PackageMetadata("app1", new byte[0])),
            new FakeTask(2, "com.example.app2", 200, new PackageMetadata("app2", new byte[0])),
            new FakeTask(
                1,
                "com.example.app1",
                100,
                new PackageMetadata("app1", new byte[0]),
                true),
            new FakeTask(
                2,
                "com.example.app2",
                200,
                new PackageMetadata("app2", new byte[0]),
                false),
        };
        setupRunningTasks(tasks);

@@ -118,8 +153,18 @@ public class RunningTaskFetcherTest {
    @Test
    public void testGetRunningTaskById_taskNotFound_returnsNull() {
        FakeTask[] tasks = {
            new FakeTask(1, "com.example.app1", 100, new PackageMetadata("app1", new byte[0])),
            new FakeTask(2, "com.example.app2", 200, new PackageMetadata("app2", new byte[0])),
            new FakeTask(
                1,
                "com.example.app1",
                100,
                new PackageMetadata("app1", new byte[0]),
                true),
            new FakeTask(
                2,
                "com.example.app2",
                200,
                new PackageMetadata("app2", new byte[0]),
                false),
        };
        setupRunningTasks(tasks);

@@ -131,7 +176,7 @@ public class RunningTaskFetcherTest {
    @Test
    public void testGetRunningTaskById_taskWithoutPackageMetadata_returnsNull() {
        FakeTask[] tasks = {
            new FakeTask(2, "com.example.app2", 200, null),
            new FakeTask(2, "com.example.app2", 200, null, true),
        };
        setupRunningTasks(tasks);

@@ -144,7 +189,7 @@ public class RunningTaskFetcherTest {
    public void testGetRunningTaskById_launcherPackage_returnsNull() {
        FakeTask[] tasks = {
            new FakeTask(
                1, LAUNCHER_PACKAGE_NAME, 200, new PackageMetadata("launcher", new byte[0])),
                1, LAUNCHER_PACKAGE_NAME, 200, new PackageMetadata("launcher", new byte[0]), false),
        };
        setupRunningTasks(tasks);

@@ -157,7 +202,8 @@ public class RunningTaskFetcherTest {
        int taskId,
        String packageName,
        long lastActiveTime,
        PackageMetadata packageMetadata) {
        PackageMetadata packageMetadata,
        boolean isHandoffEnabled) {

        public RemoteTaskInfo toRemoteTaskInfo() {
            return new RemoteTaskInfo(
@@ -165,7 +211,7 @@ public class RunningTaskFetcherTest {
                packageMetadata.label(),
                lastActiveTime,
                packageMetadata.icon(),
                true);
                isHandoffEnabled);
        }
    }

@@ -185,6 +231,8 @@ public class RunningTaskFetcherTest {
        taskInfo.lastActiveTime = task.lastActiveTime;
        when(mockPackageMetadataCache.getMetadataForPackage(task.packageName))
            .thenReturn(task.packageMetadata);
        when(mockActivityTaskManagerInternal.isHandoffEnabledForTask(task.taskId))
            .thenReturn(task.isHandoffEnabled);

        return taskInfo;
    }