Added Skeleton of TaskContinuityManager

Added a skeleton of the TaskContinuityManager service.

Flag: android.companion.enable_task_continuity
Bug: 400970610
Test: adb shell dumpsys task_continuity

Change-Id: I569f0e8c9387e9733b35d54edfe56f54e0bf6742
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index f35cbc0..fc5dea1 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -71,6 +71,8 @@
 import android.bluetooth.BluetoothFrameworkInitializer;
 import android.companion.CompanionDeviceManager;
 import android.companion.ICompanionDeviceManager;
+import android.companion.datatransfer.continuity.ITaskContinuityManager;
+import android.companion.datatransfer.continuity.TaskContinuityManager;
 import android.companion.virtual.IVirtualDeviceManager;
 import android.companion.virtual.VirtualDeviceManager;
 import android.compat.Compatibility;
@@ -1426,6 +1428,21 @@
             }
         });
 
+        if (android.companion.Flags.enableTaskContinuity()) {
+            registerService(Context.TASK_CONTINUITY_SERVICE, TaskContinuityManager.class,
+                    new CachedServiceFetcher<TaskContinuityManager>() {
+                        @Override
+                        public TaskContinuityManager createService(ContextImpl ctx)
+                                throws ServiceNotFoundException {
+                            IBinder iBinder = ServiceManager.getServiceOrThrow(
+                                    Context.TASK_CONTINUITY_SERVICE);
+                            ITaskContinuityManager service =
+                                    ITaskContinuityManager.Stub.asInterface(iBinder);
+                            return new TaskContinuityManager(ctx, service);
+                        }
+                    });
+        }
+
         registerService(Context.CROSS_PROFILE_APPS_SERVICE, CrossProfileApps.class,
                 new CachedServiceFetcher<CrossProfileApps>() {
                     @Override
diff --git a/core/java/android/companion/datatransfer/continuity/ITaskContinuityManager.aidl b/core/java/android/companion/datatransfer/continuity/ITaskContinuityManager.aidl
new file mode 100644
index 0000000..c97ec40
--- /dev/null
+++ b/core/java/android/companion/datatransfer/continuity/ITaskContinuityManager.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion.datatransfer.continuity;
+
+/**
+ * Interface for communication with the task continuity service.
+ * {@hide}
+ */
+interface ITaskContinuityManager {
+
+}
diff --git a/core/java/android/companion/datatransfer/continuity/OWNERS b/core/java/android/companion/datatransfer/continuity/OWNERS
new file mode 100644
index 0000000..4a4cb1e
--- /dev/null
+++ b/core/java/android/companion/datatransfer/continuity/OWNERS
@@ -0,0 +1,2 @@
+include /core/java/android/companion/OWNERS
+joeantonetti@google.com
diff --git a/core/java/android/companion/datatransfer/continuity/TaskContinuityManager.java b/core/java/android/companion/datatransfer/continuity/TaskContinuityManager.java
new file mode 100644
index 0000000..67ef00a
--- /dev/null
+++ b/core/java/android/companion/datatransfer/continuity/TaskContinuityManager.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.companion.datatransfer.continuity;
+
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * This class facilitates task continuity between devices owned by the same user.
+ * This includes synchronizing lists of open tasks between a user's devices, as well as requesting
+ * to hand off a task from one device to another. Handing a task off to a device will resume the
+ * application on the receiving device, preserving the state of the task.
+ *
+ * @hide
+ */
+@SystemService(Context.TASK_CONTINUITY_SERVICE)
+public class TaskContinuityManager {
+    private final Context mContext;
+    private final ITaskContinuityManager mService;
+
+    public TaskContinuityManager(Context context, ITaskContinuityManager service) {
+        mContext = context;
+        mService = service;
+    }
+}
diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig
index 2b9f700..1b63d8e 100644
--- a/core/java/android/companion/flags.aconfig
+++ b/core/java/android/companion/flags.aconfig
@@ -64,3 +64,10 @@
     description: "Enable set device icon API"
     bug: "341057668"
 }
+
+flag {
+    name: "enable_task_continuity"
+    namespace: "desktop_better_together"
+    description: "Enable task continuity API"
+    bug: "400970610"
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c11393e..2479e06 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -6696,6 +6696,15 @@
     @SystemApi
     public static final String WEARABLE_SENSING_SERVICE = "wearable_sensing";
 
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.companion.datatransfer.continuity.TaskContinuityManager}.
+     *
+     * @see #getSystemService(String)
+     * @see TaskContinuityManager
+     * @hide
+     */
+    public static final String TASK_CONTINUITY_SERVICE = "task_continuity";
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a
diff --git a/services/companion/java/com/android/server/companion/datatransfer/continuity/OWNERS b/services/companion/java/com/android/server/companion/datatransfer/continuity/OWNERS
new file mode 100644
index 0000000..4a4cb1e
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/datatransfer/continuity/OWNERS
@@ -0,0 +1,2 @@
+include /core/java/android/companion/OWNERS
+joeantonetti@google.com
diff --git a/services/companion/java/com/android/server/companion/datatransfer/continuity/TaskContinuityManagerService.java b/services/companion/java/com/android/server/companion/datatransfer/continuity/TaskContinuityManagerService.java
new file mode 100644
index 0000000..3cf9401
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/datatransfer/continuity/TaskContinuityManagerService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.companion.datatransfer.continuity;
+
+import android.companion.datatransfer.continuity.ITaskContinuityManager;
+import android.content.Context;
+
+import com.android.server.SystemService;
+
+
+/**
+ * Service to handle task continuity features
+ *
+ * @hide
+ *
+ */
+public final class TaskContinuityManagerService extends SystemService {
+
+    private TaskContinuityManagerServiceImpl mTaskContinuityManagerService;
+
+    public TaskContinuityManagerService(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onStart() {
+        mTaskContinuityManagerService = new TaskContinuityManagerServiceImpl();
+        publishBinderService(Context.TASK_CONTINUITY_SERVICE, mTaskContinuityManagerService);
+    }
+
+    private final class TaskContinuityManagerServiceImpl extends ITaskContinuityManager.Stub {
+
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 39722ab..b62e1c3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -151,6 +151,7 @@
 import com.android.server.camera.CameraServiceProxy;
 import com.android.server.clipboard.ClipboardService;
 import com.android.server.companion.CompanionDeviceManagerService;
+import com.android.server.companion.datatransfer.continuity.TaskContinuityManagerService;
 import com.android.server.companion.virtual.VirtualDeviceManagerService;
 import com.android.server.compat.PlatformCompat;
 import com.android.server.compat.PlatformCompatNative;
@@ -1591,6 +1592,7 @@
             ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());
             t.traceEnd();
 
+
             // TelecomLoader hooks into classes with defined HFP logic,
             // so check for either telephony or microphone.
             if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)
@@ -2627,6 +2629,12 @@
                 t.traceEnd();
             }
 
+            if (android.companion.Flags.enableTaskContinuity()) {
+                t.traceBegin("StartTaskContinuityService");
+                mSystemServiceManager.startService(TaskContinuityManagerService.class);
+                t.traceEnd();
+            }
+
             if (context.getResources().getBoolean(R.bool.config_enableVirtualDeviceManager)) {
                 t.traceBegin("StartVirtualDeviceManager");
                 mSystemServiceManager.startService(VirtualDeviceManagerService.class);