Loading services/companion/java/com/android/server/companion/datatransfer/continuity/TaskContinuityManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.android.server.companion.datatransfer.continuity.messages.HandoffRequ import com.android.server.companion.datatransfer.continuity.messages.HandoffRequestResultMessage; import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskAddedMessage; 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.messages.TaskContinuityMessage; import com.android.server.companion.datatransfer.continuity.tasks.RemoteTaskStore; Loading Loading @@ -131,6 +132,11 @@ public final class TaskContinuityManagerService extends SystemService { associationId, remoteTaskRemovedMessage.taskId()); break; case RemoteTaskUpdatedMessage remoteTaskUpdatedMessage: mRemoteTaskStore.updateTask( associationId, remoteTaskUpdatedMessage.getTask()); break; case HandoffRequestResultMessage handoffRequestResultMessage: mOutboundHandoffRequestController.onHandoffRequestResultMessageReceived( associationId, Loading services/companion/java/com/android/server/companion/datatransfer/continuity/tasks/RemoteDeviceTaskList.java +24 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ class RemoteDeviceTaskList { private final int mAssociationId; private final String mDeviceName; private final Consumer<RemoteTask> mOnMostRecentTaskChangedListener; private PriorityQueue<RemoteTaskInfo> mTasks; private final PriorityQueue<RemoteTaskInfo> mTasks; RemoteDeviceTaskList( int associationId, Loading Loading @@ -129,6 +129,29 @@ class RemoteDeviceTaskList { } } // Replaces tasks with the same ID as provided and notifies listeners. void updateTask(RemoteTaskInfo taskInfo) { synchronized(mTasks) { Slog.v( TAG, "Updating task: " + taskInfo.getId() + " for association: " + mAssociationId); int previousTopTaskId = mTasks.peek() == null ? -1 : mTasks.peek().getId(); mTasks.removeIf(task -> task.getId() == taskInfo.getId()); mTasks.add(taskInfo); boolean isTopTaskDifferent = previousTopTaskId != mTasks.peek().getId(); boolean didTopTaskChange = mTasks.peek() != null && mTasks.peek().getId() == taskInfo.getId(); boolean shouldNotifyListeners = isTopTaskDifferent || didTopTaskChange; if (shouldNotifyListeners) { Slog.v( TAG, "Notifying most recent task changed for association: " + mAssociationId); mOnMostRecentTaskChangedListener.accept(getMostRecentTask()); } } } /** * Gets the most recently used task on this device, or null if there are no * tasks. Loading services/companion/java/com/android/server/companion/datatransfer/continuity/tasks/RemoteTaskStore.java +10 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,16 @@ public class RemoteTaskStore implements ConnectedAssociationStore.Observer { } } public void updateTask(int associationId, RemoteTaskInfo taskInfo) { synchronized (mRemoteDeviceTaskLists) { if (!mRemoteDeviceTaskLists.containsKey(associationId)) { return; } mRemoteDeviceTaskLists.get(associationId).updateTask(taskInfo); } } /** * Returns the most recent tasks from all devices in the task store. * Loading services/tests/servicestests/src/com/android/server/companion/datatransfer/continuity/tasks/RemoteDeviceTaskListTest.java +46 −0 Original line number Diff line number Diff line Loading @@ -197,6 +197,52 @@ public class RemoteDeviceTaskListTest { assertThat(mMostRecentTask).isEqualTo(secondExpectedRemoteTask); } @Test public void updateTask_updatesMostRecentTaskAndNotifiesListeners() { // Set the initial state of the list. RemoteTaskInfo initialTaskInfo = createNewRemoteTaskInfo(1, "task1", 100); RemoteTask initialTask = initialTaskInfo.toRemoteTask(ASSOCIATION_ID, DEVICE_NAME); taskList.setTasks(Arrays.asList(initialTaskInfo)); assertThat(taskList.getMostRecentTask()).isEqualTo(initialTask); assertThat(mObserverCallCount).isEqualTo(1); assertThat(mMostRecentTask).isEqualTo(initialTask); RemoteTaskInfo updatedTaskInfo = createNewRemoteTaskInfo( initialTaskInfo.getId(), "task1", 200); RemoteTask updatedTask = updatedTaskInfo.toRemoteTask(ASSOCIATION_ID, DEVICE_NAME); taskList.updateTask(updatedTaskInfo); assertThat(taskList.getMostRecentTask()).isEqualTo(updatedTask); assertThat(mObserverCallCount).isEqualTo(2); assertThat(mMostRecentTask).isEqualTo(updatedTask); } @Test public void testUpdateTask_doesNotUpdateMostRecentTask_doesNotNotifyListeners() { // Set the initial state of the list. RemoteTaskInfo initialTaskInfo = createNewRemoteTaskInfo(1, "task1", 100); RemoteTask initialTask = initialTaskInfo.toRemoteTask(ASSOCIATION_ID, DEVICE_NAME); RemoteTaskInfo topTaskInfo = createNewRemoteTaskInfo(2, "task2", 200); RemoteTask topTask = topTaskInfo.toRemoteTask(ASSOCIATION_ID, DEVICE_NAME); taskList.setTasks(Arrays.asList(initialTaskInfo, topTaskInfo)); assertThat(taskList.getMostRecentTask()).isEqualTo(topTask); assertThat(mObserverCallCount).isEqualTo(1); assertThat(mMostRecentTask).isEqualTo(topTask); RemoteTaskInfo updatedTaskInfo = createNewRemoteTaskInfo( initialTaskInfo.getId(), "task1", 150); taskList.updateTask(updatedTaskInfo); assertThat(taskList.getMostRecentTask()).isEqualTo(topTask); assertThat(mObserverCallCount).isEqualTo(1); assertThat(mMostRecentTask).isEqualTo(topTask); } private RemoteTaskInfo createNewRemoteTaskInfo( int id, String label, Loading services/tests/servicestests/src/com/android/server/companion/datatransfer/continuity/tasks/RemoteTaskStoreTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,34 @@ public class RemoteTaskStoreTest { assertThat(taskStore.getMostRecentTasks()).isEmpty(); } @Test public void updateTask_updatesTaskAndNotifiesListeners() { // Create a fake association info, and have connected association store return it. AssociationInfo associationInfo = createAssociationInfo(1, "name"); when(mMockConnectedAssociationStore.getConnectedAssociationById(1)) .thenReturn(associationInfo); taskStore.onTransportConnected(associationInfo); RemoteTaskInfo initialTaskInfo = createNewRemoteTaskInfo(1, "task1", 100L); RemoteTask initialTask = initialTaskInfo.toRemoteTask(associationInfo.getId(), "name"); taskStore.setTasks(1, Collections.singletonList(initialTaskInfo)); assertThat(taskStore.getMostRecentTasks()).containsExactly(initialTask); assertThat(remoteTasksReportedToListener).hasSize(1); assertThat(remoteTasksReportedToListener.get(0)).containsExactly(initialTask); // Update the task to have a different name. RemoteTaskInfo updatedTaskInfo = createNewRemoteTaskInfo( initialTaskInfo.getId(), "task1", 200L); RemoteTask updatedTask = updatedTaskInfo.toRemoteTask(associationInfo.getId(), "name"); taskStore.updateTask(1, updatedTaskInfo); assertThat(taskStore.getMostRecentTasks()).containsExactly(updatedTask); assertThat(remoteTasksReportedToListener).hasSize(2); assertThat(remoteTasksReportedToListener.get(1)).containsExactly(updatedTask); } private RemoteTaskInfo createNewRemoteTaskInfo( int id, String label, Loading Loading
services/companion/java/com/android/server/companion/datatransfer/continuity/TaskContinuityManagerService.java +6 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import com.android.server.companion.datatransfer.continuity.messages.HandoffRequ import com.android.server.companion.datatransfer.continuity.messages.HandoffRequestResultMessage; import com.android.server.companion.datatransfer.continuity.messages.RemoteTaskAddedMessage; 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.messages.TaskContinuityMessage; import com.android.server.companion.datatransfer.continuity.tasks.RemoteTaskStore; Loading Loading @@ -131,6 +132,11 @@ public final class TaskContinuityManagerService extends SystemService { associationId, remoteTaskRemovedMessage.taskId()); break; case RemoteTaskUpdatedMessage remoteTaskUpdatedMessage: mRemoteTaskStore.updateTask( associationId, remoteTaskUpdatedMessage.getTask()); break; case HandoffRequestResultMessage handoffRequestResultMessage: mOutboundHandoffRequestController.onHandoffRequestResultMessageReceived( associationId, Loading
services/companion/java/com/android/server/companion/datatransfer/continuity/tasks/RemoteDeviceTaskList.java +24 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ class RemoteDeviceTaskList { private final int mAssociationId; private final String mDeviceName; private final Consumer<RemoteTask> mOnMostRecentTaskChangedListener; private PriorityQueue<RemoteTaskInfo> mTasks; private final PriorityQueue<RemoteTaskInfo> mTasks; RemoteDeviceTaskList( int associationId, Loading Loading @@ -129,6 +129,29 @@ class RemoteDeviceTaskList { } } // Replaces tasks with the same ID as provided and notifies listeners. void updateTask(RemoteTaskInfo taskInfo) { synchronized(mTasks) { Slog.v( TAG, "Updating task: " + taskInfo.getId() + " for association: " + mAssociationId); int previousTopTaskId = mTasks.peek() == null ? -1 : mTasks.peek().getId(); mTasks.removeIf(task -> task.getId() == taskInfo.getId()); mTasks.add(taskInfo); boolean isTopTaskDifferent = previousTopTaskId != mTasks.peek().getId(); boolean didTopTaskChange = mTasks.peek() != null && mTasks.peek().getId() == taskInfo.getId(); boolean shouldNotifyListeners = isTopTaskDifferent || didTopTaskChange; if (shouldNotifyListeners) { Slog.v( TAG, "Notifying most recent task changed for association: " + mAssociationId); mOnMostRecentTaskChangedListener.accept(getMostRecentTask()); } } } /** * Gets the most recently used task on this device, or null if there are no * tasks. Loading
services/companion/java/com/android/server/companion/datatransfer/continuity/tasks/RemoteTaskStore.java +10 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,16 @@ public class RemoteTaskStore implements ConnectedAssociationStore.Observer { } } public void updateTask(int associationId, RemoteTaskInfo taskInfo) { synchronized (mRemoteDeviceTaskLists) { if (!mRemoteDeviceTaskLists.containsKey(associationId)) { return; } mRemoteDeviceTaskLists.get(associationId).updateTask(taskInfo); } } /** * Returns the most recent tasks from all devices in the task store. * Loading
services/tests/servicestests/src/com/android/server/companion/datatransfer/continuity/tasks/RemoteDeviceTaskListTest.java +46 −0 Original line number Diff line number Diff line Loading @@ -197,6 +197,52 @@ public class RemoteDeviceTaskListTest { assertThat(mMostRecentTask).isEqualTo(secondExpectedRemoteTask); } @Test public void updateTask_updatesMostRecentTaskAndNotifiesListeners() { // Set the initial state of the list. RemoteTaskInfo initialTaskInfo = createNewRemoteTaskInfo(1, "task1", 100); RemoteTask initialTask = initialTaskInfo.toRemoteTask(ASSOCIATION_ID, DEVICE_NAME); taskList.setTasks(Arrays.asList(initialTaskInfo)); assertThat(taskList.getMostRecentTask()).isEqualTo(initialTask); assertThat(mObserverCallCount).isEqualTo(1); assertThat(mMostRecentTask).isEqualTo(initialTask); RemoteTaskInfo updatedTaskInfo = createNewRemoteTaskInfo( initialTaskInfo.getId(), "task1", 200); RemoteTask updatedTask = updatedTaskInfo.toRemoteTask(ASSOCIATION_ID, DEVICE_NAME); taskList.updateTask(updatedTaskInfo); assertThat(taskList.getMostRecentTask()).isEqualTo(updatedTask); assertThat(mObserverCallCount).isEqualTo(2); assertThat(mMostRecentTask).isEqualTo(updatedTask); } @Test public void testUpdateTask_doesNotUpdateMostRecentTask_doesNotNotifyListeners() { // Set the initial state of the list. RemoteTaskInfo initialTaskInfo = createNewRemoteTaskInfo(1, "task1", 100); RemoteTask initialTask = initialTaskInfo.toRemoteTask(ASSOCIATION_ID, DEVICE_NAME); RemoteTaskInfo topTaskInfo = createNewRemoteTaskInfo(2, "task2", 200); RemoteTask topTask = topTaskInfo.toRemoteTask(ASSOCIATION_ID, DEVICE_NAME); taskList.setTasks(Arrays.asList(initialTaskInfo, topTaskInfo)); assertThat(taskList.getMostRecentTask()).isEqualTo(topTask); assertThat(mObserverCallCount).isEqualTo(1); assertThat(mMostRecentTask).isEqualTo(topTask); RemoteTaskInfo updatedTaskInfo = createNewRemoteTaskInfo( initialTaskInfo.getId(), "task1", 150); taskList.updateTask(updatedTaskInfo); assertThat(taskList.getMostRecentTask()).isEqualTo(topTask); assertThat(mObserverCallCount).isEqualTo(1); assertThat(mMostRecentTask).isEqualTo(topTask); } private RemoteTaskInfo createNewRemoteTaskInfo( int id, String label, Loading
services/tests/servicestests/src/com/android/server/companion/datatransfer/continuity/tasks/RemoteTaskStoreTest.java +28 −0 Original line number Diff line number Diff line Loading @@ -203,6 +203,34 @@ public class RemoteTaskStoreTest { assertThat(taskStore.getMostRecentTasks()).isEmpty(); } @Test public void updateTask_updatesTaskAndNotifiesListeners() { // Create a fake association info, and have connected association store return it. AssociationInfo associationInfo = createAssociationInfo(1, "name"); when(mMockConnectedAssociationStore.getConnectedAssociationById(1)) .thenReturn(associationInfo); taskStore.onTransportConnected(associationInfo); RemoteTaskInfo initialTaskInfo = createNewRemoteTaskInfo(1, "task1", 100L); RemoteTask initialTask = initialTaskInfo.toRemoteTask(associationInfo.getId(), "name"); taskStore.setTasks(1, Collections.singletonList(initialTaskInfo)); assertThat(taskStore.getMostRecentTasks()).containsExactly(initialTask); assertThat(remoteTasksReportedToListener).hasSize(1); assertThat(remoteTasksReportedToListener.get(0)).containsExactly(initialTask); // Update the task to have a different name. RemoteTaskInfo updatedTaskInfo = createNewRemoteTaskInfo( initialTaskInfo.getId(), "task1", 200L); RemoteTask updatedTask = updatedTaskInfo.toRemoteTask(associationInfo.getId(), "name"); taskStore.updateTask(1, updatedTaskInfo); assertThat(taskStore.getMostRecentTasks()).containsExactly(updatedTask); assertThat(remoteTasksReportedToListener).hasSize(2); assertThat(remoteTasksReportedToListener.get(1)).containsExactly(updatedTask); } private RemoteTaskInfo createNewRemoteTaskInfo( int id, String label, Loading