Snap for 8730993 from 390bbe4f067c8d115dac5bb40976f96aa9a42d66 to mainline-tzdata3-release

Change-Id: Ic379a4e97648a1b68b2777b6574dc9f3e64cbe10
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index b61e3aa..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-*~
-.project
-.classpath
-*.iml
-gen/
-*.pyc
-*.swp
-__pycache__
-.idea
-/bin/
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..d26195e
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,35 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+    name: "car-frameworks-service",
+    installable: true,
+    libs: [
+        "services",
+        "android.hardware.automotive.vehicle-V2.0-java",
+        "com.android.car.internal.common",
+    ],
+    required: ["libcar-framework-service-jni"],
+    srcs: [
+        "src/**/*.java",
+    ],
+    static_libs: [
+        "android.car.watchdoglib",
+        "com.android.car.internal.system",
+        "android.automotive.watchdog.internal-java",
+    ],
+}
+
+cc_library_shared {
+    name: "libcar-framework-service-jni",
+    shared_libs: [
+        "libandroid_runtime",
+        "libhidlbase",
+        "liblog",
+        "libnativehelper",
+        "libsuspend",
+        "libutils",
+    ],
+    srcs: ["src/jni/com_android_internal_car_CarServiceHelperService.cpp"],
+}
diff --git a/builtInServices/PREUPLOAD.cfg b/PREUPLOAD.cfg
similarity index 100%
rename from builtInServices/PREUPLOAD.cfg
rename to PREUPLOAD.cfg
diff --git a/builtInServices/Android.bp b/builtInServices/Android.bp
deleted file mode 100644
index eeda2da..0000000
--- a/builtInServices/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-java_sdk_library {
-    name: "car-frameworks-service",
-    libs: [
-        "services",
-        "android.car",
-        "android.car.builtin",  // Will remove once split is complete
-        "android.hardware.automotive.vehicle-V2.0-java",
-    ],
-    srcs: [
-        "src/**/*.java",
-    ],
-    static_libs: [
-        "android.car.watchdoglib",
-        "android.automotive.watchdog.internal-V1-java",
-    ],
-    api_lint: {
-        enabled: true,
-    },
-
-    min_sdk_version: "33",
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.car.framework"
-    ],
-
-    unsafe_ignore_missing_latest_api: true,
-
-    test: {
-        enabled: false,
-    },
-    system: {
-        enabled: true,
-        sdk_version: "module_current",
-    },
-    module_lib: {
-        enabled: true,
-        sdk_version: "module_current",
-    },
-}
diff --git a/builtInServices/TEST_MAPPING b/builtInServices/TEST_MAPPING
deleted file mode 100644
index 2832b34..0000000
--- a/builtInServices/TEST_MAPPING
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "auto-presubmit": [
-    {
-      "name": "CarServiceCrashDumpTest"
-    },
-    {
-      "name": "FrameworkOptCarServicesTest"
-    }
-  ]
-}
diff --git a/builtInServices/api/current.txt b/builtInServices/api/current.txt
deleted file mode 100644
index d802177..0000000
--- a/builtInServices/api/current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/builtInServices/api/module-lib-current.txt b/builtInServices/api/module-lib-current.txt
deleted file mode 100644
index ddf15cf..0000000
--- a/builtInServices/api/module-lib-current.txt
+++ /dev/null
@@ -1,96 +0,0 @@
-// Signature format: 2.0
-package com.android.internal.car {
-
-  public interface CarServiceHelperInterface {
-    method @Nullable public android.os.UserHandle createUserEvenWhenDisallowed(@Nullable String, @NonNull String, int);
-    method @Nullable public java.io.File dumpServiceStacks();
-    method public void setSafetyMode(boolean);
-  }
-
-  public interface CarServiceHelperServiceUpdatable {
-    method public void dump(@NonNull java.io.PrintWriter, @Nullable String[]);
-    method public com.android.server.wm.CarLaunchParamsModifierUpdatable getCarLaunchParamsModifierUpdatable();
-    method public void initBootUser();
-    method public void onFactoryReset(@NonNull java.util.function.BiConsumer<java.lang.Integer,android.os.Bundle>);
-    method public void onStart();
-    method public void onUserRemoved(@NonNull android.os.UserHandle);
-    method public void sendUserLifecycleEvent(int, @Nullable android.os.UserHandle, @NonNull android.os.UserHandle);
-  }
-
-}
-
-package com.android.server.wm {
-
-  public final class ActivityOptionsWrapper {
-    method public com.android.server.wm.TaskDisplayAreaWrapper getLaunchTaskDisplayArea();
-    method public android.app.ActivityOptions getOptions();
-  }
-
-  public final class ActivityRecordWrapper {
-    method public boolean allowingEmbedded();
-    method public android.content.ComponentName getComponentName();
-    method public com.android.server.wm.TaskDisplayAreaWrapper getDisplayArea();
-    method public int getHandoverLaunchDisplayId();
-    method public com.android.server.wm.TaskDisplayAreaWrapper getHandoverTaskDisplayArea();
-    method public int getUserId();
-    method public boolean isDisplayTrusted();
-    method public boolean isNoDisplay();
-  }
-
-  public final class CalculateParams {
-    method public com.android.server.wm.ActivityRecordWrapper getActivity();
-    method public com.android.server.wm.LaunchParamsWrapper getCurrentParams();
-    method public com.android.server.wm.ActivityOptionsWrapper getOptions();
-    method public com.android.server.wm.LaunchParamsWrapper getOutParams();
-    method public int getPhase();
-    method public com.android.server.wm.RequestWrapper getRequest();
-    method public com.android.server.wm.ActivityRecordWrapper getSource();
-    method public com.android.server.wm.TaskWrapper getTask();
-    method public com.android.server.wm.WindowLayoutWrapper getWindowLayout();
-    method public boolean supportsMultiDisplay();
-  }
-
-  public interface CarLaunchParamsModifierInterface {
-    method @Nullable public com.android.server.wm.TaskDisplayAreaWrapper findTaskDisplayArea(int, int);
-    method @Nullable public com.android.server.wm.TaskDisplayAreaWrapper getDefaultTaskDisplayAreaOnDisplay(int);
-    method @NonNull public java.util.List<com.android.server.wm.TaskDisplayAreaWrapper> getFallbackDisplayAreasForActivity(@NonNull com.android.server.wm.ActivityRecordWrapper, @Nullable com.android.server.wm.RequestWrapper);
-  }
-
-  public interface CarLaunchParamsModifierUpdatable {
-    method public int calculate(com.android.server.wm.CalculateParams);
-    method public android.hardware.display.DisplayManager.DisplayListener getDisplayListener();
-    method public void handleCurrentUserSwitching(int);
-    method public void handleUserStarting(int);
-    method public void handleUserStopped(int);
-  }
-
-  public final class LaunchParamsWrapper {
-    method public android.graphics.Rect getBounds();
-    method public com.android.server.wm.TaskDisplayAreaWrapper getPreferredTaskDisplayArea();
-    method public int getWindowingMode();
-    method public void setBounds(android.graphics.Rect);
-    method public void setPreferredTaskDisplayArea(com.android.server.wm.TaskDisplayAreaWrapper);
-    method public void setWindowingMode(int);
-    field public static int RESULT_CONTINUE;
-    field public static int RESULT_DONE;
-    field public static int RESULT_SKIP;
-  }
-
-  public final class RequestWrapper {
-  }
-
-  public final class TaskDisplayAreaWrapper {
-    method public android.view.Display getDisplay();
-  }
-
-  public final class TaskWrapper {
-    method public com.android.server.wm.TaskWrapper getRootTask();
-    method public com.android.server.wm.TaskDisplayAreaWrapper getTaskDisplayArea();
-    method public int getUserId();
-  }
-
-  public final class WindowLayoutWrapper {
-  }
-
-}
-
diff --git a/builtInServices/api/module-lib-removed.txt b/builtInServices/api/module-lib-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/builtInServices/api/module-lib-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/builtInServices/api/removed.txt b/builtInServices/api/removed.txt
deleted file mode 100644
index d802177..0000000
--- a/builtInServices/api/removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/builtInServices/api/system-current.txt b/builtInServices/api/system-current.txt
deleted file mode 100644
index d802177..0000000
--- a/builtInServices/api/system-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/builtInServices/api/system-removed.txt b/builtInServices/api/system-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/builtInServices/api/system-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/builtInServices/api/test-current.txt b/builtInServices/api/test-current.txt
deleted file mode 100644
index d802177..0000000
--- a/builtInServices/api/test-current.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/builtInServices/api/test-removed.txt b/builtInServices/api/test-removed.txt
deleted file mode 100644
index d802177..0000000
--- a/builtInServices/api/test-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/builtInServices/host_tests/Android.bp b/builtInServices/host_tests/Android.bp
deleted file mode 100644
index 9d68572..0000000
--- a/builtInServices/host_tests/Android.bp
+++ /dev/null
@@ -1,14 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-java_test_host {
-    name: "CarServiceCrashDumpTest",
-    srcs: ["src/**/CarServiceCrashDumpTest.java"],
-    libs: [
-        "compatibility-host-util",
-        "junit",
-        "tradefed",
-        "truth-prebuilt",
-    ],
-}
diff --git a/builtInServices/host_tests/src/com/android/internal/car/test/CarServiceCrashDumpTest.java b/builtInServices/host_tests/src/com/android/internal/car/test/CarServiceCrashDumpTest.java
deleted file mode 100644
index bf19a3c..0000000
--- a/builtInServices/host_tests/src/com/android/internal/car/test/CarServiceCrashDumpTest.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2021 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.internal.car.test;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import com.android.compatibility.common.util.CommonTestUtils;
-import com.android.compatibility.common.util.PollingCheck;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-
-import static org.junit.Assume.assumeTrue;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-
-@RunWith(DeviceJUnit4ClassRunner.class)
-public final class CarServiceCrashDumpTest extends BaseHostJUnit4Test {
-    private static final int DEFAULT_TIMEOUT_SEC = 20;
-    private static final long POLL_TIMEOUT_MS = 20000;
-    private static final String BUILD_TYPE_PROPERTY = "ro.build.type";
-
-    // This must be in sync with WatchDog lib.
-    private static final List<String> HAL_INTERFACES_OF_INTEREST = Arrays.asList(
-            "android.hardware.audio@4.0::IDevicesFactory",
-            "android.hardware.audio@5.0::IDevicesFactory",
-            "android.hardware.audio@6.0::IDevicesFactory",
-            "android.hardware.audio@7.0::IDevicesFactory",
-            "android.hardware.biometrics.face@1.0::IBiometricsFace",
-            "android.hardware.biometrics.fingerprint@2.1::IBiometricsFingerprint",
-            "android.hardware.bluetooth@1.0::IBluetoothHci",
-            "android.hardware.camera.provider@2.4::ICameraProvider",
-            "android.hardware.gnss@1.0::IGnss",
-            "android.hardware.graphics.allocator@2.0::IAllocator",
-            "android.hardware.graphics.composer@2.1::IComposer",
-            "android.hardware.health@2.0::IHealth",
-            "android.hardware.light@2.0::ILight",
-            "android.hardware.media.c2@1.0::IComponentStore",
-            "android.hardware.media.omx@1.0::IOmx",
-            "android.hardware.media.omx@1.0::IOmxStore",
-            "android.hardware.neuralnetworks@1.0::IDevice",
-            "android.hardware.power.stats@1.0::IPowerStats",
-            "android.hardware.sensors@1.0::ISensors",
-            "android.hardware.sensors@2.0::ISensors",
-            "android.hardware.sensors@2.1::ISensors",
-            "android.hardware.vr@1.0::IVr",
-            "android.system.suspend@1.0::ISystemSuspend"
-    );
-
-    // Which native processes to dump into dropbox's stack traces, must be in sync with Watchdog
-    // lib.
-    private static final String[] NATIVE_STACKS_OF_INTEREST = new String[] {
-        "/system/bin/audioserver",
-        "/system/bin/cameraserver",
-        "/system/bin/drmserver",
-        "/system/bin/keystore2",
-        "/system/bin/mediadrmserver",
-        "/system/bin/mediaserver",
-        "/system/bin/netd",
-        "/system/bin/sdcard",
-        "/system/bin/surfaceflinger",
-        "/system/bin/vold",
-        "media.extractor", // system/bin/mediaextractor
-        "media.metrics", // system/bin/mediametrics
-        "media.codec", // vendor/bin/hw/android.hardware.media.omx@1.0-service
-        "media.swcodec", // /apex/com.android.media.swcodec/bin/mediaswcodec
-        "media.transcoding", // Media transcoding service
-        "com.android.bluetooth",  // Bluetooth service
-        "/apex/com.android.os.statsd/bin/statsd",  // Stats daemon
-    };
-
-    /**
-     * Executes the shell command and returns the output.
-     */
-    private String executeCommand(String command, Object... args) throws Exception {
-        String fullCommand = String.format(command, args);
-        return getDevice().executeShellCommand(fullCommand);
-    }
-
-    /**
-     * Waits until the car service is ready.
-     */
-    private void waitForCarServiceReady() throws Exception {
-        CommonTestUtils.waitUntil("timed out waiting for car service ",
-                DEFAULT_TIMEOUT_SEC, () -> isCarServiceReady());
-    }
-
-    private boolean isCarServiceReady() {
-        String cmd = "service check car_service";
-        try {
-            String output = getDevice().executeShellCommand(cmd).strip();
-            return !output.endsWith("not found");
-        } catch (Exception e) {
-            CLog.w("%s failed: %s", cmd, e.getMessage());
-        }
-        return false;
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        executeCommand("logcat -c");
-    }
-
-    /**
-     * Read the content of the dumped file.
-     */
-    private String getDumpFile() throws Exception {
-        AtomicReference<String> log = new AtomicReference<>();
-        String dumpString = "ActivityManager: Dumping to ";
-        String doneDumpingString = "ActivityManager: Done dumping";
-        PollingCheck.check("dumpStackTrace not found in log", POLL_TIMEOUT_MS, () -> {
-            String logString = executeCommand("logcat -d");
-            if (logString.contains("ActivityManager: dumpStackTraces") && logString.contains(
-                    dumpString) && logString.contains(doneDumpingString)) {
-                log.set(logString);
-                return true;
-            }
-            return false;
-        });
-        String logString = log.get();
-        int start = logString.indexOf(dumpString) + dumpString.length();
-        int end = logString.indexOf("\n", start);
-        if (end == -1) {
-            end = logString.length();
-        }
-        return logString.substring(start, end);
-    }
-
-    /**
-     * Get a list of PIDs for the interesting HALs that would be dumped.
-     */
-    private List<String> getHalPids() throws Exception {
-        String lshalResult = executeCommand("lshal -i -p");
-        List<String> pids = new ArrayList<String>();
-        int i = 0;
-        for (String line: lshalResult.split("\n")) {
-            line = line.strip();
-            if (line.equals("")) {
-                // When we see an empty line, we stops the parsing.
-                break;
-            }
-            if (i < 2) {
-                // Skip the first two lines
-                i++;
-                continue;
-            }
-            String[] fields = line.split("\\s+");
-            for (String interestHal: HAL_INTERFACES_OF_INTEREST) {
-                if (fields[0].contains(interestHal)) {
-                    pids.add(fields[1]);
-                    break;
-                }
-            }
-            i++;
-        }
-        return pids;
-    }
-
-    /**
-     * Get a list of PIDs for the native services that would be dumped.
-     */
-    private List<String> getNativePids() throws Exception {
-        List<String> pids = new ArrayList<String>();
-        for (String name: NATIVE_STACKS_OF_INTEREST) {
-            String pid = executeCommand(String.format("pidof %s", name)).strip();
-            if (!pid.equals("")) {
-                pids.add(pid);
-            }
-        }
-        return pids;
-    }
-
-    @Test
-    public void testCarServiceCrashDump() throws Exception {
-        String buildType = getDevice().getProperty("ro.build.type");
-        // Only run on userdebug devices.
-        assumeTrue(buildType.equals("userdebug") || buildType.equals("eng"));
-
-        List<String> pids = new ArrayList<String>();
-
-        getDevice().enableAdbRoot();
-
-        String systemServerPid = executeCommand(String.format("pidof %s", "system_server")).strip();
-        assertWithMessage("system_service pid not empty").that(systemServerPid).isNotEmpty();
-        pids.add(systemServerPid);
-
-        List<String> halPids = getHalPids();
-        pids.addAll(halPids);
-        assertWithMessage("hal pids").that(halPids.size() > 0).isTrue();
-
-        List<String> nativePids = getNativePids();
-        pids.addAll(nativePids);
-        assertWithMessage("native pids").that(nativePids.size() > 0).isTrue();
-
-        executeCommand("am crash --user 0 com.android.car");
-
-        String dumpFile = getDumpFile();
-        assertWithMessage("dump file").that(dumpFile).isNotEmpty();
-
-        String grepResult = executeCommand("cat %s", dumpFile);
-
-        assertWithMessage("dumped content not empty").that(grepResult)
-                .isNotEmpty();
-
-        for (String pid : pids) {
-            assertWithMessage("dumped content contains interesting pid").that(grepResult)
-                    .contains(String.format("----- pid %s at", pid));
-        }
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        waitForCarServiceReady();
-    }
-}
diff --git a/builtInServices/src/com/android/internal/car/CarServiceHelperInterface.java b/builtInServices/src/com/android/internal/car/CarServiceHelperInterface.java
deleted file mode 100644
index 362fd07..0000000
--- a/builtInServices/src/com/android/internal/car/CarServiceHelperInterface.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2021 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.internal.car;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.UserHandle;
-
-import java.io.File;
-
-/**
- * Interface implemented by CarServiceHelperService.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public interface CarServiceHelperInterface {
-
-    /**
-     * Sets safety mode
-     */
-    void setSafetyMode(boolean safe);
-
-    /**
-     * Creates user even when disallowed
-     */
-    @Nullable
-    UserHandle createUserEvenWhenDisallowed(@Nullable String name, @NonNull String userType,
-            int flags);
-
-    /**
-     * Dumps service stacks
-     */
-    @Nullable
-    File dumpServiceStacks();
-}
diff --git a/builtInServices/src/com/android/internal/car/CarServiceHelperService.java b/builtInServices/src/com/android/internal/car/CarServiceHelperService.java
deleted file mode 100644
index 4e2333c..0000000
--- a/builtInServices/src/com/android/internal/car/CarServiceHelperService.java
+++ /dev/null
@@ -1,743 +0,0 @@
-/*
- * Copyright (C) 2017 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.internal.car;
-
-import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_POST_UNLOCKED;
-import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STARTING;
-import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STOPPED;
-import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STOPPING;
-import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_SWITCHING;
-import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED;
-import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_UNLOCKING;
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.admin.DevicePolicyManager;
-import android.app.admin.DevicePolicyManager.DevicePolicyOperation;
-import android.app.admin.DevicePolicyManager.OperationSafetyReason;
-import android.app.admin.DevicePolicySafetyChecker;
-import android.automotive.watchdog.internal.ICarWatchdogMonitor;
-import android.automotive.watchdog.internal.ProcessIdentifier;
-import android.automotive.watchdog.internal.StateType;
-import android.car.builtin.util.EventLogHelper;
-import android.car.watchdoglib.CarWatchdogDaemonHelper;
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.hidl.manager.V1_0.IServiceManager;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.Trace;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.system.Os;
-import android.system.OsConstants;
-import android.util.Dumpable;
-import android.util.TimeUtils;
-
-import com.android.car.internal.common.CommonConstants.UserLifecycleEventType;
-import com.android.car.internal.common.UserHelperLite;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.IResultReceiver;
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-import com.android.server.Watchdog;
-import com.android.server.am.ActivityManagerService;
-import com.android.server.pm.UserManagerInternal;
-import com.android.server.pm.UserManagerInternal.UserLifecycleListener;
-import com.android.server.utils.Slogf;
-import com.android.server.utils.TimingsTraceAndSlog;
-import com.android.server.wm.CarLaunchParamsModifier;
-import com.android.server.wm.CarLaunchParamsModifierInterface;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * System service side companion service for CarService. Starts car service and provide necessary
- * API for CarService. Only for car product.
- *
- * @hide
- */
-public class CarServiceHelperService extends SystemService
-        implements Dumpable, DevicePolicySafetyChecker, CarServiceHelperInterface {
-
-    @VisibleForTesting
-    static final String TAG = "CarServiceHelper";
-
-    // TODO(b/154033860): STOPSHIP if they're still true
-    private static final boolean DBG = true;
-    private static final boolean VERBOSE = true;
-
-    private static final List<String> CAR_HAL_INTERFACES_OF_INTEREST = Arrays.asList(
-            "android.hardware.automotive.vehicle@2.0::IVehicle",
-            "android.hardware.automotive.audiocontrol@1.0::IAudioControl",
-            "android.hardware.automotive.audiocontrol@2.0::IAudioControl"
-    );
-
-    // Message ID representing post-processing of process dumping.
-    private static final int WHAT_POST_PROCESS_DUMPING = 1;
-    // Message ID representing process killing.
-    private static final int WHAT_PROCESS_KILL = 2;
-
-    private static final String CSHS_UPDATABLE_CLASSNAME_STRING =
-            "com.android.internal.car.updatable.CarServiceHelperServiceUpdatableImpl";
-    private static final String PROC_PID_STAT_PATTERN =
-            "(?<pid>[0-9]*)\\s\\((?<name>\\S+)\\)\\s\\S\\s(?:-?[0-9]*\\s){18}"
-                    + "(?<startClockTicks>[0-9]*)\\s(?:-?[0-9]*\\s)*-?[0-9]*";
-
-    private final Context mContext;
-    private final Object mLock = new Object();
-    @GuardedBy("mLock")
-    private boolean mSystemBootCompleted;
-
-    private final CarLaunchParamsModifier mCarLaunchParamsModifier;
-
-    private final Handler mHandler;
-    private final HandlerThread mHandlerThread = new HandlerThread("CarServiceHelperService");
-
-    private final ProcessTerminator mProcessTerminator = new ProcessTerminator();
-
-    private final Pattern mProcPidStatPattern = Pattern.compile(PROC_PID_STAT_PATTERN);
-
-    private final CarWatchdogDaemonHelper mCarWatchdogDaemonHelper;
-    private final ICarWatchdogMonitorImpl mCarWatchdogMonitor = new ICarWatchdogMonitorImpl(this);
-    private final CarWatchdogDaemonHelper.OnConnectionChangeListener mConnectionListener =
-            (connected) -> {
-                if (connected) {
-                    registerMonitorToWatchdogDaemon();
-                }
-            };
-
-    private final CarDevicePolicySafetyChecker mCarDevicePolicySafetyChecker;
-
-    private CarServiceHelperServiceUpdatable mCarServiceHelperServiceUpdatable;
-
-    /**
-     * End-to-end time (from process start) for unlocking the first non-system user.
-     */
-    private long mFirstUnlockedUserDuration;
-
-    public CarServiceHelperService(Context context) {
-        this(context,
-                new CarLaunchParamsModifier(context),
-                new CarWatchdogDaemonHelper(TAG),
-                /* carServiceHelperServiceUpdatable= */ null,
-                /* carDevicePolicySafetyChecker= */ null
-        );
-    }
-
-    @VisibleForTesting
-    CarServiceHelperService(
-            Context context,
-            CarLaunchParamsModifier carLaunchParamsModifier,
-            CarWatchdogDaemonHelper carWatchdogDaemonHelper,
-            @Nullable CarServiceHelperServiceUpdatable carServiceHelperServiceUpdatable,
-            @Nullable CarDevicePolicySafetyChecker carDevicePolicySafetyChecker) {
-        super(context);
-
-        mContext = context;
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-        mCarLaunchParamsModifier = carLaunchParamsModifier;
-        mCarWatchdogDaemonHelper = carWatchdogDaemonHelper;
-        try {
-            if (carServiceHelperServiceUpdatable == null) {
-                mCarServiceHelperServiceUpdatable = (CarServiceHelperServiceUpdatable) Class
-                        .forName(CSHS_UPDATABLE_CLASSNAME_STRING)
-                        .getConstructor(Context.class, CarServiceHelperInterface.class,
-                                CarLaunchParamsModifierInterface.class)
-                        .newInstance(mContext, this,
-                                mCarLaunchParamsModifier.getBuiltinInterface());
-                Slogf.d(TAG, "CarServiceHelperServiceUpdatable created via reflection.");
-            } else {
-                mCarServiceHelperServiceUpdatable = carServiceHelperServiceUpdatable;
-            }
-        } catch (Exception e) {
-            // TODO(b/190458000): Define recovery mechanism.
-            // can't create the CarServiceHelperServiceUpdatable object
-            // crash the process
-            Slogf.w(TAG, e, "*** CARHELPER KILLING SYSTEM PROCESS: "
-                    + "Can't create CarServiceHelperServiceUpdatable.");
-            Slogf.w(TAG, "*** GOODBYE!");
-            Process.killProcess(Process.myPid());
-            System.exit(10);
-        }
-        mCarLaunchParamsModifier.setUpdatable(
-                mCarServiceHelperServiceUpdatable.getCarLaunchParamsModifierUpdatable());
-
-        UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
-        if (umi != null) {
-            umi.addUserLifecycleListener(new UserLifecycleListener() {
-                @Override
-                public void onUserCreated(UserInfo user, Object token) {
-                    if (DBG) Slogf.d(TAG, "onUserCreated(): %s", user.toFullString());
-                }
-                @Override
-                public void onUserRemoved(UserInfo user) {
-                    if (DBG) Slogf.d(TAG, "onUserRemoved(): $s", user.toFullString());
-                    mCarServiceHelperServiceUpdatable.onUserRemoved(user.getUserHandle());
-                }
-            });
-        } else {
-            Slogf.e(TAG, "UserManagerInternal not available - should only happen on unit tests");
-        }
-        mCarDevicePolicySafetyChecker = carDevicePolicySafetyChecker == null
-                ? new CarDevicePolicySafetyChecker(this)
-                : carDevicePolicySafetyChecker;
-    }
-
-    @Override
-    public void onBootPhase(int phase) {
-        EventLogHelper.writeCarHelperBootPhase(phase);
-        if (DBG) Slogf.d(TAG, "onBootPhase: %d", phase);
-
-        TimingsTraceAndSlog t = newTimingsTraceAndSlog();
-        if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
-            t.traceBegin("onBootPhase.3pApps");
-            mCarLaunchParamsModifier.init();
-            setupAndStartUsers(t);
-            t.traceEnd();
-        } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
-            t.traceBegin("onBootPhase.completed");
-            synchronized (mLock) {
-                mSystemBootCompleted = true;
-            }
-            try {
-                mCarWatchdogDaemonHelper.notifySystemStateChange(
-                        StateType.BOOT_PHASE, phase, /* arg2= */ 0);
-            } catch (RemoteException | RuntimeException e) {
-                Slogf.w(TAG, "Failed to notify boot phase change: %s", e);
-            }
-            t.traceEnd();
-        }
-    }
-
-    @Override
-    public void onStart() {
-        EventLogHelper.writeCarHelperStart();
-
-        mCarWatchdogDaemonHelper.addOnConnectionChangeListener(mConnectionListener);
-        mCarWatchdogDaemonHelper.connect();
-        mCarServiceHelperServiceUpdatable.onStart();
-    }
-
-    @Override
-    public void dump(PrintWriter pw, String[] args) {
-        // Usage: adb shell dumpsys system_server_dumper --name CarServiceHelper
-        if (args == null || args.length == 0 || args[0].equals("-a")) {
-            pw.printf("System boot completed: %b\n", mSystemBootCompleted);
-            pw.print("First unlocked user duration: ");
-            TimeUtils.formatDuration(mFirstUnlockedUserDuration, pw); pw.println();
-            pw.printf("Queued tasks: %d\n", mProcessTerminator.mQueuedTask);
-            mCarServiceHelperServiceUpdatable.dump(pw, args);
-            mCarDevicePolicySafetyChecker.dump(pw);
-            return;
-        }
-
-        if ("--is-operation-safe".equals(args[0]) & args.length > 1) {
-            String arg1 = args[1];
-            int operation = 0;
-            try {
-                operation = Integer.parseInt(arg1);
-            } catch (Exception e) {
-                pw.printf("Invalid operation type: %s\n", arg1);
-                return;
-
-            }
-            int reason = getUnsafeOperationReason(operation);
-            boolean safe = reason == DevicePolicyManager.OPERATION_SAFETY_REASON_NONE;
-            pw.printf("Operation %s is %s. Reason: %s\n",
-                    DevicePolicyManager.operationToString(operation),
-                    safe ? "SAFE" : "UNSAFE",
-                    DevicePolicyManager.operationSafetyReasonToString(reason));
-            return;
-        }
-
-        if ("--user-metrics-only".equals(args[0]) || "--dump-service-stacks".equals(args[0])) {
-            mCarServiceHelperServiceUpdatable.dump(pw, args);
-            return;
-        }
-
-        pw.printf("Invalid args: %s\n", Arrays.toString(args));
-    }
-
-    @Override
-    public String getDumpableName() {
-        return "CarServiceHelper";
-    }
-
-    @Override
-    public void onUserUnlocking(@NonNull TargetUser user) {
-        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_UNLOCKING)) return;
-        EventLogHelper.writeCarHelperUserUnlocking(user.getUserIdentifier());
-        if (DBG) Slogf.d(TAG, "onUserUnlocking(%s)", user);
-
-        mCarServiceHelperServiceUpdatable
-                .sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKING,
-                        /* userFrom= */ null, user.getUserHandle());
-    }
-
-    @Override
-    public void onUserUnlocked(@NonNull TargetUser user) {
-        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_UNLOCKED)) return;
-        int userId = user.getUserIdentifier();
-        EventLogHelper.writeCarHelperUserUnlocked(userId);
-        if (DBG) Slogf.d(TAG, "onUserUnlocked(%s)", user);
-
-        if (mFirstUnlockedUserDuration == 0 && !UserHelperLite.isHeadlessSystemUser(userId)) {
-            mFirstUnlockedUserDuration = SystemClock.elapsedRealtime()
-                    - Process.getStartElapsedRealtime();
-            Slogf.i(TAG, "Time to unlock 1st user(%s): %s", user,
-                    TimeUtils.formatDuration(mFirstUnlockedUserDuration));
-        }
-        mCarServiceHelperServiceUpdatable.sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED,
-                /* userFrom= */ null, user.getUserHandle());
-    }
-
-    @Override
-    public void onUserStarting(@NonNull TargetUser user) {
-        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_STARTING)) return;
-        EventLogHelper.writeCarHelperUserStarting(user.getUserIdentifier());
-        if (DBG) Slogf.d(TAG, "onUserStarting(%s)", user);
-
-        mCarServiceHelperServiceUpdatable.sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING,
-                /* userFrom= */ null, user.getUserHandle());
-        int userId = user.getUserIdentifier();
-        mCarLaunchParamsModifier.handleUserStarting(userId);
-    }
-
-    @Override
-    public void onUserStopping(@NonNull TargetUser user) {
-        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_STOPPING)) return;
-        EventLogHelper.writeCarHelperUserStopping(user.getUserIdentifier());
-        if (DBG) Slogf.d(TAG, "onUserStopping(%s)", user);
-
-        mCarServiceHelperServiceUpdatable.sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPING,
-                /* userFrom= */ null, user.getUserHandle());
-        int userId = user.getUserIdentifier();
-        mCarLaunchParamsModifier.handleUserStopped(userId);
-    }
-
-    @Override
-    public void onUserStopped(@NonNull TargetUser user) {
-        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_STOPPED)) return;
-        EventLogHelper.writeCarHelperUserStopped(user.getUserIdentifier());
-        if (DBG) Slogf.d(TAG, "onUserStopped(%s)", user);
-
-        mCarServiceHelperServiceUpdatable.sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPED,
-                /* userFrom= */ null, user.getUserHandle());
-    }
-
-    @Override
-    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
-        if (isPreCreated(to, USER_LIFECYCLE_EVENT_TYPE_SWITCHING)) return;
-        EventLogHelper.writeCarHelperUserSwitching(
-                from == null ? UserHandle.USER_NULL : from.getUserIdentifier(),
-                to.getUserIdentifier());
-        if (DBG) Slogf.d(TAG, "onUserSwitching(%s>>%s)", from, to);
-
-        mCarServiceHelperServiceUpdatable.sendUserLifecycleEvent(
-                USER_LIFECYCLE_EVENT_TYPE_SWITCHING, from.getUserHandle(),
-                to.getUserHandle());
-        int userId = to.getUserIdentifier();
-        mCarLaunchParamsModifier.handleCurrentUserSwitching(userId);
-    }
-
-    @Override
-    public void onUserCompletedEvent(TargetUser user, UserCompletedEventType eventType) {
-        if (user.isPreCreated()) {
-            if (DBG) {
-                Slogf.d(TAG, "Ignoring USER_COMPLETED event %s for pre-created user %s",
-                        eventType, user);
-            }
-            return;
-        }
-
-        UserHandle handle = user.getUserHandle();
-        if (eventType.includesOnUserUnlocked()) {
-            mCarServiceHelperServiceUpdatable.sendUserLifecycleEvent(
-                    USER_LIFECYCLE_EVENT_TYPE_POST_UNLOCKED, /* userFrom= */ null, handle);
-        }
-    }
-
-    @Override // from DevicePolicySafetyChecker
-    @OperationSafetyReason
-    public int getUnsafeOperationReason(@DevicePolicyOperation int operation) {
-        return mCarDevicePolicySafetyChecker.isDevicePolicyOperationSafe(operation)
-                ? DevicePolicyManager.OPERATION_SAFETY_REASON_NONE
-                : DevicePolicyManager.OPERATION_SAFETY_REASON_DRIVING_DISTRACTION;
-    }
-
-    @Override // from DevicePolicySafetyChecker
-    public boolean isSafeOperation(@OperationSafetyReason int reason) {
-        return mCarDevicePolicySafetyChecker.isSafe();
-    }
-
-    @Override // from DevicePolicySafetyChecker
-    public void onFactoryReset(IResultReceiver callback) {
-        if (DBG) Slogf.d(TAG, "onFactoryReset: %s", callback);
-        if (callback != null) {
-            mCarServiceHelperServiceUpdatable.onFactoryReset((resultCode, resultData) -> {
-                try {
-                    callback.send(resultCode, resultData);
-                } catch (RemoteException e) {
-                    Slogf.w(TAG, e,
-                            "Callback to DevicePolicySafetyChecker threw RemoteException");
-                }
-            });
-        }
-    }
-
-    private boolean isPreCreated(@NonNull TargetUser user, @UserLifecycleEventType int eventType) {
-        if (!user.isPreCreated()) return false;
-
-        if (DBG) {
-            Slogf.d(TAG, "Ignoring event of type %d for pre-created user %s", eventType, user);
-        }
-        return true;
-    }
-
-    private TimingsTraceAndSlog newTimingsTraceAndSlog() {
-        return new TimingsTraceAndSlog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
-    }
-
-    private void setupAndStartUsers(@NonNull TimingsTraceAndSlog t) {
-        // TODO(b/156263735): decide if it should return in case the device's on Retail Mode
-        t.traceBegin("setupAndStartUsers");
-        mCarServiceHelperServiceUpdatable.initBootUser();
-        t.traceEnd();
-    }
-
-    // Adapted from frameworks/base/services/core/java/com/android/server/Watchdog.java
-    // TODO(b/131861630) use implementation common with Watchdog.java
-    //
-    private static ArrayList<Integer> getInterestingHalPids() {
-        try {
-            IServiceManager serviceManager = IServiceManager.getService();
-            ArrayList<IServiceManager.InstanceDebugInfo> dump =
-                    serviceManager.debugDump();
-            HashSet<Integer> pids = new HashSet<>();
-            for (IServiceManager.InstanceDebugInfo info : dump) {
-                if (info.pid == IServiceManager.PidConstant.NO_PID) {
-                    continue;
-                }
-
-                if (Watchdog.HAL_INTERFACES_OF_INTEREST.contains(info.interfaceName) ||
-                        CAR_HAL_INTERFACES_OF_INTEREST.contains(info.interfaceName)) {
-                    pids.add(info.pid);
-                }
-            }
-
-            return new ArrayList<Integer>(pids);
-        } catch (RemoteException e) {
-            return new ArrayList<Integer>();
-        }
-    }
-
-    // Adapted from frameworks/base/services/core/java/com/android/server/Watchdog.java
-    // TODO(b/131861630) use implementation common with Watchdog.java
-    //
-    private static ArrayList<Integer> getInterestingNativePids() {
-        ArrayList<Integer> pids = getInterestingHalPids();
-
-        int[] nativePids = Process.getPidsForCommands(Watchdog.NATIVE_STACKS_OF_INTEREST);
-        if (nativePids != null) {
-            pids.ensureCapacity(pids.size() + nativePids.length);
-            for (int i : nativePids) {
-                pids.add(i);
-            }
-        }
-
-        return pids;
-    }
-
-    /**
-     * Dumps service stack
-     */
-    // Borrowed from Watchdog.java.  Create an ANR file from the call stacks.
-    @Override
-    @Nullable
-    public File dumpServiceStacks() {
-        ArrayList<Integer> pids = new ArrayList<>();
-        pids.add(Process.myPid());
-
-        return ActivityManagerService.dumpStackTraces(
-                pids, null, null, getInterestingNativePids(), null);
-    }
-
-    private void handleClientsNotResponding(@NonNull List<ProcessIdentifier> processIdentifiers) {
-        mProcessTerminator.requestTerminateProcess(processIdentifiers);
-    }
-
-    private void registerMonitorToWatchdogDaemon() {
-        try {
-            mCarWatchdogDaemonHelper.registerMonitor(mCarWatchdogMonitor);
-            synchronized (mLock) {
-                if (!mSystemBootCompleted) {
-                    return;
-                }
-            }
-            mCarWatchdogDaemonHelper.notifySystemStateChange(
-                    StateType.BOOT_PHASE, SystemService.PHASE_BOOT_COMPLETED, /* arg2= */ 0);
-        } catch (RemoteException | RuntimeException e) {
-            Slogf.w(TAG, "Cannot register to car watchdog daemon: %s", e);
-        }
-    }
-
-    private void killProcessAndReportToMonitor(ProcessIdentifier processIdentifier) {
-        ProcessInfo processInfo = getProcessInfo(processIdentifier.pid);
-        if (!processInfo.doMatch(processIdentifier.pid, processIdentifier.startTimeMillis)) {
-            return;
-        }
-        String cmdline = getProcessCmdLine(processIdentifier.pid);
-        Process.killProcess(processIdentifier.pid);
-        Slogf.w(TAG, "carwatchdog killed %s %s", cmdline, processInfo);
-        try {
-            mCarWatchdogDaemonHelper.tellDumpFinished(mCarWatchdogMonitor, processIdentifier);
-        } catch (RemoteException | RuntimeException e) {
-            Slogf.w(TAG, "Cannot report monitor result to car watchdog daemon: %s", e);
-        }
-    }
-
-    private static String getProcessCmdLine(int pid) {
-        String filename = "/proc/" + pid + "/cmdline";
-        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
-            String line = reader.readLine().replace('\0', ' ').trim();
-            int index = line.indexOf(' ');
-            if (index != -1) {
-                line = line.substring(0, index);
-            }
-            return Paths.get(line).getFileName().toString();
-        } catch (IOException | RuntimeException e) {
-            Slogf.w(TAG, "Cannot read %s", filename);
-            return ProcessInfo.UNKNOWN_PROCESS;
-        }
-    }
-
-    private ProcessInfo getProcessInfo(int pid) {
-        String filename = "/proc/" + pid + "/stat";
-        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
-            String line = reader.readLine().replace('\0', ' ').trim();
-            Matcher m = mProcPidStatPattern.matcher(line);
-            if (m.find()) {
-                int readPid = Integer.parseInt(Objects.requireNonNull(m.group("pid")));
-                if (readPid == pid) {
-                    return new ProcessInfo(pid, m.group("name"),
-                            Long.parseLong(Objects.requireNonNull(m.group("startClockTicks"))));
-                }
-            }
-        } catch (IOException | RuntimeException e) {
-            Slogf.w(TAG, e, "Cannot read %s", filename);
-        }
-        return new ProcessInfo(pid, ProcessInfo.UNKNOWN_PROCESS, ProcessInfo.INVALID_START_TIME);
-    }
-
-    @Override
-    public void setSafetyMode(boolean safe) {
-        mCarDevicePolicySafetyChecker.setSafe(safe);
-    }
-
-    @Override
-    public UserHandle createUserEvenWhenDisallowed(String name, String userType, int flags) {
-        if (DBG) {
-            Slogf.d(TAG, "createUserEvenWhenDisallowed(): name=%s, type=%s, flags=%s",
-                    UserHelperLite.safeName(name), userType, UserInfo.flagsToString(flags));
-        }
-        UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
-        try {
-            UserInfo user = umi.createUserEvenWhenDisallowed(name, userType, flags,
-                    /* disallowedPackages= */ null, /* token= */ null);
-            if (DBG) {
-                Slogf.d(TAG, "User created: %s", (user == null ? "null" : user.toFullString()));
-            }
-            // TODO(b/172691310): decide if user should be affiliated when DeviceOwner is set
-            return user.getUserHandle();
-        } catch (UserManager.CheckedUserOperationException e) {
-            Slogf.e(TAG, e, "Error creating user");
-            return null;
-        }
-    }
-
-    private class ICarWatchdogMonitorImpl extends ICarWatchdogMonitor.Stub {
-        private final WeakReference<CarServiceHelperService> mService;
-
-        private ICarWatchdogMonitorImpl(CarServiceHelperService service) {
-            mService = new WeakReference<>(service);
-        }
-
-        @Override
-        public void onClientsNotResponding(List<ProcessIdentifier> processIdentifiers) {
-            CarServiceHelperService service = mService.get();
-            if (service == null || processIdentifiers == null || processIdentifiers.isEmpty()) {
-                return;
-            }
-            service.handleClientsNotResponding(processIdentifiers);
-        }
-
-        @Override
-        public String getInterfaceHash() {
-            return ICarWatchdogMonitor.HASH;
-        }
-
-        @Override
-        public int getInterfaceVersion() {
-            return ICarWatchdogMonitor.VERSION;
-        }
-    }
-
-    private final class ProcessTerminator {
-
-        private static final long ONE_SECOND_MS = 1_000L;
-
-        private final Object mProcessLock = new Object();
-        private ExecutorService mExecutor;
-        @GuardedBy("mProcessLock")
-        private int mQueuedTask;
-
-        public void requestTerminateProcess(@NonNull List<ProcessIdentifier> processIdentifiers) {
-            synchronized (mProcessLock) {
-                // If there is a running thread, we re-use it instead of starting a new thread.
-                if (mExecutor == null) {
-                    mExecutor = Executors.newSingleThreadExecutor();
-                }
-                mQueuedTask++;
-            }
-            mExecutor.execute(() -> {
-                for (int i = 0; i < processIdentifiers.size(); i++) {
-                    ProcessIdentifier processIdentifier = processIdentifiers.get(i);
-                    ProcessInfo processInfo = getProcessInfo(processIdentifier.pid);
-                    if (processInfo.doMatch(processIdentifier.pid,
-                            processIdentifier.startTimeMillis)) {
-                        dumpAndKillProcess(processIdentifier);
-                    }
-                }
-                // mExecutor will be stopped from the main thread, if there is no queued task.
-                mHandler.sendMessage(obtainMessage(ProcessTerminator::postProcessing, this)
-                        .setWhat(WHAT_POST_PROCESS_DUMPING));
-            });
-        }
-
-        private void postProcessing() {
-            synchronized (mProcessLock) {
-                mQueuedTask--;
-                if (mQueuedTask == 0) {
-                    mExecutor.shutdown();
-                    mExecutor = null;
-                }
-            }
-        }
-
-        private void dumpAndKillProcess(ProcessIdentifier processIdentifier) {
-            if (DBG) {
-                Slogf.d(TAG, "Dumping and killing process(pid: %d)", processIdentifier.pid);
-            }
-            ArrayList<Integer> javaPids = new ArrayList<>(1);
-            ArrayList<Integer> nativePids = new ArrayList<>();
-            try {
-                if (isJavaApp(processIdentifier.pid)) {
-                    javaPids.add(processIdentifier.pid);
-                } else {
-                    nativePids.add(processIdentifier.pid);
-                }
-            } catch (IOException e) {
-                Slogf.w(TAG, "Cannot get process information: %s", e);
-                return;
-            }
-            nativePids.addAll(getInterestingNativePids());
-            long startDumpTime = SystemClock.uptimeMillis();
-            ActivityManagerService.dumpStackTraces(javaPids, null, null, nativePids, null);
-            long dumpTime = SystemClock.uptimeMillis() - startDumpTime;
-            if (DBG) {
-                Slogf.d(TAG, "Dumping process took %dms", dumpTime);
-            }
-            // To give clients a chance of wrapping up before the termination.
-            if (dumpTime < ONE_SECOND_MS) {
-                mHandler.sendMessageDelayed(obtainMessage(
-                        CarServiceHelperService::killProcessAndReportToMonitor,
-                        CarServiceHelperService.this, processIdentifier).setWhat(WHAT_PROCESS_KILL),
-                        ONE_SECOND_MS - dumpTime);
-            } else {
-                killProcessAndReportToMonitor(processIdentifier);
-            }
-        }
-
-        private boolean isJavaApp(int pid) throws IOException {
-            Path exePath = new File("/proc/" + pid + "/exe").toPath();
-            String target = Files.readSymbolicLink(exePath).toString();
-            // Zygote's target exe is also /system/bin/app_process32 or /system/bin/app_process64.
-            // But, we can be very sure that Zygote will not be the client of car watchdog daemon.
-            return target.equals("/system/bin/app_process32") ||
-                    target.equals("/system/bin/app_process64");
-        }
-    }
-
-    private static final class ProcessInfo {
-        public static final String UNKNOWN_PROCESS = "unknown process";
-        public static final int INVALID_START_TIME = -1;
-
-        private static final long MILLIS_PER_JIFFY = 1000L / Os.sysconf(OsConstants._SC_CLK_TCK);
-
-        public final int pid;
-        public final String name;
-        public final long startTimeMillis;
-
-        ProcessInfo(int pid, String name, long startClockTicks) {
-            this.pid = pid;
-            this.name = name;
-            this.startTimeMillis = startClockTicks != INVALID_START_TIME
-                    ? startClockTicks * MILLIS_PER_JIFFY : INVALID_START_TIME;
-        }
-
-        boolean doMatch(int pid, long startTimeMillis) {
-            // Start time reported by the services that monitor the process health will be either
-            // the actual start time of the pid or the elapsed real time when the pid was last seen
-            // alive. Thus, verify whether the given start time is at least the actual start time of
-            // the pid.
-            return this.pid == pid && (this.startTimeMillis == INVALID_START_TIME
-                    || this.startTimeMillis <= startTimeMillis);
-        }
-
-        @Override
-        public String toString() {
-            return new StringBuilder("ProcessInfo { pid = ").append(pid)
-                    .append(", name = ").append(name)
-                    .append(", startTimeMillis = ")
-                    .append(startTimeMillis != INVALID_START_TIME ? startTimeMillis : "invalid")
-                    .append(" }").toString();
-        }
-    }
-}
diff --git a/builtInServices/src/com/android/internal/car/CarServiceHelperServiceUpdatable.java b/builtInServices/src/com/android/internal/car/CarServiceHelperServiceUpdatable.java
deleted file mode 100644
index 175da48..0000000
--- a/builtInServices/src/com/android/internal/car/CarServiceHelperServiceUpdatable.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2021 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.internal.car;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Bundle;
-import android.os.UserHandle;
-
-import com.android.server.wm.CarLaunchParamsModifierUpdatable;
-
-import java.io.PrintWriter;
-import java.util.function.BiConsumer;
-
-/**
- * Contains calls from CarServiceHelperService (which is a built-in class) to
- * CarServiceHelperServiceUpdatableImpl (which is a updatable class as part of car-module).
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public interface CarServiceHelperServiceUpdatable {
-
-    void onUserRemoved(@NonNull UserHandle userHandle);
-
-    void onStart();
-
-    void dump(@NonNull PrintWriter pw, @Nullable String[] args);
-
-    void sendUserLifecycleEvent(int eventType, @Nullable UserHandle userFrom,
-            @NonNull UserHandle userTo);
-
-    void onFactoryReset(@NonNull BiConsumer<Integer, Bundle> processFactoryReset);
-
-    void initBootUser();
-
-    CarLaunchParamsModifierUpdatable getCarLaunchParamsModifierUpdatable();
-}
diff --git a/builtInServices/src/com/android/server/wm/ActivityOptionsWrapper.java b/builtInServices/src/com/android/server/wm/ActivityOptionsWrapper.java
deleted file mode 100644
index f9dc751..0000000
--- a/builtInServices/src/com/android/server/wm/ActivityOptionsWrapper.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.SystemApi;
-import android.app.ActivityOptions;
-import android.window.WindowContainerToken;
-
-/**
- * Wrapper of {@link ActivityOptions}.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class ActivityOptionsWrapper {
-    private final ActivityOptions mOptions;
-
-    private ActivityOptionsWrapper(ActivityOptions options) {
-        mOptions = options;
-    }
-
-    /** @hide */
-    public static ActivityOptionsWrapper create(ActivityOptions options) {
-        if (options == null) return null;
-        return new ActivityOptionsWrapper(options);
-    }
-
-    /**
-     * Gets the underlying {@link ActivityOptions} that is wrapped by this instance.
-     */
-    // Exposed the original object in order to allow to use the public accessors.
-    public ActivityOptions getOptions() {
-        return mOptions;
-    }
-
-    /**
-     * Gets {@link TaskDisplayAreaWrapper} to launch the Activity into
-     */
-    public TaskDisplayAreaWrapper getLaunchTaskDisplayArea() {
-        WindowContainerToken daToken = mOptions.getLaunchTaskDisplayArea();
-        if (daToken == null) return null;
-        TaskDisplayArea tda = (TaskDisplayArea) WindowContainer.fromBinder(daToken.asBinder());
-        return TaskDisplayAreaWrapper.create(tda);
-    }
-
-    @Override
-    public String toString() {
-        return mOptions.toString();
-    }
-}
diff --git a/builtInServices/src/com/android/server/wm/ActivityRecordWrapper.java b/builtInServices/src/com/android/server/wm/ActivityRecordWrapper.java
deleted file mode 100644
index bd15a54..0000000
--- a/builtInServices/src/com/android/server/wm/ActivityRecordWrapper.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.content.ComponentName;
-import android.content.pm.ActivityInfo;
-
-/**
- * Wrapper of {@link ActivityRecord}.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class ActivityRecordWrapper {
-    private final ActivityRecord mActivityRecord;
-
-    private ActivityRecordWrapper(ActivityRecord activityRecord) {
-        mActivityRecord = activityRecord;
-    }
-
-    /** @hide */
-    public static ActivityRecordWrapper create(@Nullable ActivityRecord activityRecord) {
-        if (activityRecord == null) return null;
-        return new ActivityRecordWrapper(activityRecord);
-    }
-
-    /** @hide */
-    public ActivityRecord getActivityRecord() {
-        return mActivityRecord;
-    }
-
-    /**
-     * Gets which user this Activity is running for.
-     */
-    public int getUserId() {
-        return mActivityRecord.mUserId;
-    }
-
-    /**
-     * Gets the actual {@link ComponentName} of this Activity.
-     */
-    public ComponentName getComponentName() {
-        if (mActivityRecord.info == null) return null;
-        return mActivityRecord.info.getComponentName();
-    }
-
-    /**
-     * Gets the {@link TaskDisplayAreaWrapper} where this is located.
-     */
-    public TaskDisplayAreaWrapper getDisplayArea() {
-        return TaskDisplayAreaWrapper.create(mActivityRecord.getDisplayArea());
-    }
-
-    /**
-     * Returns whether this Activity is not displayed.
-     */
-    public boolean isNoDisplay() {
-        return mActivityRecord.noDisplay;
-    }
-
-    /**
-     * Gets {@link TaskDisplayAreaWrapper} where the handover Activity is supposed to launch
-     */
-    public TaskDisplayAreaWrapper getHandoverTaskDisplayArea() {
-        return TaskDisplayAreaWrapper.create(mActivityRecord.mHandoverTaskDisplayArea);
-    }
-
-    /**
-     * Gets {@code displayId} where the handover Activity is supposed to launch
-     */
-    public int getHandoverLaunchDisplayId() {
-        return mActivityRecord.mHandoverLaunchDisplayId;
-    }
-
-    /**
-     * Returns whether this Activity allows to be embedded in the other Activity.
-     */
-    public boolean allowingEmbedded() {
-        if (mActivityRecord.info == null) return false;
-        return (mActivityRecord.info.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) != 0;
-    }
-
-    /**
-     * Returns whether the display where this Activity is located is trusted.
-     */
-    public boolean isDisplayTrusted() {
-        return mActivityRecord.getDisplayContent().isTrusted();
-    }
-
-    @Override
-    public String toString() {
-        return mActivityRecord.toString();
-    }
-}
diff --git a/builtInServices/src/com/android/server/wm/CalculateParams.java b/builtInServices/src/com/android/server/wm/CalculateParams.java
deleted file mode 100644
index 8b4faff..0000000
--- a/builtInServices/src/com/android/server/wm/CalculateParams.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.SystemApi;
-import android.app.ActivityOptions;
-import android.content.pm.ActivityInfo;
-import android.view.WindowLayout;
-
-/**
- * Wrapper of the parameters of {@code LaunchParamsController.LaunchParamsModifier.onCalculate()}
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class CalculateParams {
-    private TaskWrapper mTask;
-    private WindowLayoutWrapper mLayout;
-    private ActivityRecordWrapper mActivity;
-    private ActivityRecordWrapper mSource;
-    private ActivityOptionsWrapper mOptions;
-    private RequestWrapper mRequest;
-    private int mPhase;
-    private LaunchParamsWrapper mCurrentParams;
-    private LaunchParamsWrapper mOutParams;
-    private boolean mSupportsMultiDisplay;
-
-    private CalculateParams() {}
-
-    /** @hide */
-    public static CalculateParams create(Task task, ActivityInfo.WindowLayout layout,
-            ActivityRecord actvity, ActivityRecord source,
-            ActivityOptions options, ActivityStarter.Request request, int phase,
-            LaunchParamsController.LaunchParams currentParams,
-            LaunchParamsController.LaunchParams outParms,
-            boolean supportsMultiDisplay) {
-        CalculateParams params = new CalculateParams();
-        params.mTask = TaskWrapper.create(task);
-        params.mLayout = WindowLayoutWrapper.create(layout);
-        params.mActivity = ActivityRecordWrapper.create(actvity);
-        params.mSource = ActivityRecordWrapper.create(source);
-        params.mOptions = ActivityOptionsWrapper.create(options);
-        params.mRequest = RequestWrapper.create(request);
-        params.mPhase = phase;
-        params.mCurrentParams = LaunchParamsWrapper.create(currentParams);
-        params.mOutParams = LaunchParamsWrapper.create(outParms);
-        params.mSupportsMultiDisplay = supportsMultiDisplay;
-        return params;
-    }
-
-    /**
-     * Gets the {@link TaskWrapper} currently being positioned.
-     */
-    public TaskWrapper getTask() {
-        return mTask;
-    }
-
-    /**
-     * Gets the specified {@link WindowLayoutWrapper}.
-     */
-    public WindowLayoutWrapper getWindowLayout() {
-        return mLayout;
-    }
-
-    /**
-     * Gets the {@link ActivityRecordWrapper} currently being positioned.
-     */
-    public ActivityRecordWrapper getActivity() {
-        return mActivity;
-    }
-
-    /**
-     * Gets the {@link ActivityRecordWrapper} from which activity was started from.
-     */
-    public ActivityRecordWrapper getSource() {
-        return mSource;
-    }
-
-    /**
-     * Gets the {@link ActivityOptionsWrapper} specified for the activity.
-     */
-    public ActivityOptionsWrapper getOptions() {
-        return mOptions;
-    }
-
-    /**
-     * Gets the optional {@link RequestWrapper} from the activity starter.
-     */
-    public RequestWrapper getRequest() {
-        return mRequest;
-    }
-
-    /**
-     * Gets the {@link LaunchParamsController.LaunchParamsModifier.Phase} that the resolution should
-     * finish.
-     */
-    public int getPhase() {
-        return mPhase;
-    }
-
-    /**
-     * Gets the current {@link LaunchParamsWrapper}.
-     */
-    public LaunchParamsWrapper getCurrentParams() {
-        return mCurrentParams;
-    }
-
-    /**
-     * Gets the resulting {@link LaunchParamsWrapper}.
-     */
-    public LaunchParamsWrapper getOutParams() {
-        return mOutParams;
-    }
-
-    /**
-     * Returns whether the current system supports the multiple display.
-     */
-    public boolean supportsMultiDisplay() {
-        return mSupportsMultiDisplay;
-    }
-}
diff --git a/builtInServices/src/com/android/server/wm/CarDisplayAreaPolicyProvider.java b/builtInServices/src/com/android/server/wm/CarDisplayAreaPolicyProvider.java
deleted file mode 100644
index ea4a4bf..0000000
--- a/builtInServices/src/com/android/server/wm/CarDisplayAreaPolicyProvider.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2021 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.wm;
-
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
-import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
-import static android.window.DisplayAreaOrganizer.FEATURE_IME_PLACEHOLDER;
-import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provider for platform-default car display area policy for reference design.
- *
- * @hide
- */
-public class CarDisplayAreaPolicyProvider implements DisplayAreaPolicy.Provider {
-
-    /**
-     * This display area is mandatory to be defined. This is where the applications will be
-     * launched.
-     */
-    private static final int DEFAULT_APP_TASK_CONTAINER = FEATURE_DEFAULT_TASK_CONTAINER;
-
-    /**
-     * The display partition to launch applications by default. This contains {@link
-     * #DEFAULT_APP_TASK_CONTAINER}.
-     */
-    private static final int FOREGROUND_DISPLAY_AREA_ROOT = FEATURE_VENDOR_FIRST + 1;
-
-    /**
-     * Background applications task container.
-     */
-    private static final int BACKGROUND_TASK_CONTAINER = FEATURE_VENDOR_FIRST + 2;
-    private static final int FEATURE_TASKDISPLAYAREA_PARENT = FEATURE_VENDOR_FIRST + 3;
-
-    /**
-     * Control bar task container.
-     *
-     * Currently we are launching CarLauncher activity in this TDA. This is because the audio card
-     * implementation today is using fragments. If that changes in future then we can use the window
-     * instead to display that view instead of fragments that need an activity.
-     */
-    private static final int CONTROL_BAR_DISPLAY_AREA = FEATURE_VENDOR_FIRST + 4;
-
-    /**
-     * Feature to display the title bar.
-     */
-    private static final int FEATURE_TITLE_BAR = FEATURE_VENDOR_FIRST + 5;
-
-    /**
-     * Feature to display voice plate.
-     */
-    private static final int FEATURE_VOICE_PLATE = FEATURE_VENDOR_FIRST + 6;
-
-    @Override
-    public DisplayAreaPolicy instantiate(WindowManagerService wmService, DisplayContent content,
-            RootDisplayArea root, DisplayArea.Tokens imeContainer) {
-
-        if (!content.isDefaultDisplay) {
-            return new DisplayAreaPolicy.DefaultProvider().instantiate(wmService, content, root,
-                    imeContainer);
-        }
-
-        TaskDisplayArea backgroundTaskDisplayArea = new TaskDisplayArea(content, wmService,
-                "BackgroundTaskDisplayArea", BACKGROUND_TASK_CONTAINER,
-                /* createdByOrganizer= */ false, /* canHostHomeTask= */ false);
-
-        TaskDisplayArea controlBarDisplayArea = new TaskDisplayArea(content, wmService,
-                "ControlBarTaskDisplayArea", CONTROL_BAR_DISPLAY_AREA,
-                /* createdByOrganizer= */ false, /* canHostHomeTask= */ false);
-
-        TaskDisplayArea voicePlateTaskDisplayArea = new TaskDisplayArea(content, wmService,
-                "VoicePlateTaskDisplayArea", FEATURE_VOICE_PLATE,
-                /* createdByOrganizer= */ false, /* canHostHomeTask= */ false);
-
-        List<TaskDisplayArea> backgroundTdaList = new ArrayList<>();
-        backgroundTdaList.add(voicePlateTaskDisplayArea);
-        backgroundTdaList.add(backgroundTaskDisplayArea);
-        backgroundTdaList.add(controlBarDisplayArea);
-
-        // Root
-        DisplayAreaPolicyBuilder.HierarchyBuilder rootHierarchy =
-                new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
-                        .setTaskDisplayAreas(backgroundTdaList)
-                        .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy,
-                                "ImePlaceholder", FEATURE_IME_PLACEHOLDER)
-                                .and(TYPE_INPUT_METHOD, TYPE_INPUT_METHOD_DIALOG)
-                                .build())
-                        // to make sure there are 2 children under root.
-                        // TODO: replace when b/188102153 is resolved to set this to top.
-                        .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy,
-                                "TaskDisplayAreaParent", FEATURE_TASKDISPLAYAREA_PARENT)
-                                .and(TYPE_APPLICATION)
-                                .build());
-
-        // Default application launches here
-        RootDisplayArea defaultAppsRoot = new DisplayAreaGroup(wmService,
-                "FeatureForegroundApplication", FOREGROUND_DISPLAY_AREA_ROOT);
-        TaskDisplayArea defaultAppTaskDisplayArea = new TaskDisplayArea(content, wmService,
-                "DefaultApplicationTaskDisplayArea", DEFAULT_APP_TASK_CONTAINER);
-        List<TaskDisplayArea> firstTdaList = new ArrayList<>();
-        firstTdaList.add(defaultAppTaskDisplayArea);
-        DisplayAreaPolicyBuilder.HierarchyBuilder applicationHierarchy =
-                new DisplayAreaPolicyBuilder.HierarchyBuilder(defaultAppsRoot)
-                        .setTaskDisplayAreas(firstTdaList)
-                        .setImeContainer(imeContainer)
-                        .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy,
-                                "ImePlaceholder", FEATURE_IME_PLACEHOLDER)
-                                .and(TYPE_INPUT_METHOD, TYPE_INPUT_METHOD_DIALOG)
-                                .build())
-                        .addFeature(new DisplayAreaPolicyBuilder.Feature.Builder(wmService.mPolicy,
-                                "TitleBar", FEATURE_TITLE_BAR)
-                                .and(TYPE_APPLICATION_OVERLAY)
-                                .build());
-
-        return new DisplayAreaPolicyBuilder()
-                .setRootHierarchy(rootHierarchy)
-                .addDisplayAreaGroupHierarchy(applicationHierarchy)
-                .build(wmService);
-    }
-}
diff --git a/builtInServices/src/com/android/server/wm/CarLaunchParamsModifier.java b/builtInServices/src/com/android/server/wm/CarLaunchParamsModifier.java
deleted file mode 100644
index 6472ffb..0000000
--- a/builtInServices/src/com/android/server/wm/CarLaunchParamsModifier.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2019 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.wm;
-
-import static com.android.server.wm.ActivityStarter.Request;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
-import android.app.ActivityOptions;
-import android.app.ActivityTaskManager;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
-import android.hardware.display.DisplayManager;
-import android.os.Handler;
-import android.os.Looper;
-import android.view.Display;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Class to control the assignment of a display for Car while launching a Activity.
- *
- * <p>This one controls which displays users are allowed to launch.
- * The policy should be passed from car service through
- * {@link com.android.internal.car.ICarServiceHelper} binder interfaces. If no policy is set,
- * this module will not change anything for launch process.</p>
- *
- * <p> The policy can only affect which display passenger users can use. Current user, assumed
- * to be a driver user, is allowed to launch any display always.</p>
- *
- * @hide
- */
-public final class CarLaunchParamsModifier implements LaunchParamsController.LaunchParamsModifier {
-
-    private final Context mContext;
-
-    private DisplayManager mDisplayManager;  // set only from init()
-    private ActivityTaskManagerService mAtm;  // set only from init()
-
-    private CarLaunchParamsModifierUpdatable mUpdatable;
-
-    // getFallbackDisplayAreasForActivity() can return the most 3 {@link TaskDisplayAreaWrapper}.
-    private final ArrayList<TaskDisplayAreaWrapper> mFallBackDisplayAreaList = new ArrayList<>(3);
-
-    /** Constructor. Can be constructed any time. */
-    public CarLaunchParamsModifier(Context context) {
-        // This can be very early stage. So postpone interaction with other system until init.
-        mContext = context;
-    }
-
-    public void setUpdatable(CarLaunchParamsModifierUpdatable updatable) {
-        mUpdatable = updatable;
-    }
-
-    public CarLaunchParamsModifierInterface getBuiltinInterface() {
-        return mBuiltinInterface;
-    }
-
-    /**
-     * Initializes all internal stuffs. This should be called only after ATMS, DisplayManagerService
-     * are ready.
-     */
-    public void init() {
-        mAtm = (ActivityTaskManagerService) ActivityTaskManager.getService();
-        LaunchParamsController controller = mAtm.mTaskSupervisor.getLaunchParamsController();
-        controller.registerModifier(this);
-        mDisplayManager = mContext.getSystemService(DisplayManager.class);
-        mDisplayManager.registerDisplayListener(mUpdatable.getDisplayListener(),
-                new Handler(Looper.getMainLooper()));
-    }
-
-    /** Notifies user switching. */
-    public void handleUserStarting(@UserIdInt int startingUserId) {
-        mUpdatable.handleUserStarting(startingUserId);
-    }
-
-    /** Notifies user switching. */
-    public void handleCurrentUserSwitching(@UserIdInt int newUserId) {
-        mUpdatable.handleCurrentUserSwitching(newUserId);
-    }
-
-    /** Notifies user stopped. */
-    public void handleUserStopped(@UserIdInt int stoppedUser) {
-        mUpdatable.handleUserStopped(stoppedUser);
-    }
-
-    /**
-     * Decides display to assign while an Activity is launched.
-     *
-     * <p>For current user (=driver), launching to any display is allowed as long as system
-     * allows it.</p>
-     *
-     * <p>For private display, do not change anything as private display has its own logic.</p>
-     *
-     * <p>For passenger displays, only run in allowed displays. If requested display is not
-     * allowed, change to the 1st allowed display.</p>
-     */
-    @Override
-    @Result
-    public int onCalculate(@Nullable Task task, @Nullable ActivityInfo.WindowLayout layout,
-            @Nullable ActivityRecord activity, @Nullable ActivityRecord source,
-            ActivityOptions options, @Nullable Request request, int phase,
-            LaunchParamsController.LaunchParams currentParams,
-            LaunchParamsController.LaunchParams outParams) {
-        CalculateParams params = CalculateParams.create(task, layout, activity, source,
-                options, request, phase, currentParams, outParams, mAtm.mSupportsMultiDisplay);
-        return mUpdatable.calculate(params);
-    }
-
-    @Nullable
-    private TaskDisplayAreaWrapper getDefaultTaskDisplayAreaOnDisplay(int displayId) {
-        if (displayId == Display.INVALID_DISPLAY) {
-            return null;
-        }
-        DisplayContent dc = mAtm.mRootWindowContainer.getDisplayContentOrCreate(displayId);
-        if (dc == null) {
-            return null;
-        }
-        return TaskDisplayAreaWrapper.create(dc.getDefaultTaskDisplayArea());
-    }
-
-    /**
-     * Calculates the default {@link TaskDisplayAreaWrapper} for a task. We attempt to put
-     * the activity within the same display area if possible. The strategy is to find the display
-     * in the following order:
-     *
-     * <ol>
-     *     <li>The display area of the top activity from the launching process will be used</li>
-     *     <li>The display area of the top activity from the real launching process will be used
-     *     </li>
-     *     <li>Default display area from the associated root window container.</li>
-     * </ol>
-     * @param activityRecordWrapper the activity being started
-     * @param requestWrapper optional {@link RequestWrapper} made to start the activity record
-     * @return the list of {@link TaskDisplayAreaWrapper} to house the task
-     */
-    private List<TaskDisplayAreaWrapper> getFallbackDisplayAreasForActivity(
-            @NonNull ActivityRecordWrapper activityRecordWrapper,
-            @Nullable RequestWrapper requestWrapper) {
-        ActivityRecord activityRecord = activityRecordWrapper.getActivityRecord();
-        Request request = requestWrapper != null ? requestWrapper.getRequest() : null;
-        mFallBackDisplayAreaList.clear();
-
-        WindowProcessController controllerFromLaunchingRecord = mAtm.getProcessController(
-                activityRecord.launchedFromPid, activityRecord.launchedFromUid);
-        TaskDisplayArea displayAreaForLaunchingRecord = controllerFromLaunchingRecord == null
-                ? null : controllerFromLaunchingRecord.getTopActivityDisplayArea();
-        if (displayAreaForLaunchingRecord != null) {
-            mFallBackDisplayAreaList.add(
-                    TaskDisplayAreaWrapper.create(displayAreaForLaunchingRecord));
-        }
-
-        WindowProcessController controllerFromProcess = mAtm.getProcessController(
-                activityRecord.getProcessName(), activityRecord.getUid());
-        TaskDisplayArea displayAreaForRecord = controllerFromProcess == null ? null
-                : controllerFromProcess.getTopActivityDisplayArea();
-        if (displayAreaForRecord != null) {
-            mFallBackDisplayAreaList.add(TaskDisplayAreaWrapper.create(displayAreaForRecord));
-        }
-
-        WindowProcessController controllerFromRequest =
-                request == null ? null : mAtm.getProcessController(request.realCallingPid,
-                        request.realCallingUid);
-        TaskDisplayArea displayAreaFromSourceProcess = controllerFromRequest == null ? null
-                : controllerFromRequest.getTopActivityDisplayArea();
-        if (displayAreaFromSourceProcess != null) {
-            mFallBackDisplayAreaList.add(
-                    TaskDisplayAreaWrapper.create(displayAreaFromSourceProcess));
-        }
-        return mFallBackDisplayAreaList;
-    }
-
-    @Nullable
-    private TaskDisplayAreaWrapper findTaskDisplayArea(int displayId, int featureId) {
-        DisplayContent display = mAtm.mRootWindowContainer.getDisplayContentOrCreate(displayId);
-        if (display == null) {
-            return null;
-        }
-        TaskDisplayArea tda = display.getItemFromTaskDisplayAreas(
-                displayArea -> displayArea.mFeatureId == featureId ? displayArea : null);
-        return TaskDisplayAreaWrapper.create(tda);
-    }
-
-    private final CarLaunchParamsModifierInterface mBuiltinInterface
-            = new CarLaunchParamsModifierInterface() {
-        @Nullable
-        @Override
-        public TaskDisplayAreaWrapper findTaskDisplayArea(int displayId, int featureId) {
-            return CarLaunchParamsModifier.this.findTaskDisplayArea(displayId, featureId);
-        }
-
-        @Nullable
-        @Override
-        public TaskDisplayAreaWrapper getDefaultTaskDisplayAreaOnDisplay(int displayId) {
-            return CarLaunchParamsModifier.this.getDefaultTaskDisplayAreaOnDisplay(displayId);
-        }
-
-        @NonNull
-        @Override
-        public List<TaskDisplayAreaWrapper> getFallbackDisplayAreasForActivity(
-                @NonNull ActivityRecordWrapper activityRecord, @Nullable RequestWrapper request) {
-            return CarLaunchParamsModifier.this.getFallbackDisplayAreasForActivity(
-                    activityRecord, request);
-        }
-    };
-}
diff --git a/builtInServices/src/com/android/server/wm/CarLaunchParamsModifierInterface.java b/builtInServices/src/com/android/server/wm/CarLaunchParamsModifierInterface.java
deleted file mode 100644
index 8550c55..0000000
--- a/builtInServices/src/com/android/server/wm/CarLaunchParamsModifierInterface.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.graphics.Rect;
-import android.view.Display;
-
-import java.util.List;
-
-/**
- * Interface implemented by {@code CarLaunchParamsModifier} and used by
- * {@code CarLaunchParamsModifierUpdatable}.
- *
- * Because {@code CarLaunchParamsModifierUpdatable} calls {@code CarLaunchParamsModifierInterface}
- * with {@code mLock} acquired, {@code CarLaunchParamsModifierInterface} shouldn't call
- * {@code CarLaunchParamsModifierUpdatable} again during its execution.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public interface CarLaunchParamsModifierInterface {
-    /**
-     * Returns {@link TaskDisplayAreaWrapper} of the given {@code featureId} in the given
-     * {@code displayId}.
-     */
-    @Nullable TaskDisplayAreaWrapper findTaskDisplayArea(int displayId, int featureId);
-
-    /**
-     * Returns the default {@link TaskDisplayAreaWrapper} of the given {@code displayId}.
-     */
-    @Nullable TaskDisplayAreaWrapper getDefaultTaskDisplayAreaOnDisplay(int displayId);
-
-    /**
-     * Returns the list of fallback {@link TaskDisplayAreaWrapper} from the source of the request.
-     */
-    @NonNull List<TaskDisplayAreaWrapper> getFallbackDisplayAreasForActivity(
-            @NonNull ActivityRecordWrapper activityRecord, @Nullable RequestWrapper request);
-
-}
diff --git a/builtInServices/src/com/android/server/wm/CarLaunchParamsModifierUpdatable.java b/builtInServices/src/com/android/server/wm/CarLaunchParamsModifierUpdatable.java
deleted file mode 100644
index 3abf54e..0000000
--- a/builtInServices/src/com/android/server/wm/CarLaunchParamsModifierUpdatable.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.annotation.UserIdInt;
-import android.car.app.CarActivityManager;
-import android.content.ComponentName;
-import android.hardware.display.DisplayManager;
-import android.os.ServiceSpecificException;
-import android.os.UserHandle;
-import android.util.ArrayMap;
-import android.util.Slog;
-import android.util.SparseIntArray;
-import android.view.Display;
-import android.window.DisplayAreaOrganizer;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Updatable interface of CarLaunchParamsModifier.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public interface CarLaunchParamsModifierUpdatable {
-
-    /** Returns {@link DisplayManager.DisplayListener} of CarLaunchParamsModifierUpdatable. */
-    DisplayManager.DisplayListener getDisplayListener();
-
-    /** Notifies user switching. */
-    void handleCurrentUserSwitching(@UserIdInt int newUserId);
-
-    /** Notifies user starting. */
-    void handleUserStarting(@UserIdInt int startingUser);
-
-    /** Notifies user stopped. */
-    void handleUserStopped(@UserIdInt int stoppedUser);
-
-    /**
-     * Calculates {@code outParams} based on the given arguments.
-     * See {@code LaunchParamsController.LaunchParamsModifier.onCalculate()} for the detail.
-     */
-    int calculate(CalculateParams params);
-}
diff --git a/builtInServices/src/com/android/server/wm/LaunchParamsWrapper.java b/builtInServices/src/com/android/server/wm/LaunchParamsWrapper.java
deleted file mode 100644
index 344961f..0000000
--- a/builtInServices/src/com/android/server/wm/LaunchParamsWrapper.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.graphics.Rect;
-
-/**
- * Wrapper of {@link com.android.server.wm.LaunchParamsController.LaunchParams}.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class LaunchParamsWrapper {
-    /** Returned when the modifier does not want to influence the bounds calculation */
-    public static int RESULT_SKIP = LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
-    /**
-     * Returned when the modifier has changed the bounds and would like its results to be the
-     * final bounds applied.
-     */
-    public static int RESULT_DONE = LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
-    /**
-     * Returned when the modifier has changed the bounds but is okay with other modifiers
-     * influencing the bounds.
-     */
-    public static int RESULT_CONTINUE = LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
-
-    private final LaunchParamsController.LaunchParams mLaunchParams;
-
-    private LaunchParamsWrapper(LaunchParamsController.LaunchParams launchParams) {
-        mLaunchParams = launchParams;
-    }
-
-    /** @hide */
-    public static LaunchParamsWrapper create(
-            @Nullable LaunchParamsController.LaunchParams launchParams) {
-        if (launchParams == null) return null;
-        return new LaunchParamsWrapper(launchParams);
-    }
-
-    /**
-     * Gets the {@link TaskDisplayAreaWrapper} the {@link Task} would prefer to be on.
-     */
-    public TaskDisplayAreaWrapper getPreferredTaskDisplayArea() {
-        return TaskDisplayAreaWrapper.create(mLaunchParams.mPreferredTaskDisplayArea);
-    }
-
-    /**
-     * Sets the {@link TaskDisplayAreaWrapper} the {@link Task} would prefer to be on.
-     */
-    public void setPreferredTaskDisplayArea(TaskDisplayAreaWrapper tda) {
-        mLaunchParams.mPreferredTaskDisplayArea = tda.getTaskDisplayArea();
-    }
-
-    /**
-     * Gets the windowing mode to be in.
-     */
-    public int getWindowingMode() {
-        return mLaunchParams.mWindowingMode;
-    }
-
-    /**
-     * Sets the windowing mode to be in.
-     */
-    public void setWindowingMode(int windowingMode) {
-        mLaunchParams.mWindowingMode = windowingMode;
-    }
-
-    /**
-     *  Gets the bounds within the parent container.
-     */
-    public Rect getBounds() {
-        return mLaunchParams.mBounds;
-    }
-
-    /**
-     *  Sets the bounds within the parent container.
-     */
-    public void setBounds(Rect bounds) {
-        mLaunchParams.mBounds.set(bounds);
-    }
-
-    @Override
-    public String toString() {
-        return "LaunchParams{" +
-                "mPreferredTaskDisplayArea=" + mLaunchParams.mPreferredTaskDisplayArea +
-                ", mWindowingMode=" + mLaunchParams.mWindowingMode +
-                ", mBounds=" + mLaunchParams.mBounds.toString() + '}';
-    }
-}
diff --git a/builtInServices/src/com/android/server/wm/RequestWrapper.java b/builtInServices/src/com/android/server/wm/RequestWrapper.java
deleted file mode 100644
index d6e1795..0000000
--- a/builtInServices/src/com/android/server/wm/RequestWrapper.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-
-/**
- * Wrapper of {@link com.android.server.wm.ActivityStarter.Request}.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class RequestWrapper {
-    private final ActivityStarter.Request mRequest;
-
-    private RequestWrapper(ActivityStarter.Request request) {
-        mRequest = request;
-    }
-
-    /** @hide */
-    public static RequestWrapper create(@Nullable ActivityStarter.Request request) {
-        if (request == null) return null;
-        return new RequestWrapper(request);
-    }
-
-    /** @hide */
-    public ActivityStarter.Request getRequest() {
-        return mRequest;
-    }
-
-    @Override
-    public String toString() {
-        return mRequest.toString();
-    }
-}
diff --git a/builtInServices/src/com/android/server/wm/TaskDisplayAreaWrapper.java b/builtInServices/src/com/android/server/wm/TaskDisplayAreaWrapper.java
deleted file mode 100644
index 9faef06..0000000
--- a/builtInServices/src/com/android/server/wm/TaskDisplayAreaWrapper.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.view.Display;
-
-/**
- * Wrapper of {@link TaskDisplayArea}.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class TaskDisplayAreaWrapper {
-    private final TaskDisplayArea mTaskDisplayArea;
-
-    private TaskDisplayAreaWrapper(TaskDisplayArea taskDisplayArea) {
-        mTaskDisplayArea = taskDisplayArea;
-    }
-
-    /** @hide */
-    public static TaskDisplayAreaWrapper create(@Nullable TaskDisplayArea taskDisplayArea) {
-        if (taskDisplayArea == null) return null;
-        return new TaskDisplayAreaWrapper(taskDisplayArea);
-    }
-
-    /** @hide */
-    public TaskDisplayArea getTaskDisplayArea() {
-        return mTaskDisplayArea;
-    }
-
-    /**
-     * Gets the display this {@link TaskDisplayAreaWrapper} is on.
-     */
-    public Display getDisplay() {
-        return mTaskDisplayArea.getDisplayContent().getDisplay();
-    }
-
-    @Override
-    public String toString() {
-        return mTaskDisplayArea.toString();
-    }
-}
diff --git a/builtInServices/src/com/android/server/wm/TaskWrapper.java b/builtInServices/src/com/android/server/wm/TaskWrapper.java
deleted file mode 100644
index 3a2c682..0000000
--- a/builtInServices/src/com/android/server/wm/TaskWrapper.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-
-/**
- * Wrapper of {@link Task}.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class TaskWrapper {
-    private final Task mTask;
-
-    private TaskWrapper(Task task) {
-        mTask = task;
-    }
-
-    /** @hide */
-    public static TaskWrapper create(@Nullable Task task) {
-        if (task == null) return null;
-        return new TaskWrapper(task);
-    }
-
-    /**
-     * Gets the {@code userId} of this {@link Task} is created for
-     */
-    public int getUserId() {
-        return mTask.mUserId;
-    }
-
-    /**
-     * Gets the root {@link TaskWrapper} of the this.
-     */
-    public TaskWrapper getRootTask() {
-        return create(mTask.getRootTask());
-    }
-
-    /**
-     * Gets the {@link TaskDisplayAreaWrapper} this {@link Task} is on.
-     */
-    public TaskDisplayAreaWrapper getTaskDisplayArea() {
-        return TaskDisplayAreaWrapper.create(mTask.getTaskDisplayArea());
-    }
-
-    @Override
-    public String toString() {
-        return mTask.toString();
-    }
-}
diff --git a/builtInServices/src/com/android/server/wm/WindowLayoutWrapper.java b/builtInServices/src/com/android/server/wm/WindowLayoutWrapper.java
deleted file mode 100644
index e028a20..0000000
--- a/builtInServices/src/com/android/server/wm/WindowLayoutWrapper.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.content.pm.ActivityInfo;
-
-/**
- * Wrapper of {@link android.content.pm.ActivityInfo.WindowLayout}.
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class WindowLayoutWrapper {
-    private final ActivityInfo.WindowLayout mLayout;
-
-    private WindowLayoutWrapper(ActivityInfo.WindowLayout layout) {
-        mLayout = layout;
-    }
-
-    /** @hide */
-    public static WindowLayoutWrapper create(@Nullable ActivityInfo.WindowLayout layout) {
-        if (layout == null) return null;
-        return new WindowLayoutWrapper(layout);
-    }
-
-    @Override
-    public String toString() {
-        return mLayout.toString();
-    }
-}
diff --git a/builtInServices/tests/src/com/android/server/wm/ActivityOptionsWrapperTest.java b/builtInServices/tests/src/com/android/server/wm/ActivityOptionsWrapperTest.java
deleted file mode 100644
index 682c31f..0000000
--- a/builtInServices/tests/src/com/android/server/wm/ActivityOptionsWrapperTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.ActivityOptions;
-
-import org.junit.Test;
-
-/**
- * This class contains unit tests for the {@link ActivityOptionsWrapper}.
- */
-public final class ActivityOptionsWrapperTest {
-    @Test
-    public void create_returnsActivityOptionWrapper() {
-        ActivityOptions options = ActivityOptions.makeBasic();
-        ActivityOptionsWrapper wrapper = ActivityOptionsWrapper.create(options);
-        assertThat(wrapper).isNotNull();
-        assertThat(wrapper.getOptions()).isSameInstanceAs(options);
-        assertThat(wrapper.toString()).isEqualTo(options.toString());
-    }
-
-    @Test
-    public void create_returnsNull() {
-        ActivityOptionsWrapper wrapper = ActivityOptionsWrapper.create(null);
-        assertThat(wrapper).isNull();
-    }
-}
diff --git a/builtInServices/tests/src/com/android/server/wm/ActivityRecordWrapperTest.java b/builtInServices/tests/src/com/android/server/wm/ActivityRecordWrapperTest.java
deleted file mode 100644
index 302f974..0000000
--- a/builtInServices/tests/src/com/android/server/wm/ActivityRecordWrapperTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-/**
- * This class contains unit tests for the {@link ActivityRecordWrapper}.
- */
-@RunWith(MockitoJUnitRunner.class)
-public final class ActivityRecordWrapperTest {
-    @Mock
-    private ActivityRecord mActivityRecord;
-
-    @Test
-    public void create_returnsActivityOptionWrapper() {
-        ActivityRecordWrapper wrapper = ActivityRecordWrapper.create(mActivityRecord);
-        assertThat(wrapper).isNotNull();
-        assertThat(wrapper.getActivityRecord()).isSameInstanceAs(mActivityRecord);
-        assertThat(wrapper.toString()).isEqualTo(mActivityRecord.toString());
-    }
-
-    @Test
-    public void create_returnsNull() {
-        ActivityRecordWrapper wrapper = ActivityRecordWrapper.create(null);
-        assertThat(wrapper).isNull();
-    }
-}
diff --git a/builtInServices/tests/src/com/android/server/wm/CalculateParamsTest.java b/builtInServices/tests/src/com/android/server/wm/CalculateParamsTest.java
deleted file mode 100644
index bf34497..0000000
--- a/builtInServices/tests/src/com/android/server/wm/CalculateParamsTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.ActivityOptions;
-import android.content.pm.ActivityInfo;
-import android.view.Gravity;
-
-import com.android.server.wm.LaunchParamsController.LaunchParams;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-/**
- * This class contains unit tests for the {@link CalculateParams}.
- */
-@RunWith(MockitoJUnitRunner.class)
-public class CalculateParamsTest {
-    @Mock
-    private Task mTask;
-    private ActivityInfo.WindowLayout mLayout = new ActivityInfo.WindowLayout(
-            /* width= */ 1280, /* widthFraction= */ 0.5f,
-            /* height= */ 800, /* heightFraction= */ 1.0f,
-            /* gravity= */ Gravity.CENTER, /* minWidth= */ 400, /* minHeight= */ 300);
-    @Mock
-    private ActivityRecord mActvity;
-    @Mock
-    private ActivityRecord mSource;
-    private ActivityOptions mOptions = ActivityOptions.makeBasic();
-    private ActivityStarter.Request mRequest = new ActivityStarter.Request();
-    private int mPhase = LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS;
-    private LaunchParams mCurrentParams = new LaunchParams();
-    private LaunchParams mOutParms = new LaunchParams();
-    boolean mSupportsMultiDisplay = true;
-
-    @Test
-    public void createReturnsCalculateParams() {
-        mCurrentParams.mWindowingMode = WINDOWING_MODE_FULLSCREEN;
-        mOutParms.mWindowingMode = WINDOWING_MODE_MULTI_WINDOW;
-        CalculateParams params = CalculateParams.create(mTask,mLayout, mActvity, mSource, mOptions,
-                mRequest, mPhase, mCurrentParams, mOutParms, mSupportsMultiDisplay);
-        // Current toString() of Wrappers are using toString() of the underlying object
-        // except LaunchParams.
-        assertThat(params.getTask().toString()).isEqualTo(mTask.toString());
-        assertThat(params.getWindowLayout().toString()).isEqualTo(mLayout.toString());
-        assertThat(params.getActivity().getActivityRecord()).isSameInstanceAs(mActvity);
-        assertThat(params.getSource().getActivityRecord()).isSameInstanceAs(mSource);
-        assertThat(params.getCurrentParams().getWindowingMode())
-                .isEqualTo(WINDOWING_MODE_FULLSCREEN);
-        assertThat(params.getOutParams().getWindowingMode()).isEqualTo(WINDOWING_MODE_MULTI_WINDOW);
-        assertThat(params.supportsMultiDisplay()).isEqualTo(mSupportsMultiDisplay);
-    }
-}
diff --git a/builtInServices/tests/src/com/android/server/wm/LaunchParamsWrapperTest.java b/builtInServices/tests/src/com/android/server/wm/LaunchParamsWrapperTest.java
deleted file mode 100644
index 3a19199..0000000
--- a/builtInServices/tests/src/com/android/server/wm/LaunchParamsWrapperTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-
-/**
- * This class contains unit tests for the {@link LaunchParamsWrapper}.
- */
-public final class LaunchParamsWrapperTest {
-    @Test
-    public void create_returnsLaunchParamsWrapper() {
-        LaunchParamsController.LaunchParams params = new LaunchParamsController.LaunchParams();
-        LaunchParamsWrapper wrapper = LaunchParamsWrapper.create(params);
-        assertThat(wrapper).isNotNull();
-    }
-
-    @Test
-    public void create_returnsNull() {
-        LaunchParamsWrapper wrapper = LaunchParamsWrapper.create(null);
-        assertThat(wrapper).isNull();
-    }
-}
\ No newline at end of file
diff --git a/builtInServices/tests/src/com/android/server/wm/RequestWrapperTest.java b/builtInServices/tests/src/com/android/server/wm/RequestWrapperTest.java
deleted file mode 100644
index 7e81390..0000000
--- a/builtInServices/tests/src/com/android/server/wm/RequestWrapperTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-
-/**
- * This class contains unit tests for the {@link RequestWrapper}.
- */
-public final class RequestWrapperTest {
-    @Test
-    public void create_returnsActivityOptionWrapper() {
-        ActivityStarter.Request request = new ActivityStarter.Request();
-        RequestWrapper wrapper = RequestWrapper.create(request);
-        assertThat(wrapper).isNotNull();
-        assertThat(wrapper.getRequest()).isSameInstanceAs(request);
-        assertThat(wrapper.toString()).isEqualTo(request.toString());
-    }
-
-    @Test
-    public void create_returnsNull() {
-        RequestWrapper wrapper = RequestWrapper.create(null);
-        assertThat(wrapper).isNull();
-    }
-}
diff --git a/builtInServices/tests/src/com/android/server/wm/TaskDisplayAreaWrapperTest.java b/builtInServices/tests/src/com/android/server/wm/TaskDisplayAreaWrapperTest.java
deleted file mode 100644
index 53c100f..0000000
--- a/builtInServices/tests/src/com/android/server/wm/TaskDisplayAreaWrapperTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-/**
- * This class contains unit tests for the {@link TaskDisplayAreaWrapper}.
- */
-@RunWith(MockitoJUnitRunner.class)
-public final class TaskDisplayAreaWrapperTest {
-    @Mock
-    private TaskDisplayArea mTaskDisplayArea;
-
-    @Test
-    public void create_returnsActivityOptionWrapper() {
-        TaskDisplayAreaWrapper wrapper = TaskDisplayAreaWrapper.create(mTaskDisplayArea);
-        assertThat(wrapper).isNotNull();
-        assertThat(wrapper.getTaskDisplayArea()).isSameInstanceAs(mTaskDisplayArea);
-        assertThat(wrapper.toString()).isEqualTo(mTaskDisplayArea.toString());
-    }
-
-    @Test
-    public void create_returnsNull() {
-        TaskDisplayAreaWrapper wrapper = TaskDisplayAreaWrapper.create(null);
-        assertThat(wrapper).isNull();
-    }
-}
diff --git a/builtInServices/tests/src/com/android/server/wm/TaskWrapperTest.java b/builtInServices/tests/src/com/android/server/wm/TaskWrapperTest.java
deleted file mode 100644
index ce29cd6..0000000
--- a/builtInServices/tests/src/com/android/server/wm/TaskWrapperTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
-
-/**
- * This class contains unit tests for the {@link TaskWrapper}.
- */
-@RunWith(MockitoJUnitRunner.class)
-public final class TaskWrapperTest {
-    @Mock
-    private Task mTask;
-
-    @Test
-    public void create_returnsActivityOptionWrapper() {
-        TaskWrapper wrapper = TaskWrapper.create(mTask);
-        assertThat(wrapper).isNotNull();
-        assertThat(wrapper.toString()).isEqualTo(mTask.toString());
-    }
-
-    @Test
-    public void create_returnsNull() {
-        TaskWrapper wrapper = TaskWrapper.create(null);
-        assertThat(wrapper).isNull();
-    }
-}
diff --git a/builtInServices/tests/src/com/android/server/wm/WindowLayoutWrapperTest.java b/builtInServices/tests/src/com/android/server/wm/WindowLayoutWrapperTest.java
deleted file mode 100644
index 0d04d69..0000000
--- a/builtInServices/tests/src/com/android/server/wm/WindowLayoutWrapperTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.pm.ActivityInfo;
-import android.view.Gravity;
-
-import org.junit.Test;
-
-/**
- * This class contains unit tests for the {@link WindowLayoutWrapper}.
- */
-public final class WindowLayoutWrapperTest {
-    @Test
-    public void create_returnsActivityOptionWrapper() {
-        ActivityInfo.WindowLayout layout = new ActivityInfo.WindowLayout(
-                /* width= */ 1280, /* widthFraction= */ 0.5f,
-                /* height= */ 800, /* heightFraction= */ 1.0f,
-                /* gravity= */ Gravity.CENTER, /* minWidth= */ 400, /* minHeight= */ 300);
-        WindowLayoutWrapper wrapper = WindowLayoutWrapper.create(layout);
-        assertThat(wrapper).isNotNull();
-        assertThat(wrapper.toString()).isEqualTo(layout.toString());
-    }
-
-    @Test
-    public void create_returnsNull() {
-        WindowLayoutWrapper wrapper = WindowLayoutWrapper.create(null);
-        assertThat(wrapper).isNull();
-    }
-}
diff --git a/builtInServices/src/com/android/internal/car/CarDevicePolicySafetyChecker.java b/src/com/android/internal/car/CarDevicePolicySafetyChecker.java
similarity index 98%
rename from builtInServices/src/com/android/internal/car/CarDevicePolicySafetyChecker.java
rename to src/com/android/internal/car/CarDevicePolicySafetyChecker.java
index 2ae2e63..0bc0c21 100644
--- a/builtInServices/src/com/android/internal/car/CarDevicePolicySafetyChecker.java
+++ b/src/com/android/internal/car/CarDevicePolicySafetyChecker.java
@@ -35,12 +35,12 @@
 import android.app.admin.DevicePolicyManager.DevicePolicyOperation;
 import android.app.admin.DevicePolicyManagerLiteInternal;
 import android.app.admin.DevicePolicySafetyChecker;
+import android.util.IndentingPrintWriter;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.server.LocalServices;
 
-import java.io.PrintWriter;
 import java.util.Arrays;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -48,8 +48,6 @@
 
 /**
  * Integrates {@link android.app.admin.DevicePolicyManager} operations with car UX restrictions.
- *
- * @hide
  */
 final class CarDevicePolicySafetyChecker {
 
@@ -125,7 +123,7 @@
         return mSafe.get();
     }
 
-    void dump(@NonNull PrintWriter pw) {
+    void dump(@NonNull IndentingPrintWriter pw) {
         pw.printf("Safe to run device policy operations: %b\n", mSafe.get());
         pw.printf("Unsafe operations: %s\n", Arrays.stream(UNSAFE_OPERATIONS)
                 .mapToObj(o -> operationToString(o)).collect(Collectors.toList()));
diff --git a/src/com/android/internal/car/CarServiceHelperService.java b/src/com/android/internal/car/CarServiceHelperService.java
new file mode 100644
index 0000000..8e82316
--- /dev/null
+++ b/src/com/android/internal/car/CarServiceHelperService.java
@@ -0,0 +1,796 @@
+/*
+ * Copyright (C) 2017 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.internal.car;
+
+import static com.android.car.internal.SystemConstants.ICAR_SYSTEM_SERVER_CLIENT;
+import static com.android.car.internal.common.CommonConstants.CAR_SERVICE_INTERFACE;
+import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STARTING;
+import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STOPPED;
+import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STOPPING;
+import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_SWITCHING;
+import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED;
+import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_UNLOCKING;
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.DevicePolicyManager.DevicePolicyOperation;
+import android.app.admin.DevicePolicyManager.OperationSafetyReason;
+import android.app.admin.DevicePolicySafetyChecker;
+import android.automotive.watchdog.internal.ICarWatchdogMonitor;
+import android.automotive.watchdog.internal.PowerCycle;
+import android.automotive.watchdog.internal.StateType;
+import android.car.watchdoglib.CarWatchdogDaemonHelper;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.pm.UserInfo;
+import android.hidl.manager.V1_0.IServiceManager;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.EventLog;
+import android.util.IndentingPrintWriter;
+import android.util.TimeUtils;
+
+import com.android.car.internal.ICarServiceHelper;
+import com.android.car.internal.ICarSystemServerClient;
+import com.android.car.internal.common.CommonConstants.UserLifecycleEventType;
+import com.android.car.internal.common.EventLogTags;
+import com.android.car.internal.common.UserHelperLite;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.IResultReceiver;
+import com.android.server.Dumpable;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.Watchdog;
+import com.android.server.am.ActivityManagerService;
+import com.android.server.pm.UserManagerInternal;
+import com.android.server.pm.UserManagerInternal.UserLifecycleListener;
+import com.android.server.utils.Slogf;
+import com.android.server.utils.TimingsTraceAndSlog;
+import com.android.server.wm.CarLaunchParamsModifier;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * System service side companion service for CarService. Starts car service and provide necessary
+ * API for CarService. Only for car product.
+ */
+public class CarServiceHelperService extends SystemService
+        implements Dumpable, DevicePolicySafetyChecker {
+
+    private static final String TAG = "CarServiceHelper";
+
+    // TODO(b/154033860): STOPSHIP if they're still true
+    private static final boolean DBG = true;
+    private static final boolean VERBOSE = true;
+
+    private static final String PROP_RESTART_RUNTIME = "ro.car.recovery.restart_runtime.enabled";
+
+    private static final List<String> CAR_HAL_INTERFACES_OF_INTEREST = Arrays.asList(
+            "android.hardware.automotive.vehicle@2.0::IVehicle",
+            "android.hardware.automotive.audiocontrol@1.0::IAudioControl",
+            "android.hardware.automotive.audiocontrol@2.0::IAudioControl"
+    );
+
+    // Message ID representing post-processing of process dumping.
+    private static final int WHAT_POST_PROCESS_DUMPING = 1;
+    // Message ID representing process killing.
+    private static final int WHAT_PROCESS_KILL = 2;
+    // Message ID representing service unresponsiveness.
+    private static final int WHAT_SERVICE_UNRESPONSIVE = 3;
+
+    private static final long CAR_SERVICE_BINDER_CALL_TIMEOUT = 15_000;
+
+    private static final long LIFECYCLE_TIMESTAMP_IGNORE = 0;
+
+    private final ICarServiceHelperImpl mHelper = new ICarServiceHelperImpl();
+    private final Context mContext;
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private IBinder mCarServiceBinder;
+    @GuardedBy("mLock")
+    private boolean mSystemBootCompleted;
+
+    private final CarLaunchParamsModifier mCarLaunchParamsModifier;
+
+    private final Handler mHandler;
+    private final HandlerThread mHandlerThread = new HandlerThread("CarServiceHelperService");
+
+    private final ProcessTerminator mProcessTerminator = new ProcessTerminator();
+    private final CarServiceConnectedCallback mCarServiceConnectedCallback =
+            new CarServiceConnectedCallback();
+    private final CarServiceProxy mCarServiceProxy;
+
+    /**
+     * End-to-end time (from process start) for unlocking the first non-system user.
+     */
+    private long mFirstUnlockedUserDuration;
+
+    private final CarWatchdogDaemonHelper mCarWatchdogDaemonHelper;
+    private final ICarWatchdogMonitorImpl mCarWatchdogMonitor = new ICarWatchdogMonitorImpl(this);
+    private final CarWatchdogDaemonHelper.OnConnectionChangeListener mConnectionListener =
+            (connected) -> {
+                if (connected) {
+                    registerMonitorToWatchdogDaemon();
+                }
+            };
+
+    private final ServiceConnection mCarServiceConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+            if (DBG) {
+                Slogf.d(TAG, "onServiceConnected: %s", iBinder);
+            }
+            handleCarServiceConnection(iBinder);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName componentName) {
+            handleCarServiceCrash();
+        }
+    };
+
+    private final BroadcastReceiver mShutdownEventReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // Skip immediately if intent is not relevant to device shutdown.
+            // FLAG_RECEIVER_FOREGROUND is checked to ignore the intent from UserController when
+            // a user is stopped.
+            if ((!intent.getAction().equals(Intent.ACTION_REBOOT)
+                    && !intent.getAction().equals(Intent.ACTION_SHUTDOWN))
+                    || (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) == 0) {
+                return;
+            }
+            int powerCycle = PowerCycle.POWER_CYCLE_SHUTDOWN_ENTER;
+            try {
+                mCarWatchdogDaemonHelper.notifySystemStateChange(StateType.POWER_CYCLE,
+                        powerCycle, /* arg2= */ 0);
+                if (DBG) {
+                    Slogf.d(TAG, "Notified car watchdog daemon of power cycle(%d)", powerCycle);
+                }
+            } catch (RemoteException | RuntimeException e) {
+                Slogf.w(TAG, "Notifying power cycle state change failed: %s", e);
+            }
+        }
+    };
+
+    private final CarDevicePolicySafetyChecker mCarDevicePolicySafetyChecker;
+
+    public CarServiceHelperService(Context context) {
+        this(context,
+                new CarLaunchParamsModifier(context),
+                new CarWatchdogDaemonHelper(TAG),
+                null
+        );
+    }
+
+    @VisibleForTesting
+    CarServiceHelperService(
+            Context context,
+            CarLaunchParamsModifier carLaunchParamsModifier,
+            CarWatchdogDaemonHelper carWatchdogDaemonHelper,
+            CarServiceProxy carServiceOperationManager) {
+        super(context);
+
+        mContext = context;
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mCarLaunchParamsModifier = carLaunchParamsModifier;
+        mCarWatchdogDaemonHelper = carWatchdogDaemonHelper;
+        mCarServiceProxy =
+                carServiceOperationManager == null ? new CarServiceProxy(this)
+                        : carServiceOperationManager;
+        UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+        if (umi != null) {
+            umi.addUserLifecycleListener(new UserLifecycleListener() {
+                @Override
+                public void onUserCreated(UserInfo user, Object token) {
+                    if (DBG) Slogf.d(TAG, "onUserCreated(): %s", user.toFullString());
+                }
+                @Override
+                public void onUserRemoved(UserInfo user) {
+                    if (DBG) Slogf.d(TAG, "onUserRemoved(): $s", user.toFullString());
+                    mCarServiceProxy.onUserRemoved(user);
+                }
+            });
+        } else {
+            Slogf.e(TAG, "UserManagerInternal not available - should only happen on unit tests");
+        }
+        mCarDevicePolicySafetyChecker = new CarDevicePolicySafetyChecker(this);
+    }
+    @Override
+    public void onBootPhase(int phase) {
+        EventLog.writeEvent(EventLogTags.CAR_HELPER_BOOT_PHASE, phase);
+        if (DBG) Slogf.d(TAG, "onBootPhase: %d", phase);
+
+        TimingsTraceAndSlog t = newTimingsTraceAndSlog();
+        if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
+            t.traceBegin("onBootPhase.3pApps");
+            mCarLaunchParamsModifier.init();
+            setupAndStartUsers(t);
+            t.traceEnd();
+        } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
+            t.traceBegin("onBootPhase.completed");
+            synchronized (mLock) {
+                mSystemBootCompleted = true;
+            }
+            try {
+                mCarWatchdogDaemonHelper.notifySystemStateChange(
+                        StateType.BOOT_PHASE, phase, /* arg2= */ 0);
+            } catch (RemoteException | RuntimeException e) {
+                Slogf.w(TAG, "Failed to notify boot phase change: %s", e);
+            }
+            t.traceEnd();
+        }
+    }
+
+    @Override
+    public void onStart() {
+        EventLog.writeEvent(EventLogTags.CAR_HELPER_START);
+
+        IntentFilter filter = new IntentFilter(Intent.ACTION_REBOOT);
+        filter.addAction(Intent.ACTION_SHUTDOWN);
+        mContext.registerReceiverForAllUsers(mShutdownEventReceiver, filter, null, null);
+        mCarWatchdogDaemonHelper.addOnConnectionChangeListener(mConnectionListener);
+        mCarWatchdogDaemonHelper.connect();
+        Intent intent = new Intent();
+        intent.setPackage("com.android.car");
+        intent.setAction(CAR_SERVICE_INTERFACE);
+        if (!mContext.bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
+                mHandler, UserHandle.SYSTEM)) {
+            Slogf.wtf(TAG, "cannot start car service");
+        }
+        loadNativeLibrary();
+    }
+
+    @Override
+    public void dump(IndentingPrintWriter pw, String[] args) {
+        if (args == null || args.length == 0 || args[0].equals("-a")) {
+            pw.printf("System boot completed: %b\n", mSystemBootCompleted);
+            pw.print("First unlocked user duration: ");
+            TimeUtils.formatDuration(mFirstUnlockedUserDuration, pw); pw.println();
+            pw.printf("Queued tasks: %d\n", mProcessTerminator.mQueuedTask);
+            mCarServiceProxy.dump(pw);
+            mCarDevicePolicySafetyChecker.dump(pw);
+            return;
+        }
+
+        if ("--user-metrics-only".equals(args[0])) {
+            mCarServiceProxy.dumpUserMetrics(pw);
+            return;
+        }
+
+        if ("--is-operation-safe".equals(args[0]) & args.length > 1) {
+            String arg1 = args[1];
+            int operation = 0;
+            try {
+                operation = Integer.parseInt(arg1);
+            } catch (Exception e) {
+                pw.printf("Invalid operation type: %s\n", arg1);
+                return;
+
+            }
+            int reason = getUnsafeOperationReason(operation);
+            boolean safe = reason == DevicePolicyManager.OPERATION_SAFETY_REASON_NONE;
+            pw.printf("Operation %s is %s. Reason: %s\n",
+                    DevicePolicyManager.operationToString(operation),
+                    safe ? "SAFE" : "UNSAFE",
+                    DevicePolicyManager.operationSafetyReasonToString(reason));
+            return;
+        }
+        pw.printf("Invalid args: %s\n", Arrays.toString(args));
+    }
+
+    @Override
+    public String getDumpableName() {
+        return "CarServiceHelper";
+    }
+
+    @Override
+    public void onUserUnlocking(@NonNull TargetUser user) {
+        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_UNLOCKING)) return;
+        EventLog.writeEvent(EventLogTags.CAR_HELPER_USER_UNLOCKING, user.getUserIdentifier());
+        if (DBG) Slogf.d(TAG, "onUserUnlocking(%s)", user);
+
+        sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKING, user);
+    }
+
+    @Override
+    public void onUserUnlocked(@NonNull TargetUser user) {
+        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_UNLOCKED)) return;
+        int userId = user.getUserIdentifier();
+        EventLog.writeEvent(EventLogTags.CAR_HELPER_USER_UNLOCKED, userId);
+        if (DBG) Slogf.d(TAG, "onUserUnlocked(%s)", user);
+
+        if (mFirstUnlockedUserDuration == 0 && !UserHelperLite.isHeadlessSystemUser(userId)) {
+            mFirstUnlockedUserDuration = SystemClock.elapsedRealtime()
+                    - Process.getStartElapsedRealtime();
+            Slogf.i(TAG, "Time to unlock 1st user(%s): %s", user,
+                    TimeUtils.formatDuration(mFirstUnlockedUserDuration));
+        }
+        sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED, user);
+    }
+
+    @Override
+    public void onUserStarting(@NonNull TargetUser user) {
+        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_STARTING)) return;
+        EventLog.writeEvent(EventLogTags.CAR_HELPER_USER_STARTING, user.getUserIdentifier());
+        if (DBG) Slogf.d(TAG, "onUserStarting(%s)", user);
+
+        sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING, user);
+    }
+
+    @Override
+    public void onUserStopping(@NonNull TargetUser user) {
+        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_STOPPING)) return;
+        EventLog.writeEvent(EventLogTags.CAR_HELPER_USER_STOPPING, user.getUserIdentifier());
+        if (DBG) Slogf.d(TAG, "onUserStopping(%s)", user);
+
+        sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPING, user);
+        int userId = user.getUserIdentifier();
+        mCarLaunchParamsModifier.handleUserStopped(userId);
+    }
+
+    @Override
+    public void onUserStopped(@NonNull TargetUser user) {
+        if (isPreCreated(user, USER_LIFECYCLE_EVENT_TYPE_STOPPED)) return;
+        EventLog.writeEvent(EventLogTags.CAR_HELPER_USER_STOPPED, user.getUserIdentifier());
+        if (DBG) Slogf.d(TAG, "onUserStopped(%s)", user);
+
+        sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STOPPED, user);
+    }
+
+    @Override
+    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
+        if (isPreCreated(to, USER_LIFECYCLE_EVENT_TYPE_SWITCHING)) return;
+        EventLog.writeEvent(EventLogTags.CAR_HELPER_USER_SWITCHING,
+                from == null ? UserHandle.USER_NULL : from.getUserIdentifier(),
+                to.getUserIdentifier());
+        if (DBG) Slogf.d(TAG, "onUserSwitching(%s>>%s)", from, to);
+
+        mCarServiceProxy.sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_SWITCHING,
+                from, to);
+        int userId = to.getUserIdentifier();
+        mCarLaunchParamsModifier.handleCurrentUserSwitching(userId);
+    }
+
+    @Override // from DevicePolicySafetyChecker
+    @OperationSafetyReason
+    public int getUnsafeOperationReason(@DevicePolicyOperation int operation) {
+        return mCarDevicePolicySafetyChecker.isDevicePolicyOperationSafe(operation)
+                ? DevicePolicyManager.OPERATION_SAFETY_REASON_NONE
+                : DevicePolicyManager.OPERATION_SAFETY_REASON_DRIVING_DISTRACTION;
+    }
+
+    @Override // from DevicePolicySafetyChecker
+    public boolean isSafeOperation(@OperationSafetyReason int reason) {
+        return mCarDevicePolicySafetyChecker.isSafe();
+    }
+
+    @Override // from DevicePolicySafetyChecker
+    public void onFactoryReset(IResultReceiver callback) {
+        if (DBG) Slogf.d(TAG, "onFactoryReset: %s", callback);
+
+        mCarServiceProxy.onFactoryReset(callback);
+    }
+
+    @VisibleForTesting
+    void loadNativeLibrary() {
+        System.loadLibrary("car-framework-service-jni");
+    }
+
+    private boolean isPreCreated(@NonNull TargetUser user, @UserLifecycleEventType int eventType) {
+        if (!user.isPreCreated()) return false;
+
+        if (DBG) {
+            Slogf.d(TAG, "Ignoring event of type %d for pre-created user %s", eventType, user);
+        }
+        return true;
+    }
+
+    @VisibleForTesting
+    void handleCarServiceConnection(IBinder iBinder) {
+        synchronized (mLock) {
+            if (mCarServiceBinder == iBinder) {
+                return; // already connected.
+            }
+            Slogf.i(TAG, "car service binder changed, was %s new: %s", mCarServiceBinder, iBinder);
+            mCarServiceBinder = iBinder;
+            Slogf.i(TAG, "**CarService connected**");
+        }
+
+        sendSetSystemServerConnectionsCall();
+
+        mHandler.removeMessages(WHAT_SERVICE_UNRESPONSIVE);
+        mHandler.sendMessageDelayed(
+                obtainMessage(CarServiceHelperService::handleCarServiceUnresponsive, this)
+                        .setWhat(WHAT_SERVICE_UNRESPONSIVE), CAR_SERVICE_BINDER_CALL_TIMEOUT);
+    }
+
+    private TimingsTraceAndSlog newTimingsTraceAndSlog() {
+        return new TimingsTraceAndSlog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
+    }
+
+    private void setupAndStartUsers(@NonNull TimingsTraceAndSlog t) {
+        // TODO(b/156263735): decide if it should return in case the device's on Retail Mode
+        t.traceBegin("setupAndStartUsers");
+        mCarServiceProxy.initBootUser();
+        t.traceEnd();
+    }
+
+    private void handleCarServiceUnresponsive() {
+        // This should not happen. Calling this method means ICarSystemServerClient binder is not
+        // returned after service connection. and CarService has not connected in the given time.
+        Slogf.w(TAG, "*** CARHELPER KILLING SYSTEM PROCESS: CarService unresponsive.");
+        Slogf.w(TAG, "*** GOODBYE!");
+        Process.killProcess(Process.myPid());
+        System.exit(10);
+    }
+
+    private void sendSetSystemServerConnectionsCall() {
+        Parcel data = Parcel.obtain();
+        data.writeInterfaceToken(CAR_SERVICE_INTERFACE);
+        data.writeStrongBinder(mHelper.asBinder());
+        data.writeStrongBinder(mCarServiceConnectedCallback.asBinder());
+        IBinder binder;
+        synchronized (mLock) {
+            binder = mCarServiceBinder;
+        }
+        int code = IBinder.FIRST_CALL_TRANSACTION;
+        try {
+            if (VERBOSE) Slogf.v(TAG, "calling one-way binder transaction with code %d", code);
+            // oneway void setSystemServerConnections(in IBinder helper, in IBinder receiver) = 0;
+            binder.transact(code, data, null, Binder.FLAG_ONEWAY);
+            if (VERBOSE) Slogf.v(TAG, "finished one-way binder transaction with code %d", code);
+        } catch (RemoteException e) {
+            Slogf.w(TAG, "RemoteException from car service", e);
+            handleCarServiceCrash();
+        } catch (RuntimeException e) {
+            Slogf.wtf(TAG, e, "Exception calling binder transaction (real code: %d)", code);
+            throw e;
+        } finally {
+            data.recycle();
+        }
+    }
+
+    private void sendUserLifecycleEvent(@UserLifecycleEventType int eventType,
+            @NonNull TargetUser user) {
+        mCarServiceProxy.sendUserLifecycleEvent(eventType, /* from= */ null, user);
+    }
+
+    // Adapted from frameworks/base/services/core/java/com/android/server/Watchdog.java
+    // TODO(b/131861630) use implementation common with Watchdog.java
+    //
+    private static ArrayList<Integer> getInterestingHalPids() {
+        try {
+            IServiceManager serviceManager = IServiceManager.getService();
+            ArrayList<IServiceManager.InstanceDebugInfo> dump =
+                    serviceManager.debugDump();
+            HashSet<Integer> pids = new HashSet<>();
+            for (IServiceManager.InstanceDebugInfo info : dump) {
+                if (info.pid == IServiceManager.PidConstant.NO_PID) {
+                    continue;
+                }
+
+                if (Watchdog.HAL_INTERFACES_OF_INTEREST.contains(info.interfaceName) ||
+                        CAR_HAL_INTERFACES_OF_INTEREST.contains(info.interfaceName)) {
+                    pids.add(info.pid);
+                }
+            }
+
+            return new ArrayList<Integer>(pids);
+        } catch (RemoteException e) {
+            return new ArrayList<Integer>();
+        }
+    }
+
+    // Adapted from frameworks/base/services/core/java/com/android/server/Watchdog.java
+    // TODO(b/131861630) use implementation common with Watchdog.java
+    //
+    private static ArrayList<Integer> getInterestingNativePids() {
+        ArrayList<Integer> pids = getInterestingHalPids();
+
+        int[] nativePids = Process.getPidsForCommands(Watchdog.NATIVE_STACKS_OF_INTEREST);
+        if (nativePids != null) {
+            pids.ensureCapacity(pids.size() + nativePids.length);
+            for (int i : nativePids) {
+                pids.add(i);
+            }
+        }
+
+        return pids;
+    }
+
+    // Borrowed from Watchdog.java.  Create an ANR file from the call stacks.
+    //
+    private static void dumpServiceStacks() {
+        ArrayList<Integer> pids = new ArrayList<>();
+        pids.add(Process.myPid());
+
+        ActivityManagerService.dumpStackTraces(
+                pids, null, null, getInterestingNativePids(), null);
+    }
+
+    @VisibleForTesting
+    void handleCarServiceCrash() {
+        // Recovery behavior.  Kill the system server and reset
+        // everything if enabled by the property.
+        boolean restartOnServiceCrash = SystemProperties.getBoolean(PROP_RESTART_RUNTIME, false);
+
+        mHandler.removeMessages(WHAT_SERVICE_UNRESPONSIVE);
+
+        dumpServiceStacks();
+        if (restartOnServiceCrash) {
+            Slogf.w(TAG, "*** CARHELPER KILLING SYSTEM PROCESS: CarService crash");
+            Slogf.w(TAG, "*** GOODBYE!");
+            Process.killProcess(Process.myPid());
+            System.exit(10);
+        } else {
+            Slogf.w(TAG, "*** CARHELPER ignoring: CarService crash");
+        }
+    }
+
+    private void handleClientsNotResponding(@NonNull int[] pids) {
+        mProcessTerminator.requestTerminateProcess(pids);
+    }
+
+    private void registerMonitorToWatchdogDaemon() {
+        try {
+            mCarWatchdogDaemonHelper.registerMonitor(mCarWatchdogMonitor);
+        } catch (RemoteException | RuntimeException e) {
+            Slogf.w(TAG, "Cannot register to car watchdog daemon: %s", e);
+        }
+    }
+
+    private void killProcessAndReportToMonitor(int pid) {
+        String processName = getProcessName(pid);
+        Process.killProcess(pid);
+        Slogf.w(TAG, "carwatchdog killed %s (pid: %d)", processName, pid);
+        try {
+            mCarWatchdogDaemonHelper.tellDumpFinished(mCarWatchdogMonitor, pid);
+        } catch (RemoteException | RuntimeException e) {
+            Slogf.w(TAG, "Cannot report monitor result to car watchdog daemon: %s", e);
+        }
+    }
+
+    private static String getProcessName(int pid) {
+        String unknownProcessName = "unknown process";
+        String filename = "/proc/" + pid + "/cmdline";
+        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
+            String line = reader.readLine().replace('\0', ' ').trim();
+            int index = line.indexOf(' ');
+            if (index != -1) {
+                line = line.substring(0, index);
+            }
+            return Paths.get(line).getFileName().toString();
+        } catch (IOException e) {
+            Slogf.w(TAG, "Cannot read %s", filename);
+            return unknownProcessName;
+        }
+    }
+
+    private static native int nativeForceSuspend(int timeoutMs);
+
+    // TODO(b/173664653): it's missing unit tests (for example, to make sure that
+    // when its setSafetyMode() is called, mCarDevicePolicySafetyChecker is updated).
+    private class ICarServiceHelperImpl extends ICarServiceHelper.Stub {
+        /**
+         * Force device to suspend
+         */
+        @Override // Binder call
+        public int forceSuspend(int timeoutMs) {
+            int retVal;
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                retVal = nativeForceSuspend(timeoutMs);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+            return retVal;
+        }
+
+        @Override
+        public void setDisplayAllowlistForUser(@UserIdInt int userId, int[] displayIds) {
+            mCarLaunchParamsModifier.setDisplayAllowListForUser(userId, displayIds);
+        }
+
+        @Override
+        public void setPassengerDisplays(int[] displayIdsForPassenger) {
+            mCarLaunchParamsModifier.setPassengerDisplays(displayIdsForPassenger);
+        }
+
+        @Override
+        public void setSourcePreferredComponents(boolean enableSourcePreferred,
+                @Nullable List<ComponentName> sourcePreferredComponents) {
+            mCarLaunchParamsModifier.setSourcePreferredComponents(
+                    enableSourcePreferred, sourcePreferredComponents);
+        }
+
+        @Override
+        public void setSafetyMode(boolean safe) {
+            mCarDevicePolicySafetyChecker.setSafe(safe);
+        }
+
+        @Override
+        public UserInfo createUserEvenWhenDisallowed(String name, String userType, int flags) {
+            if (DBG) {
+                Slogf.d(TAG, "createUserEvenWhenDisallowed(): name=%s, type=%s, flags=%s",
+                        UserHelperLite.safeName(name), userType, UserInfo.flagsToString(flags));
+            }
+            UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+            try {
+                UserInfo user = umi.createUserEvenWhenDisallowed(name, userType, flags,
+                        /* disallowedPackages= */ null, /* token= */ null);
+                if (DBG) {
+                    Slogf.d(TAG, "User created: %s", (user == null ? "null" : user.toFullString()));
+                }
+                // TODO(b/172691310): decide if user should be affiliated when DeviceOwner is set
+                return user;
+            } catch (UserManager.CheckedUserOperationException e) {
+                Slogf.e(TAG, "Error creating user", e);
+                return null;
+            }
+        }
+    }
+
+    private class ICarWatchdogMonitorImpl extends ICarWatchdogMonitor.Stub {
+        private final WeakReference<CarServiceHelperService> mService;
+
+        private ICarWatchdogMonitorImpl(CarServiceHelperService service) {
+            mService = new WeakReference<>(service);
+        }
+
+        @Override
+        public void onClientsNotResponding(int[] pids) {
+            CarServiceHelperService service = mService.get();
+            if (service == null || pids == null || pids.length == 0) {
+                return;
+            }
+            service.handleClientsNotResponding(pids);
+        }
+    }
+
+    private final class ProcessTerminator {
+
+        private static final long ONE_SECOND_MS = 1_000L;
+
+        private final Object mProcessLock = new Object();
+        private ExecutorService mExecutor;
+        @GuardedBy("mProcessLock")
+        private int mQueuedTask;
+
+        public void requestTerminateProcess(@NonNull int[] pids) {
+            synchronized (mProcessLock) {
+                // If there is a running thread, we re-use it instead of starting a new thread.
+                if (mExecutor == null) {
+                    mExecutor = Executors.newSingleThreadExecutor();
+                }
+                mQueuedTask++;
+            }
+            mExecutor.execute(() -> {
+                for (int pid : pids) {
+                    dumpAndKillProcess(pid);
+                }
+                // mExecutor will be stopped from the main thread, if there is no queued task.
+                mHandler.sendMessage(obtainMessage(ProcessTerminator::postProcessing, this)
+                        .setWhat(WHAT_POST_PROCESS_DUMPING));
+            });
+        }
+
+        private void postProcessing() {
+            synchronized (mProcessLock) {
+                mQueuedTask--;
+                if (mQueuedTask == 0) {
+                    mExecutor.shutdown();
+                    mExecutor = null;
+                }
+            }
+        }
+
+        private void dumpAndKillProcess(int pid) {
+            if (DBG) {
+                Slogf.d(TAG, "Dumping and killing process(pid: %d)", pid);
+            }
+            ArrayList<Integer> javaPids = new ArrayList<>(1);
+            ArrayList<Integer> nativePids = new ArrayList<>();
+            try {
+                if (isJavaApp(pid)) {
+                    javaPids.add(pid);
+                } else {
+                    nativePids.add(pid);
+                }
+            } catch (IOException e) {
+                Slogf.w(TAG, "Cannot get process information: %s", e);
+                return;
+            }
+            nativePids.addAll(getInterestingNativePids());
+            long startDumpTime = SystemClock.uptimeMillis();
+            ActivityManagerService.dumpStackTraces(javaPids, null, null, nativePids, null);
+            long dumpTime = SystemClock.uptimeMillis() - startDumpTime;
+            if (DBG) {
+                Slogf.d(TAG, "Dumping process took %dms", dumpTime);
+            }
+            // To give clients a chance of wrapping up before the termination.
+            if (dumpTime < ONE_SECOND_MS) {
+                mHandler.sendMessageDelayed(obtainMessage(
+                        CarServiceHelperService::killProcessAndReportToMonitor,
+                        CarServiceHelperService.this, pid).setWhat(WHAT_PROCESS_KILL),
+                        ONE_SECOND_MS - dumpTime);
+            } else {
+                killProcessAndReportToMonitor(pid);
+            }
+        }
+
+        private boolean isJavaApp(int pid) throws IOException {
+            Path exePath = new File("/proc/" + pid + "/exe").toPath();
+            String target = Files.readSymbolicLink(exePath).toString();
+            // Zygote's target exe is also /system/bin/app_process32 or /system/bin/app_process64.
+            // But, we can be very sure that Zygote will not be the client of car watchdog daemon.
+            return target == "/system/bin/app_process32" || target == "/system/bin/app_process64";
+        }
+    }
+
+    private final class CarServiceConnectedCallback extends IResultReceiver.Stub {
+        @Override
+        public void send(int resultCode, Bundle resultData) {
+            mHandler.removeMessages(WHAT_SERVICE_UNRESPONSIVE);
+
+            IBinder binder;
+            if (resultData == null
+                    || (binder = resultData.getBinder(ICAR_SYSTEM_SERVER_CLIENT)) == null) {
+                Slogf.wtf(TAG, "setSystemServerConnections return NULL Binder.");
+                handleCarServiceUnresponsive();
+                return;
+            }
+
+            ICarSystemServerClient carService = ICarSystemServerClient.Stub.asInterface(binder);
+            mCarServiceProxy.handleCarServiceConnection(carService);
+        }
+    }
+}
diff --git a/updatableServices/src/com/android/internal/car/updatable/CarServiceProxy.java b/src/com/android/internal/car/CarServiceProxy.java
similarity index 65%
rename from updatableServices/src/com/android/internal/car/updatable/CarServiceProxy.java
rename to src/com/android/internal/car/CarServiceProxy.java
index 0824755..42c344b 100644
--- a/updatableServices/src/com/android/internal/car/updatable/CarServiceProxy.java
+++ b/src/com/android/internal/car/CarServiceProxy.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.car.updatable;
+package com.android.internal.car;
 
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STARTING;
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STOPPED;
@@ -27,22 +27,23 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.car.ICarResultReceiver;
-import android.car.builtin.os.UserManagerHelper;
-import android.car.builtin.util.Slogf;
-import android.car.builtin.util.TimingsTraceLog;
+import android.content.pm.UserInfo;
 import android.os.RemoteException;
+import android.os.Trace;
 import android.os.UserHandle;
+import android.util.DebugUtils;
+import android.util.IndentingPrintWriter;
+import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 
 import com.android.car.internal.ICarSystemServerClient;
 import com.android.car.internal.common.CommonConstants.UserLifecycleEventType;
-import com.android.car.internal.util.DebugUtils;
-import com.android.car.internal.util.IndentingPrintWriter;
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.IResultReceiver;
 import com.android.internal.util.Preconditions;
+import com.android.server.SystemService.TargetUser;
+import com.android.server.utils.TimingsTraceAndSlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -88,13 +89,10 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface PendingOperationId{}
 
-    @VisibleForTesting
-    static final String TAG = CarServiceProxy.class.getSimpleName();
-
-    private static final long TRACE_TAG_SYSTEM_SERVER = 1L << 19;
     private static final boolean DBG = false;
+    private static final String TAG = CarServiceProxy.class.getSimpleName();
 
-    private static final int USER_SYSTEM = UserHandle.SYSTEM.getIdentifier();
+    private static final long LIFECYCLE_TIMESTAMP_IGNORE = 0;
 
     private final Object mLock = new Object();
 
@@ -102,10 +100,10 @@
     private boolean mCarServiceCrashed;
     @UserIdInt
     @GuardedBy("mLock")
-    private int mLastSwitchedUser = UserManagerHelper.USER_NULL;
+    private int mLastSwitchedUser = UserHandle.USER_NULL;
     @UserIdInt
     @GuardedBy("mLock")
-    private int mPreviousUserOfLastSwitchedUser = UserManagerHelper.USER_NULL;
+    private int mPreviousUserOfLastSwitchedUser = UserHandle.USER_NULL;
     // Key: user id, value: life-cycle
     @GuardedBy("mLock")
     private final SparseIntArray mLastUserLifecycle = new SparseIntArray();
@@ -116,21 +114,19 @@
     @GuardedBy("mLock")
     private ICarSystemServerClient mCarService;
 
-    private final CarServiceHelperServiceUpdatableImpl mCarServiceHelperServiceUpdatableImpl;
+    private final CarServiceHelperService mCarServiceHelperService;
     private final UserMetrics mUserMetrics = new UserMetrics();
-    @GuardedBy("mLock")
-    private UserHandle mInitialUser;
 
-    CarServiceProxy(CarServiceHelperServiceUpdatableImpl carServiceHelperServiceUpdatableImpl) {
-        mCarServiceHelperServiceUpdatableImpl = carServiceHelperServiceUpdatableImpl;
+    CarServiceProxy(CarServiceHelperService carServiceHelperService) {
+        mCarServiceHelperService = carServiceHelperService;
     }
 
     /**
      * Handles new CarService Connection.
      */
     void handleCarServiceConnection(ICarSystemServerClient carService) {
-        Slogf.i(TAG, "CarService connected.");
-        TimingsTraceLog t = newTimingsTraceLog();
+        Slog.i(TAG, "CarService connected.");
+        TimingsTraceAndSlog t = newTimingsTraceAndSlog();
         t.traceBegin("handleCarServiceConnection");
         synchronized (mLock) {
             mCarService = carService;
@@ -140,37 +136,9 @@
             runQueuedOperationLocked(PO_ON_FACTORY_RESET);
         }
         sendLifeCycleEvents();
-        sendInitialUser();
         t.traceEnd();
     }
 
-    private void sendInitialUser() {
-        UserHandle initialUser;
-        ICarSystemServerClient carService;
-        synchronized (mLock) {
-            initialUser = mInitialUser;
-            carService = mCarService;
-        }
-        if (initialUser != null && carService != null) {
-            try {
-                carService.setInitialUser(initialUser);
-            } catch (RemoteException e) {
-                Slogf.w(TAG, "RemoteException from car service while calling setInitialUser.", e);
-            }
-        } else {
-            Slogf.i(TAG, "Didn't send Initial User, User: %s, CarService: %s", initialUser,
-                    carService);
-        }
-    }
-
-    void saveInitialUser(UserHandle user) {
-        synchronized (mLock) {
-            if (user != null || user.getIdentifier() != UserManagerHelper.USER_NULL) {
-                mInitialUser = user;
-            }
-        }
-    }
-
     @GuardedBy("mLock")
     private void runQueuedOperationLocked(@PendingOperationId int operationId) {
         PendingOperation pendingOperation = mPendingOperations.get(operationId);
@@ -179,7 +147,7 @@
             return;
         }
         if (DBG) {
-            Slogf.d(TAG, "No queued operation of type " + pendingOperationToString(operationId));
+            Slog.d(TAG, "No queued operation of type " + pendingOperationToString(operationId));
         }
     }
 
@@ -193,14 +161,13 @@
         }
 
         // Send user0 events first
-        int user0Lifecycle = lastUserLifecycle.get(USER_SYSTEM);
-        boolean user0IsCurrent = lastSwitchedUser == USER_SYSTEM;
+        int user0Lifecycle = lastUserLifecycle.get(UserHandle.USER_SYSTEM);
+        boolean user0IsCurrent = lastSwitchedUser == UserHandle.USER_SYSTEM;
         // If user0Lifecycle is 0, then no life-cycle event received yet.
         if (user0Lifecycle != 0) {
-            sendAllLifecyleToUser(USER_SYSTEM, user0Lifecycle,
-                    user0IsCurrent);
+            sendAllLifecyleToUser(UserHandle.USER_SYSTEM, user0Lifecycle, user0IsCurrent);
         }
-        lastUserLifecycle.delete(USER_SYSTEM);
+        lastUserLifecycle.delete(UserHandle.USER_SYSTEM);
 
         // Send current user events next
         if (!user0IsCurrent) {
@@ -225,28 +192,28 @@
     private void sendAllLifecyleToUser(@UserIdInt int userId, int lifecycle,
             boolean isCurrentUser) {
         if (DBG) {
-            Slogf.d(TAG, "sendAllLifecyleToUser, user:" + userId + " lifecycle:" + lifecycle);
+            Slog.d(TAG, "sendAllLifecyleToUser, user:" + userId + " lifecycle:" + lifecycle);
         }
         if (lifecycle >= USER_LIFECYCLE_EVENT_TYPE_STARTING) {
-            sendUserLifecycleEventInternal(USER_LIFECYCLE_EVENT_TYPE_STARTING,
-                    UserManagerHelper.USER_NULL, userId);
+            sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_STARTING, UserHandle.USER_NULL,
+                    userId);
         }
 
-        if (isCurrentUser && userId != USER_SYSTEM) {
+        if (isCurrentUser && userId != UserHandle.USER_SYSTEM) {
             synchronized (mLock) {
-                sendUserLifecycleEventInternal(USER_LIFECYCLE_EVENT_TYPE_SWITCHING,
+                sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_SWITCHING,
                         mPreviousUserOfLastSwitchedUser, userId);
             }
         }
 
         if (lifecycle >= USER_LIFECYCLE_EVENT_TYPE_UNLOCKING) {
-            sendUserLifecycleEventInternal(USER_LIFECYCLE_EVENT_TYPE_UNLOCKING,
-                    UserManagerHelper.USER_NULL, userId);
+            sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKING, UserHandle.USER_NULL,
+                    userId);
         }
 
         if (lifecycle >= USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) {
-            sendUserLifecycleEventInternal(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED,
-                    UserManagerHelper.USER_NULL, userId);
+            sendUserLifecycleEvent(USER_LIFECYCLE_EVENT_TYPE_UNLOCKED, UserHandle.USER_NULL,
+                    userId);
         }
     }
 
@@ -254,7 +221,7 @@
      * Initializes boot user.
      */
     void initBootUser() {
-        if (DBG) Slogf.d(TAG, "initBootUser()");
+        if (DBG) Slog.d(TAG, "initBootUser()");
 
         saveOrRun(PO_INIT_BOOT_USER);
     }
@@ -263,8 +230,8 @@
     /**
      * Callback to indifcate the given user was removed.
      */
-    void onUserRemoved(@NonNull UserHandle user) {
-        if (DBG) Slogf.d(TAG, "onUserRemoved(): " + user);
+    void onUserRemoved(@NonNull UserInfo user) {
+        if (DBG) Slog.d(TAG, "onUserRemoved(): " + user.toFullString());
 
         saveOrRun(PO_ON_USER_REMOVED, user);
     }
@@ -273,8 +240,8 @@
     /**
      * Callback to ask user to confirm if it's ok to factory reset the device.
      */
-    void onFactoryReset(@NonNull ICarResultReceiver callback) {
-        if (DBG) Slogf.d(TAG, "onFactoryReset(): " + callback);
+    void onFactoryReset(@NonNull IResultReceiver callback) {
+        if (DBG) Slog.d(TAG, "onFactoryReset(): " + callback);
 
         saveOrRun(PO_ON_FACTORY_RESET, callback);
     }
@@ -287,7 +254,7 @@
         synchronized (mLock) {
             if (mCarService == null) {
                 if (DBG) {
-                    Slogf.d(TAG, "CarService null. Operation "
+                    Slog.d(TAG, "CarService null. Operation "
                             + pendingOperationToString(operationId)
                             + (value == null ? "" : "(" + value + ")") + " deferred.");
                 }
@@ -305,22 +272,20 @@
 
     @GuardedBy("mLock")
     private void runLocked(@PendingOperationId int operationId, @Nullable Object value) {
-        if (DBG) {
-            Slogf.d(TAG, "runLocked(): " + pendingOperationToString(operationId) + "/" + value);
-        }
+        if (DBG) Slog.d(TAG, "runLocked(): " + pendingOperationToString(operationId) + "/" + value);
         try {
             if (isServiceCrashedLoggedLocked(operationId)) {
                 return;
             }
             sendCarServiceActionLocked(operationId, value);
             if (operationId == PO_ON_FACTORY_RESET) {
-                if (DBG) Slogf.d(TAG, "NOT removing " + pendingOperationToString(operationId));
+                if (DBG) Slog.d(TAG, "NOT removing " + pendingOperationToString(operationId));
                 return;
             }
-            if (DBG) Slogf.d(TAG, "removing " + pendingOperationToString(operationId));
+            if (DBG) Slog.d(TAG, "removing " + pendingOperationToString(operationId));
             mPendingOperations.delete(operationId);
         } catch (RemoteException e) {
-            Slogf.w(TAG, "RemoteException from car service", e);
+            Slog.w(TAG, "RemoteException from car service", e);
             handleCarServiceCrash();
         }
     }
@@ -332,22 +297,22 @@
 
         if (pendingOperation == null) {
             pendingOperation = new PendingOperation(operationId, value);
-            if (DBG) Slogf.d(TAG, "Created " + pendingOperation);
+            if (DBG) Slog.d(TAG, "Created " + pendingOperation);
             mPendingOperations.put(operationId, pendingOperation);
             return;
         }
         switch (operationId) {
             case PO_ON_USER_REMOVED:
-                Preconditions.checkArgument((value instanceof UserHandle),
+                Preconditions.checkArgument((value instanceof UserInfo),
                         "invalid value passed to ON_USER_REMOVED", value);
                 if (pendingOperation.value instanceof ArrayList) {
-                    if (DBG) Slogf.d(TAG, "Adding " + value + " to existing " + pendingOperation);
+                    if (DBG) Slog.d(TAG, "Adding " + value + " to existing " + pendingOperation);
                     ((ArrayList) pendingOperation.value).add(value);
-                } else if (pendingOperation.value instanceof UserHandle) {
+                } else if (pendingOperation.value instanceof UserInfo) {
                     ArrayList<Object> list = new ArrayList<>(2);
                     list.add(pendingOperation.value);
                     list.add(value);
-                    if (DBG) Slogf.d(TAG, "Converting " + pendingOperation.value + " to " + list);
+                    if (DBG) Slog.d(TAG, "Converting " + pendingOperation.value + " to " + list);
                     pendingOperation.value = list;
                 } else {
                     throw new IllegalStateException("Invalid value for ON_USER_REMOVED: " + value);
@@ -355,12 +320,12 @@
                 break;
             case PO_ON_FACTORY_RESET:
                 PendingOperation newOperation = new PendingOperation(operationId, value);
-                if (DBG) Slogf.d(TAG, "Replacing " + pendingOperation + " by " + newOperation);
+                if (DBG) Slog.d(TAG, "Replacing " + pendingOperation + " by " + newOperation);
                 mPendingOperations.put(operationId, newOperation);
                 break;
             default:
                 if (DBG) {
-                    Slogf.d(TAG, "Already saved operation of type "
+                    Slog.d(TAG, "Already saved operation of type "
                             + pendingOperationToString(operationId));
                 }
         }
@@ -370,7 +335,7 @@
     private void sendCarServiceActionLocked(@PendingOperationId int operationId,
             @Nullable Object value) throws RemoteException {
         if (DBG) {
-            Slogf.d(TAG, "sendCarServiceActionLocked: Operation "
+            Slog.d(TAG, "sendCarServiceActionLocked: Operation "
                     + pendingOperationToString(operationId));
         }
         switch (operationId) {
@@ -380,7 +345,7 @@
             case PO_ON_USER_REMOVED:
                 if (value instanceof ArrayList) {
                     ArrayList<Object> list = (ArrayList<Object>) value;
-                    if (DBG) Slogf.d(TAG, "Sending " + list.size() + " onUserRemoved() calls");
+                    if (DBG) Slog.d(TAG, "Sending " + list.size() + " onUserRemoved() calls");
                     for (Object user: list) {
                         onUserRemovedLocked(user);
                     }
@@ -389,56 +354,58 @@
                 }
                 break;
             case PO_ON_FACTORY_RESET:
-                mCarService.onFactoryReset((ICarResultReceiver) value);
+                mCarService.onFactoryReset((IResultReceiver) value);
                 break;
             default:
-                Slogf.wtf(TAG, "Invalid Operation. OperationId -" + operationId);
+                Slog.wtf(TAG, "Invalid Operation. OperationId -" + operationId);
         }
     }
 
     @GuardedBy("mLock")
     private void onUserRemovedLocked(@NonNull Object value) throws RemoteException {
-        Preconditions.checkArgument((value instanceof UserHandle),
+        Preconditions.checkArgument((value instanceof UserInfo),
                 "Invalid value for ON_USER_REMOVED: %s", value);
-        UserHandle user = (UserHandle) value;
-        if (DBG) Slogf.d(TAG, "Sending onUserRemoved(): " + user);
+        UserInfo user = (UserInfo) value;
+        if (DBG) Slog.d(TAG, "Sending onUserRemoved(): " + user.toFullString());
         mCarService.onUserRemoved(user);
     }
 
     /**
      * Sends user life-cycle events to CarService.
      */
-    void sendUserLifecycleEvent(@UserLifecycleEventType int eventType, @UserIdInt int fromId,
-            @UserIdInt int toId) {
+    void sendUserLifecycleEvent(@UserLifecycleEventType int eventType, @Nullable TargetUser from,
+            @NonNull TargetUser to) {
         long now = System.currentTimeMillis();
+        int fromId = from == null ? UserHandle.USER_NULL : from.getUserIdentifier();
+        int toId = to.getUserIdentifier();
         mUserMetrics.onEvent(eventType, now, fromId, toId);
 
         synchronized (mLock) {
             if (eventType == USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
-                mLastSwitchedUser = toId;
-                mPreviousUserOfLastSwitchedUser = fromId;
-                mLastUserLifecycle.put(toId, eventType);
+                mLastSwitchedUser = to.getUserIdentifier();
+                mPreviousUserOfLastSwitchedUser = from.getUserIdentifier();
+                mLastUserLifecycle.put(to.getUserIdentifier(), eventType);
             } else if (eventType == USER_LIFECYCLE_EVENT_TYPE_STOPPING
                     || eventType == USER_LIFECYCLE_EVENT_TYPE_STOPPED) {
-                mLastUserLifecycle.delete(toId);
+                mLastUserLifecycle.delete(to.getUserIdentifier());
             } else {
-                mLastUserLifecycle.put(toId, eventType);
+                mLastUserLifecycle.put(to.getUserIdentifier(), eventType);
             }
             if (mCarService == null) {
                 if (DBG) {
-                    Slogf.d(TAG, "CarService null. sendUserLifecycleEvent() deferred for lifecycle"
-                            + " event " + eventType + " for user " + toId);
+                    Slog.d(TAG, "CarService null. sendUserLifecycleEvent() deferred for lifecycle"
+                            + " event " + eventType + " for user " + to);
                 }
                 return;
             }
         }
-        sendUserLifecycleEventInternal(eventType, fromId, toId);
+        sendUserLifecycleEvent(eventType, fromId, toId);
     }
 
-    private void sendUserLifecycleEventInternal(@UserLifecycleEventType int eventType,
+    private void sendUserLifecycleEvent(@UserLifecycleEventType int eventType,
             @UserIdInt int fromId, @UserIdInt int toId) {
         if (DBG) {
-            Slogf.d(TAG, "sendUserLifecycleEvent():" + " eventType=" + eventType + ", fromId="
+            Slog.d(TAG, "sendUserLifecycleEvent():" + " eventType=" + eventType + ", fromId="
                     + fromId + ", toId=" + toId);
         }
         try {
@@ -447,7 +414,7 @@
                 mCarService.onUserLifecycleEvent(eventType, fromId, toId);
             }
         } catch (RemoteException e) {
-            Slogf.w(TAG, "RemoteException from car service", e);
+            Slog.w(TAG, "RemoteException from car service", e);
             handleCarServiceCrash();
         }
     }
@@ -457,12 +424,12 @@
             mCarServiceCrashed = true;
             mCarService = null;
         }
-        Slogf.w(TAG, "CarServiceCrashed. No more car service calls before reconnection.");
-        mCarServiceHelperServiceUpdatableImpl.handleCarServiceCrash();
+        Slog.w(TAG, "CarServiceCrashed. No more car service calls before reconnection.");
+        mCarServiceHelperService.handleCarServiceCrash();
     }
 
-    private TimingsTraceLog newTimingsTraceLog() {
-        return new TimingsTraceLog(TAG, TRACE_TAG_SYSTEM_SERVER);
+    private TimingsTraceAndSlog newTimingsTraceAndSlog() {
+        return new TimingsTraceAndSlog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
     }
 
     @GuardedBy("mLock")
@@ -473,8 +440,7 @@
     @GuardedBy("mLock")
     private boolean isServiceCrashedLoggedLocked(@NonNull String operation) {
         if (mCarServiceCrashed) {
-            Slogf.w(TAG, "CarServiceCrashed. " + operation + " will be executed after "
-                    + "reconnection");
+            Slog.w(TAG, "CarServiceCrashed. " + operation + " will be executed after reconnection");
             return true;
         }
         return false;
@@ -484,37 +450,33 @@
      * Dump
      */
     void dump(IndentingPrintWriter writer) {
-        // Do not change the next line, Used in cts test: testCarServiceHelperServiceDump
         writer.println("CarServiceProxy");
         writer.increaseIndent();
-        synchronized (mLock) {
-            writer.printf("mLastSwitchedUser=%s\n", mLastSwitchedUser);
-            writer.printf("mInitialUser=%s\n", mInitialUser);
-            writer.printf("mLastUserLifecycle:\n");
-            int user0Lifecycle = mLastUserLifecycle.get(USER_SYSTEM, 0);
-            if (user0Lifecycle != 0) {
-                writer.printf("SystemUser Lifecycle Event:%s\n", user0Lifecycle);
-            } else {
-                writer.println("SystemUser not initialized");
-            }
+        writer.printf("mLastSwitchedUser=%s\n", mLastSwitchedUser);
+        writer.printf("mLastUserLifecycle:\n");
+        int user0Lifecycle = mLastUserLifecycle.get(UserHandle.USER_SYSTEM, 0);
+        if (user0Lifecycle != 0) {
+            writer.printf("SystemUser Lifecycle Event:%s\n", user0Lifecycle);
+        } else {
+            writer.println("SystemUser not initialized");
+        }
 
-            int lastUserLifecycle = mLastUserLifecycle.get(mLastSwitchedUser, 0);
-            if (mLastSwitchedUser != USER_SYSTEM && user0Lifecycle != 0) {
-                writer.printf("last user (%s) Lifecycle Event:%s\n",
-                        mLastSwitchedUser, lastUserLifecycle);
-            }
+        int lastUserLifecycle = mLastUserLifecycle.get(mLastSwitchedUser, 0);
+        if (mLastSwitchedUser != UserHandle.USER_SYSTEM && user0Lifecycle != 0) {
+            writer.printf("last user (%s) Lifecycle Event:%s\n",
+                    mLastSwitchedUser, lastUserLifecycle);
+        }
 
-            int size = mPendingOperations.size();
-            if (size == 0) {
-                writer.println("No pending operations");
-            } else {
-                writer.printf("%d pending operation%s:\n", size, size == 1 ? "" : "s");
-                writer.increaseIndent();
-                for (int i = 0; i < size; i++) {
-                    writer.println(mPendingOperations.valueAt(i));
-                }
-                writer.decreaseIndent();
+        int size = mPendingOperations.size();
+        if (size == 0) {
+            writer.println("No pending operations");
+        } else {
+            writer.printf("%d pending operation%s:\n", size, size == 1 ? "" : "s");
+            writer.increaseIndent();
+            for (int i = 0; i < size; i++) {
+                writer.println(mPendingOperations.valueAt(i));
             }
+            writer.decreaseIndent();
         }
         writer.decreaseIndent();
         dumpUserMetrics(writer);
diff --git a/updatableServices/src/com/android/internal/car/updatable/UserMetrics.java b/src/com/android/internal/car/UserMetrics.java
similarity index 94%
rename from updatableServices/src/com/android/internal/car/updatable/UserMetrics.java
rename to src/com/android/internal/car/UserMetrics.java
index 31a4bfd..ff5fa75 100644
--- a/updatableServices/src/com/android/internal/car/updatable/UserMetrics.java
+++ b/src/com/android/internal/car/UserMetrics.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.car.updatable;
+package com.android.internal.car;
 
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STARTING;
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STOPPED;
@@ -26,13 +26,13 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
-import android.car.builtin.util.Slogf;
-import android.car.builtin.util.TimeUtils;
+import android.util.IndentingPrintWriter;
+import android.util.LocalLog;
+import android.util.Slog;
 import android.util.SparseArray;
+import android.util.TimeUtils;
 
 import com.android.car.internal.common.CommonConstants.UserLifecycleEventType;
-import com.android.car.internal.util.IndentingPrintWriter;
-import com.android.car.internal.util.LocalLog;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -105,7 +105,7 @@
                     onUserStoppedEventLocked(timestampMs, toUserId);
                     return;
                 default:
-                    Slogf.w(TAG, "Invalid event: " + eventType);
+                    Slog.w(TAG, "Invalid event: " + eventType);
             }
         }
     }
@@ -131,7 +131,7 @@
 
         UserStartingMetric existingMetrics = mUserStartingMetrics.get(userId);
         if (existingMetrics != null) {
-            Slogf.w(TAG, "user re-started: " + existingMetrics);
+            Slog.w(TAG, "user re-started: " + existingMetrics);
             finishUserStartingLocked(existingMetrics, /* removeMetric= */ false);
         }
 
@@ -169,7 +169,7 @@
         }
         UserStoppingMetric existingMetrics = mUserStoppingMetrics.get(userId);
         if (existingMetrics != null) {
-            Slogf.w(TAG, "user re-stopped: " + existingMetrics);
+            Slog.w(TAG, "user re-stopped: " + existingMetrics);
             finishUserStoppingLocked(existingMetrics, /* removeMetric= */ false);
         }
         mUserStoppingMetrics.put(userId, new UserStoppingMetric(userId, timestampMs));
@@ -187,15 +187,14 @@
     private <T extends BaseUserMetric> T getExistingMetricsLocked(
             @NonNull SparseArray<? extends BaseUserMetric> metrics, @UserIdInt int userId) {
         if (metrics == null) {
-            Slogf.w(TAG, "getExistingMetricsLocked() should not pass null metrics, except on "
-                    + "tests");
+            Slog.w(TAG, "getExistingMetricsLocked() should not pass null metrics, except on tests");
             return null;
         }
         @SuppressWarnings("unchecked")
         T metric = (T) metrics.get(userId);
         if (metric == null) {
             String name = metrics == mUserStartingMetrics ? "starting" : "stopping";
-            Slogf.w(TAG, "no " + name + " metrics for user " + userId);
+            Slog.w(TAG, "no " + name + " metrics for user " + userId);
         }
         return metric;
     }
diff --git a/src/com/android/server/wm/CarLaunchParamsModifier.java b/src/com/android/server/wm/CarLaunchParamsModifier.java
new file mode 100644
index 0000000..0997ff2
--- /dev/null
+++ b/src/com/android/server/wm/CarLaunchParamsModifier.java
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2019 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.wm;
+
+import static com.android.server.wm.ActivityStarter.Request;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityOptions;
+import android.app.ActivityTaskManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.hardware.display.DisplayManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.util.Slog;
+import android.util.SparseIntArray;
+import android.view.Display;
+import android.window.WindowContainerToken;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Class to control the assignment of a display for Car while launching a Activity.
+ *
+ * <p>This one controls which displays users are allowed to launch.
+ * The policy should be passed from car service through
+ * {@link com.android.internal.car.ICarServiceHelper} binder interfaces. If no policy is set,
+ * this module will not change anything for launch process.</p>
+ *
+ * <p> The policy can only affect which display passenger users can use. Current user, assumed
+ * to be a driver user, is allowed to launch any display always.</p>
+ */
+public final class CarLaunchParamsModifier implements LaunchParamsController.LaunchParamsModifier {
+
+    private static final String TAG = "CAR.LAUNCH";
+    private static final boolean DBG = false;
+
+    private final Context mContext;
+
+    private DisplayManager mDisplayManager;  // set only from init()
+    private ActivityTaskManagerService mAtm;  // set only from init()
+
+    private final Object mLock = new Object();
+
+    // Always start with USER_SYSTEM as the timing of handleCurrentUserSwitching(USER_SYSTEM) is not
+    // guaranteed to be earler than 1st Activity launch.
+    @GuardedBy("mLock")
+    private int mCurrentDriverUser = UserHandle.USER_SYSTEM;
+
+    // TODO: Switch from tracking displays to tracking display areas instead
+    /**
+     * This one is for holding all passenger (=profile user) displays which are mostly static unless
+     * displays are added / removed. Note that {@link #mDisplayToProfileUserMapping} can be empty
+     * while user is assigned and that cannot always tell if specific display is for driver or not.
+     */
+    @GuardedBy("mLock")
+    private final ArrayList<Integer> mPassengerDisplays = new ArrayList<>();
+
+    /** key: display id, value: profile user id */
+    @GuardedBy("mLock")
+    private final SparseIntArray mDisplayToProfileUserMapping = new SparseIntArray();
+
+    /** key: profile user id, value: display id */
+    @GuardedBy("mLock")
+    private final SparseIntArray mDefaultDisplayForProfileUser = new SparseIntArray();
+
+    @GuardedBy("mLock")
+    private boolean mIsSourcePreferred;
+
+    @GuardedBy("mLock")
+    private List<ComponentName> mSourcePreferredComponents;
+
+
+    @VisibleForTesting
+    final DisplayManager.DisplayListener mDisplayListener =
+            new DisplayManager.DisplayListener() {
+        @Override
+        public void onDisplayAdded(int displayId) {
+            // ignore. car service should update whiltelist.
+        }
+
+        @Override
+        public void onDisplayRemoved(int displayId) {
+            synchronized (mLock) {
+                mPassengerDisplays.remove(Integer.valueOf(displayId));
+                updateProfileUserConfigForDisplayRemovalLocked(displayId);
+            }
+        }
+
+        @Override
+        public void onDisplayChanged(int displayId) {
+            // ignore
+        }
+    };
+
+    private void updateProfileUserConfigForDisplayRemovalLocked(int displayId) {
+        mDisplayToProfileUserMapping.delete(displayId);
+        int i = mDefaultDisplayForProfileUser.indexOfValue(displayId);
+        if (i >= 0) {
+            mDefaultDisplayForProfileUser.removeAt(i);
+        }
+    }
+
+    /** Constructor. Can be constructed any time. */
+    public CarLaunchParamsModifier(Context context) {
+        // This can be very early stage. So postpone interaction with other system until init.
+        mContext = context;
+    }
+
+    /**
+     * Initializes all internal stuffs. This should be called only after ATMS, DisplayManagerService
+     * are ready.
+     */
+    public void init() {
+        mAtm = (ActivityTaskManagerService) ActivityTaskManager.getService();
+        LaunchParamsController controller = mAtm.mTaskSupervisor.getLaunchParamsController();
+        controller.registerModifier(this);
+        mDisplayManager = mContext.getSystemService(DisplayManager.class);
+        mDisplayManager.registerDisplayListener(mDisplayListener,
+                new Handler(Looper.getMainLooper()));
+    }
+
+    /**
+     * Sets sourcePreferred configuration. When sourcePreferred is enabled and there is no pre-
+     * assigned display for the Activity, CarLauncherParamsModifier will launch the Activity in
+     * the display of the source. When sourcePreferredComponents isn't null the sourcePreferred
+     * is applied for the sourcePreferredComponents only.
+     *
+     * @param enableSourcePreferred whether to enable sourcePreferred mode
+     * @param sourcePreferredComponents null for all components, or the list of components to apply
+     */
+    public void setSourcePreferredComponents(boolean enableSourcePreferred,
+            @Nullable List<ComponentName> sourcePreferredComponents) {
+        synchronized (mLock) {
+            mIsSourcePreferred = enableSourcePreferred;
+            mSourcePreferredComponents = sourcePreferredComponents;
+            if (mSourcePreferredComponents != null) {
+                Collections.sort(mSourcePreferredComponents);
+            }
+        }
+    }
+
+    /** Notifies user switching. */
+    public void handleCurrentUserSwitching(int newUserId) {
+        synchronized (mLock) {
+            mCurrentDriverUser = newUserId;
+            mDefaultDisplayForProfileUser.clear();
+            mDisplayToProfileUserMapping.clear();
+        }
+    }
+
+    private void removeUserFromAllowlistsLocked(int userId) {
+        for (int i = mDisplayToProfileUserMapping.size() - 1; i >= 0; i--) {
+            if (mDisplayToProfileUserMapping.valueAt(i) == userId) {
+                mDisplayToProfileUserMapping.removeAt(i);
+            }
+        }
+        mDefaultDisplayForProfileUser.delete(userId);
+    }
+
+    /** Notifies user stopped. */
+    public void handleUserStopped(int stoppedUser) {
+        // Note that the current user is never stopped. It always takes switching into
+        // non-current user before stopping the user.
+        synchronized (mLock) {
+            removeUserFromAllowlistsLocked(stoppedUser);
+        }
+    }
+
+    /**
+     * Sets display allowlist for the userId. For passenger user, activity will be always launched
+     * to a display in the allowlist. If requested display is not in the allowlist, the 1st display
+     * in the allowlist will be selected as target display.
+     *
+     * <p>The allowlist is kept only for profile user. Assigning the current user unassigns users
+     * for the given displays.
+     */
+    public void setDisplayAllowListForUser(int userId, int[] displayIds) {
+        if (DBG) {
+            Slog.d(TAG, "setDisplayAllowlistForUser userId:" + userId
+                    + " displays:" + displayIds);
+        }
+        synchronized (mLock) {
+            for (int displayId : displayIds) {
+                if (!mPassengerDisplays.contains(displayId)) {
+                    Slog.w(TAG, "setDisplayAllowlistForUser called with display:" + displayId
+                            + " not in passenger display list:" + mPassengerDisplays);
+                    continue;
+                }
+                if (userId == mCurrentDriverUser) {
+                    mDisplayToProfileUserMapping.delete(displayId);
+                } else {
+                    mDisplayToProfileUserMapping.put(displayId, userId);
+                }
+                // now the display cannot be a default display for other user
+                int i = mDefaultDisplayForProfileUser.indexOfValue(displayId);
+                if (i >= 0) {
+                    mDefaultDisplayForProfileUser.removeAt(i);
+                }
+            }
+            if (displayIds.length > 0) {
+                mDefaultDisplayForProfileUser.put(userId, displayIds[0]);
+            } else {
+                removeUserFromAllowlistsLocked(userId);
+            }
+        }
+    }
+
+    /**
+     * Sets displays assigned to passenger. All other displays will be treated as assigned to
+     * driver.
+     *
+     * <p>The 1st display in the array will be considered as a default display to assign
+     * for any non-driver user if there is no display assigned for the user. </p>
+     */
+    public void setPassengerDisplays(int[] displayIdsForPassenger) {
+        if (DBG) {
+            Slog.d(TAG, "setPassengerDisplays displays:" + displayIdsForPassenger);
+        }
+        synchronized (mLock) {
+            for (int id : displayIdsForPassenger) {
+                mPassengerDisplays.remove(Integer.valueOf(id));
+            }
+            // handle removed displays
+            for (int i = 0; i < mPassengerDisplays.size(); i++) {
+                int displayId = mPassengerDisplays.get(i);
+                updateProfileUserConfigForDisplayRemovalLocked(displayId);
+            }
+            mPassengerDisplays.clear();
+            mPassengerDisplays.ensureCapacity(displayIdsForPassenger.length);
+            for (int id : displayIdsForPassenger) {
+                mPassengerDisplays.add(id);
+            }
+        }
+    }
+
+    /**
+     * Decides display to assign while an Activity is launched.
+     *
+     * <p>For current user (=driver), launching to any display is allowed as long as system
+     * allows it.</p>
+     *
+     * <p>For private display, do not change anything as private display has its own logic.</p>
+     *
+     * <p>For passenger displays, only run in allowed displays. If requested display is not
+     * allowed, change to the 1st allowed display.</p>
+     */
+    @Override
+    @Result
+    public int onCalculate(@Nullable Task task, @Nullable ActivityInfo.WindowLayout layout,
+            @Nullable ActivityRecord activity, @Nullable ActivityRecord source,
+            ActivityOptions options, @Nullable Request request, int phase,
+            LaunchParamsController.LaunchParams currentParams,
+            LaunchParamsController.LaunchParams outParams) {
+        int userId;
+        if (task != null) {
+            userId = task.mUserId;
+        } else if (activity != null) {
+            userId = activity.mUserId;
+        } else {
+            Slog.w(TAG, "onCalculate, cannot decide user");
+            return RESULT_SKIP;
+        }
+        // DisplayArea where user wants to launch the Activity.
+        TaskDisplayArea originalDisplayArea = currentParams.mPreferredTaskDisplayArea;
+        // DisplayArea where CarLaunchParamsModifier targets to launch the Activity.
+        TaskDisplayArea targetDisplayArea = null;
+        if (DBG) {
+            Slog.d(TAG, "onCalculate, userId:" + userId
+                    + " original displayArea:" + originalDisplayArea
+                    + " ActivityOptions:" + options);
+        }
+        // If originalDisplayArea is set, respect that before ActivityOptions check.
+        if (originalDisplayArea == null) {
+            if (options != null) {
+                WindowContainerToken daToken = options.getLaunchTaskDisplayArea();
+                if (daToken != null) {
+                    originalDisplayArea = (TaskDisplayArea) WindowContainer.fromBinder(
+                            daToken.asBinder());
+                } else {
+                    int originalDisplayId = options.getLaunchDisplayId();
+                    if (originalDisplayId != Display.INVALID_DISPLAY) {
+                        originalDisplayArea = getDefaultTaskDisplayAreaOnDisplay(originalDisplayId);
+                    }
+                }
+            }
+        }
+        decision:
+        synchronized (mLock) {
+            if (originalDisplayArea == null  // No specified DisplayArea to launch the Activity
+                    && mIsSourcePreferred && source != null
+                    && (mSourcePreferredComponents == null || Collections.binarySearch(
+                            mSourcePreferredComponents, activity.info.getComponentName()) >= 0)) {
+                targetDisplayArea = source.noDisplay ? source.mHandoverTaskDisplayArea
+                        : source.getDisplayArea();
+            } else if (originalDisplayArea == null
+                    && task == null  // launching as a new task
+                    && source != null && !source.getDisplayContent().isTrusted()
+                    && ((activity.info.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0)) {
+                if (DBG) {
+                    Slog.d(TAG, "Disallow launch on virtual display for not-embedded activity.");
+                }
+                targetDisplayArea = getDefaultTaskDisplayAreaOnDisplay(Display.DEFAULT_DISPLAY);
+            }
+            if (userId == mCurrentDriverUser) {
+                // Respect the existing DisplayArea.
+                break decision;
+            }
+            if (userId == UserHandle.USER_SYSTEM) {
+                // This will be only allowed if it has FLAG_SHOW_FOR_ALL_USERS.
+                // The flag is not immediately accessible here so skip the check.
+                // But other WM policy will enforce it.
+                break decision;
+            }
+            // Now user is a passenger.
+            if (mPassengerDisplays.isEmpty()) {
+                // No displays for passengers. This could be old user and do not do anything.
+                break decision;
+            }
+            if (targetDisplayArea == null) {
+                if (originalDisplayArea != null) {
+                    targetDisplayArea = originalDisplayArea;
+                } else {
+                    targetDisplayArea = getDefaultTaskDisplayAreaOnDisplay(Display.DEFAULT_DISPLAY);
+                }
+            }
+            Display display = targetDisplayArea.mDisplayContent.getDisplay();
+            if ((display.getFlags() & Display.FLAG_PRIVATE) != 0) {
+                // private display should follow its own restriction rule.
+                break decision;
+            }
+            if (display.getType() == Display.TYPE_VIRTUAL) {
+                // TODO(b/132903422) : We need to update this after the bug is resolved.
+                // For now, don't change anything.
+                break decision;
+            }
+            int userForDisplay = mDisplayToProfileUserMapping.get(display.getDisplayId(),
+                    UserHandle.USER_NULL);
+            if (userForDisplay == userId) {
+                break decision;
+            }
+            targetDisplayArea = getAlternativeDisplayAreaForPassengerLocked(
+                    userId, activity, request);
+        }
+        if (targetDisplayArea != null && originalDisplayArea != targetDisplayArea) {
+            Slog.i(TAG, "Changed launching display, user:" + userId
+                    + " requested display area:" + originalDisplayArea
+                    + " target display area:" + targetDisplayArea);
+            outParams.mPreferredTaskDisplayArea = targetDisplayArea;
+            return RESULT_DONE;
+        } else {
+            return RESULT_SKIP;
+        }
+    }
+
+    @Nullable
+    private TaskDisplayArea getAlternativeDisplayAreaForPassengerLocked(int userId,
+            @NonNull ActivityRecord activityRecord, @Nullable Request request) {
+        TaskDisplayArea sourceDisplayArea = sourceDisplayArea(userId, activityRecord, request);
+
+        return sourceDisplayArea != null ? sourceDisplayArea : fallbackDisplayArea(userId);
+    }
+
+    @VisibleForTesting
+    @Nullable
+    TaskDisplayArea getDefaultTaskDisplayAreaOnDisplay(int displayId) {
+        DisplayContent dc = mAtm.mRootWindowContainer.getDisplayContentOrCreate(displayId);
+        if (dc == null) {
+            return null;
+        }
+        return dc.getDefaultTaskDisplayArea();
+    }
+
+    /**
+     * Calculates the {@link TaskDisplayArea} for the source of the request. The source is
+     * calculated implicitly from the request or the activity record.
+     *
+     * @param userId ID of the current active user
+     * @param activityRecord {@link ActivityRecord} that is to be shown
+     * @param request {@link Request} data for showing the {@link ActivityRecord}
+     * @return {@link TaskDisplayArea} First non {@code null} candidate display area that is allowed
+     * for the user.  It is allowed if the display has been added to the profile mapping.
+     */
+    @Nullable
+    private TaskDisplayArea sourceDisplayArea(int userId, @NonNull ActivityRecord activityRecord,
+            @Nullable Request request) {
+        List<WindowProcessController> candidateControllers = candidateControllers(activityRecord,
+                request);
+
+        for (int i = 0; i < candidateControllers.size(); i++) {
+            WindowProcessController controller = candidateControllers.get(i);
+            TaskDisplayArea candidate = controller.getTopActivityDisplayArea();
+            int displayId = candidate != null ? candidate.getDisplayId() : Display.INVALID_DISPLAY;
+            int userForDisplay = mDisplayToProfileUserMapping.get(displayId, UserHandle.USER_NULL);
+            if (userForDisplay == userId) {
+                return candidate;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Calculates a list of {@link WindowProcessController} that can calculate the
+     * {@link TaskDisplayArea} to house the {@link ActivityRecord}. Controllers are calculated since
+     * calculating the display can be expensive. The list is ordered in the
+     * following way
+     * <ol>
+     *     <li>Controller for the activity record from the process name and app uid</li>
+     *     <li>Controller for the activity that is launching the given record</li>
+     *     <li>Controller for the actual process that is launching the record</li>
+     * </ol>
+     *
+     * @param activityRecord {@link ActivityRecord} that is to be shown
+     * @param request {@link Request} data for showing the {@link ActivityRecord}
+     * @return {@link List} of {@link WindowProcessController} ordered by preference to be shown
+     */
+    private List<WindowProcessController> candidateControllers(
+            @NonNull ActivityRecord activityRecord, @Nullable Request request) {
+        WindowProcessController firstController = mAtm.getProcessController(
+                activityRecord.getProcessName(), activityRecord.getUid());
+
+        WindowProcessController secondController = mAtm.getProcessController(
+                activityRecord.getLaunchedFromPid(), activityRecord.getLaunchedFromUid());
+
+        WindowProcessController thirdController = request == null ? null :
+                mAtm.getProcessController(request.realCallingPid, request.realCallingUid);
+
+        List<WindowProcessController> candidates = new ArrayList<>(3);
+
+        if (firstController != null) {
+            candidates.add(firstController);
+        }
+        if (secondController != null) {
+            candidates.add(secondController);
+        }
+        if (thirdController != null) {
+            candidates.add(thirdController);
+        }
+
+        return candidates;
+    }
+
+    /**
+     * Return a {@link TaskDisplayArea} that can be used if a source display area is not found.
+     * First check the default display for the user. If it is absent select the first passenger
+     * display if present.  If both are absent return {@code null}
+     *
+     * @param userId ID of the active user
+     * @return {@link TaskDisplayArea} that is recommended when a display area is not specified
+     */
+    @Nullable
+    private TaskDisplayArea fallbackDisplayArea(int userId) {
+        int displayIdForUserProfile = mDefaultDisplayForProfileUser.get(userId,
+                Display.INVALID_DISPLAY);
+        if (displayIdForUserProfile != Display.INVALID_DISPLAY) {
+            int displayId = mDefaultDisplayForProfileUser.get(userId);
+            return getDefaultTaskDisplayAreaOnDisplay(displayId);
+        }
+
+        if (!mPassengerDisplays.isEmpty()) {
+            int displayId = mPassengerDisplays.get(0);
+            return getDefaultTaskDisplayAreaOnDisplay(displayId);
+        }
+
+        return null;
+    }
+
+}
diff --git a/src/jni/com_android_internal_car_CarServiceHelperService.cpp b/src/jni/com_android_internal_car_CarServiceHelperService.cpp
new file mode 100644
index 0000000..3942b77
--- /dev/null
+++ b/src/jni/com_android_internal_car_CarServiceHelperService.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "CarServiceHelperService-JNI"
+
+//#define LOG_NDEBUG 0
+
+#include "jni.h"
+
+#include <nativehelper/JNIHelp.h>
+#include <suspend/autosuspend.h>
+#include <utils/Log.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+static jint nativeForceSuspend(JNIEnv* /* env */, jclass /* clazz */, jint timeoutMs) {
+    jint ret = autosuspend_force_suspend(timeoutMs);
+    ALOGD("nativeForceSuspend returned %d", ret);
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+
+static const JNINativeMethod gCarServiceHelperServiceMethods[] = {
+    /* name, signature, funcPtr */
+    { "nativeForceSuspend", "(I)I",
+            (void*) nativeForceSuspend },
+};
+
+int register_android_internal_car_CarServiceHelperService(JNIEnv* env) {
+    int res = jniRegisterNativeMethods(env, "com/android/internal/car/CarServiceHelperService",
+            gCarServiceHelperServiceMethods, NELEM(gCarServiceHelperServiceMethods));
+    (void) res;  // Faked use when LOG_NDEBUG.
+    LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+    return 0;
+}
+
+} /* namespace android */
+
+
+using namespace android;
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
+{
+    JNIEnv* env = NULL;
+    jint result = -1;
+
+    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        ALOGE("GetEnv failed!");
+        return result;
+    }
+    ALOG_ASSERT(env, "Could not retrieve the env!");
+
+    register_android_internal_car_CarServiceHelperService(env);
+    return JNI_VERSION_1_4;
+}
diff --git a/builtInServices/tests/Android.mk b/tests/Android.mk
similarity index 88%
rename from builtInServices/tests/Android.mk
rename to tests/Android.mk
index c9eee58..1cf4dcc 100644
--- a/builtInServices/tests/Android.mk
+++ b/tests/Android.mk
@@ -8,7 +8,7 @@
     $(call all-java-files-under, ../src) \
     $(call all-Iaidl-files-under, ../src)
 
-LOCAL_PACKAGE_NAME := FrameworkOptCarServicesTest
+LOCAL_PACKAGE_NAME := CarServicesTest
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
 LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_PRIVATE_PLATFORM_APIS := true
@@ -23,21 +23,21 @@
 LOCAL_PROGUARD_ENABLED := disabled
 
 LOCAL_JAVA_LIBRARIES += \
-    android.car \
     android.test.runner \
     android.test.base \
     android.hardware.automotive.vehicle-V2.0-java \
+    com.android.car.internal.common
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android.car.test.utils \
     android.car.watchdoglib \
     androidx.test.ext.junit \
     androidx.test.rules \
+    com.android.car.internal.system \
     mockito-target-extended-minus-junit4 \
     services.core \
     testng \
-    truth-prebuilt \
-    android.car.builtin \
+    truth-prebuilt
 
 # mockito-target-extended dependencies
 LOCAL_JNI_SHARED_LIBRARIES := \
diff --git a/builtInServices/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
similarity index 94%
rename from builtInServices/tests/AndroidManifest.xml
rename to tests/AndroidManifest.xml
index edce0fd..ff050df 100644
--- a/builtInServices/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -22,7 +22,7 @@
       android:targetPackage="com.android.internal.car"
       android:label="Unit Tests for Car Framework Services"/>
 
-  <application android:label="FrameworkOptCarServicesTest"
+  <application android:label="CarServicesTest"
                android:debuggable="true">
     <uses-library android:name="android.test.runner" />
   </application>
diff --git a/builtInServices/tests/src/com/android/internal/car/CarDevicePolicySafetyCheckerTest.java b/tests/src/com/android/internal/car/CarDevicePolicySafetyCheckerTest.java
similarity index 100%
rename from builtInServices/tests/src/com/android/internal/car/CarDevicePolicySafetyCheckerTest.java
rename to tests/src/com/android/internal/car/CarDevicePolicySafetyCheckerTest.java
diff --git a/builtInServices/tests/src/com/android/internal/car/CarServiceHelperServiceTest.java b/tests/src/com/android/internal/car/CarServiceHelperServiceTest.java
similarity index 69%
rename from builtInServices/tests/src/com/android/internal/car/CarServiceHelperServiceTest.java
rename to tests/src/com/android/internal/car/CarServiceHelperServiceTest.java
index 552a27a..a2da2a5 100644
--- a/builtInServices/tests/src/com/android/internal/car/CarServiceHelperServiceTest.java
+++ b/tests/src/com/android/internal/car/CarServiceHelperServiceTest.java
@@ -16,19 +16,23 @@
 
 package com.android.internal.car;
 
-import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_POST_UNLOCKED;
+import static com.android.car.internal.common.CommonConstants.CAR_SERVICE_INTERFACE;
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STARTING;
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STOPPED;
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STOPPING;
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_SWITCHING;
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_UNLOCKING;
-import static com.android.server.SystemService.UserCompletedEventType.newUserCompletedEventTypeForTest;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.ArgumentMatchers.notNull;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 
@@ -36,16 +40,18 @@
 import android.car.test.mocks.AbstractExtendedMockitoTestCase;
 import android.car.watchdoglib.CarWatchdogDaemonHelper;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.os.Binder;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
-import android.os.SystemProperties.Handle;
+
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.server.SystemService;
 import com.android.server.SystemService.TargetUser;
-import com.android.server.SystemService.UserCompletedEventType;
 import com.android.server.wm.CarLaunchParamsModifier;
 
 import org.junit.Before;
@@ -59,6 +65,9 @@
 @RunWith(AndroidJUnit4.class)
 public class CarServiceHelperServiceTest extends AbstractExtendedMockitoTestCase {
 
+    private static final String TAG = CarServiceHelperServiceTest.class.getSimpleName();
+
+    private CarServiceHelperService mHelperSpy;
     private CarServiceHelperService mHelper;
 
     @Mock
@@ -72,14 +81,7 @@
     @Mock
     private IBinder mICarBinder;
     @Mock
-    private CarServiceHelperServiceUpdatable mCarServiceHelperServiceUpdatable;
-
-    @Mock
-    private CarDevicePolicySafetyChecker mCarDevicePolicySafetyChecker;
-
-    public CarServiceHelperServiceTest() {
-        super(CarServiceHelperService.TAG);
-    }
+    private CarServiceProxy mCarServiceProxy;
 
     /**
      * Initialize objects and setup testing environment.
@@ -95,18 +97,40 @@
                 mMockContext,
                 mCarLaunchParamsModifier,
                 mCarWatchdogDaemonHelper,
-                mCarServiceHelperServiceUpdatable,
-                mCarDevicePolicySafetyChecker);
+                mCarServiceProxy);
+        mHelperSpy = spy(mHelper);
         when(mMockContext.getPackageManager()).thenReturn(mPackageManager);
     }
 
     @Test
+    public void testCarServiceLaunched() throws Exception {
+        mockRegisterReceiver();
+        mockBindService();
+        mockLoadLibrary();
+
+        mHelperSpy.onStart();
+
+        verifyBindService();
+    }
+
+    @Test
+    public void testHandleCarServiceCrash() throws Exception {
+        mockHandleCarServiceCrash();
+        mockCarServiceException();
+
+        mHelperSpy.handleCarServiceConnection(mICarBinder);
+
+        verify(mHelperSpy).handleCarServiceCrash();
+    }
+
+    @Test
     public void testOnUserStarting_notifiesICar() throws Exception {
         int userId = 10;
 
         mHelper.onUserStarting(newTargetUser(userId));
 
-        verifyICarOnUserLifecycleEventCalled(USER_LIFECYCLE_EVENT_TYPE_STARTING, userId);
+        verifyICarOnUserLifecycleEventCalled(USER_LIFECYCLE_EVENT_TYPE_STARTING,
+                UserHandle.USER_NULL, userId);
     }
 
     @Test
@@ -141,7 +165,8 @@
 
         mHelper.onUserUnlocking(newTargetUser(userId));
 
-        verifyICarOnUserLifecycleEventCalled(USER_LIFECYCLE_EVENT_TYPE_UNLOCKING, userId);
+        verifyICarOnUserLifecycleEventCalled(USER_LIFECYCLE_EVENT_TYPE_UNLOCKING,
+                UserHandle.USER_NULL, userId);
     }
 
     @Test
@@ -157,7 +182,8 @@
 
         mHelper.onUserStopping(newTargetUser(userId));
 
-        verifyICarOnUserLifecycleEventCalled(USER_LIFECYCLE_EVENT_TYPE_STOPPING, userId);
+        verifyICarOnUserLifecycleEventCalled(USER_LIFECYCLE_EVENT_TYPE_STOPPING,
+                UserHandle.USER_NULL, userId);
     }
 
     @Test
@@ -173,7 +199,8 @@
 
         mHelper.onUserStopped(newTargetUser(userId));
 
-        verifyICarOnUserLifecycleEventCalled(USER_LIFECYCLE_EVENT_TYPE_STOPPED, userId);
+        verifyICarOnUserLifecycleEventCalled(USER_LIFECYCLE_EVENT_TYPE_STOPPED,
+                UserHandle.USER_NULL, userId);
     }
 
     @Test
@@ -190,29 +217,6 @@
         verifyInitBootUser();
     }
 
-    @Test
-    public void testOnUserCompletedEvent_notifiesPostUnlockedEvent() throws Exception {
-        int userId = 10;
-
-        mHelper.onUserCompletedEvent(newTargetUser(userId), newUserCompletedEventTypeForTest(
-                UserCompletedEventType.EVENT_TYPE_USER_UNLOCKED));
-
-        verifyICarOnUserLifecycleEventCalled(USER_LIFECYCLE_EVENT_TYPE_POST_UNLOCKED, userId);
-    }
-
-    @Test
-    public void testOnUserCompletedEvent_preCreatedUserDoesNotNotifyICar() throws Exception {
-        UserCompletedEventType userCompletedEventType = newUserCompletedEventTypeForTest(
-                UserCompletedEventType.EVENT_TYPE_USER_STARTING
-                | UserCompletedEventType.EVENT_TYPE_USER_SWITCHING
-                | UserCompletedEventType.EVENT_TYPE_USER_UNLOCKED);
-
-        mHelper.onUserCompletedEvent(newTargetUser(10, /* preCreated= */true),
-                userCompletedEventType);
-
-        verifyICarOnUserLifecycleEventNeverCalled();
-    }
-
     private TargetUser newTargetUser(int userId) {
         return newTargetUser(userId, /* preCreated= */ false);
     }
@@ -220,11 +224,40 @@
     private TargetUser newTargetUser(int userId, boolean preCreated) {
         TargetUser targetUser = mock(TargetUser.class);
         when(targetUser.getUserIdentifier()).thenReturn(userId);
-        when(targetUser.getUserHandle()).thenReturn(UserHandle.of(userId));
         when(targetUser.isPreCreated()).thenReturn(preCreated);
         return targetUser;
     }
 
+    private void verifyBindService() throws Exception {
+        verify(mMockContext).bindServiceAsUser(
+                argThat(intent -> intent.getAction().equals(CAR_SERVICE_INTERFACE)),
+                any(), eq(Context.BIND_AUTO_CREATE), any(), eq(UserHandle.SYSTEM));
+    }
+
+    private void mockRegisterReceiver() {
+        when(mMockContext.registerReceiverForAllUsers(any(), any(), any(), any()))
+                .thenReturn(new Intent());
+    }
+
+    private void mockBindService() {
+        when(mMockContext.bindServiceAsUser(any(), any(),
+                eq(Context.BIND_AUTO_CREATE), any(), eq(UserHandle.SYSTEM)))
+                .thenReturn(true);
+    }
+
+    private void mockLoadLibrary() {
+        doNothing().when(mHelperSpy).loadNativeLibrary();
+    }
+
+    private void mockCarServiceException() throws Exception {
+        when(mICarBinder.transact(anyInt(), notNull(), isNull(), eq(Binder.FLAG_ONEWAY)))
+                .thenThrow(new RemoteException("mock car service Crash"));
+    }
+
+    private void mockHandleCarServiceCrash() throws Exception {
+        doNothing().when(mHelperSpy).handleCarServiceCrash();
+    }
+
     enum InitialUserInfoAction {
         DEFAULT,
         DEFAULT_WITH_LOCALE,
@@ -239,22 +272,21 @@
 
     private void verifyICarOnUserLifecycleEventCalled(int eventType,
             @UserIdInt int fromId, @UserIdInt int toId) throws Exception {
-        verify(mCarServiceHelperServiceUpdatable).sendUserLifecycleEvent(eventType,
-                UserHandle.of(fromId), UserHandle.of(toId));
+        verify(mCarServiceProxy).sendUserLifecycleEvent(eq(eventType),
+                isTargetUser(fromId), isTargetUser(toId));
     }
 
-    private void verifyICarOnUserLifecycleEventCalled(int eventType,
-            @UserIdInt int userId) throws Exception {
-        verify(mCarServiceHelperServiceUpdatable).sendUserLifecycleEvent(eventType,
-                null, UserHandle.of(userId));
+    private static TargetUser isTargetUser(@UserIdInt int userId) {
+        return argThat((user) -> {
+            return user == null || user.getUserIdentifier() == userId;
+        });
     }
 
     private void verifyICarOnUserLifecycleEventNeverCalled() throws Exception {
-        verify(mCarServiceHelperServiceUpdatable, never()).sendUserLifecycleEvent(anyInt(), any(),
-                any());
+        verify(mCarServiceProxy, never()).sendUserLifecycleEvent(anyInt(), any(), any());
     }
 
     private void verifyInitBootUser() throws Exception {
-        verify(mCarServiceHelperServiceUpdatable).initBootUser();
+        verify(mCarServiceProxy).initBootUser();
     }
 }
diff --git a/updatableServices/tests/src/com/android/internal/car/updatable/CarServiceProxyTest.java b/tests/src/com/android/internal/car/CarServiceProxyTest.java
similarity index 84%
rename from updatableServices/tests/src/com/android/internal/car/updatable/CarServiceProxyTest.java
rename to tests/src/com/android/internal/car/CarServiceProxyTest.java
index 714cf55..74bc8b0 100644
--- a/updatableServices/tests/src/com/android/internal/car/updatable/CarServiceProxyTest.java
+++ b/tests/src/com/android/internal/car/CarServiceProxyTest.java
@@ -13,7 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.internal.car.updatable;
+
+
+package com.android.internal.car;
 
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_SWITCHING;
 
@@ -22,13 +24,13 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
-import android.car.ICarResultReceiver;
 import android.car.test.mocks.AbstractExtendedMockitoTestCase;
 import android.car.test.util.UserTestingHelper.UserInfoBuilder;
 import android.content.pm.UserInfo;
 import android.os.RemoteException;
 
 import com.android.car.internal.ICarSystemServerClient;
+import com.android.internal.os.IResultReceiver;
 import com.android.server.SystemService.TargetUser;
 
 import org.junit.Before;
@@ -38,15 +40,15 @@
 public class CarServiceProxyTest extends AbstractExtendedMockitoTestCase {
 
     @Mock
-    private CarServiceHelperServiceUpdatableImpl mCarServiceHelperServiceUpdatableImpl;
+    private CarServiceHelperService mCarServiceHelperService;
     @Mock
     private ICarSystemServerClient mCarService;
 
     @Mock
-    private ICarResultReceiver mFactoryResetCallback1;
+    private IResultReceiver mFactoryResetCallback1;
 
     @Mock
-    private ICarResultReceiver mFactoryResetCallback2;
+    private IResultReceiver mFactoryResetCallback2;
 
     private final TargetUser mFromUser = new TargetUser(new UserInfo(101, "fromUser", 0));
     private final TargetUser mToUser = new TargetUser(new UserInfo(102, "toUser", 0));
@@ -57,13 +59,9 @@
 
     private CarServiceProxy mCarServiceProxy;
 
-    public CarServiceProxyTest() {
-        super(CarServiceProxy.TAG);
-    }
-
     @Before
     public void setUpMocks() {
-        mCarServiceProxy = new CarServiceProxy(mCarServiceHelperServiceUpdatableImpl);
+        mCarServiceProxy = new CarServiceProxy(mCarServiceHelperService);
     }
 
     @Test
@@ -172,17 +170,16 @@
     }
 
     private void callSendLifecycleEvent(int eventType) {
-        mCarServiceProxy.sendUserLifecycleEvent(eventType, mFromUser.getUserIdentifier(),
-                mToUser.getUserIdentifier());
+        mCarServiceProxy.sendUserLifecycleEvent(eventType, mFromUser, mToUser);
     }
 
     private void callOnUserRemoved() {
-        mCarServiceProxy.onUserRemoved(mRemovedUser1.getUserHandle());
-        mCarServiceProxy.onUserRemoved(mRemovedUser2.getUserHandle());
-        mCarServiceProxy.onUserRemoved(mRemovedUser3.getUserHandle());
+        mCarServiceProxy.onUserRemoved(mRemovedUser1);
+        mCarServiceProxy.onUserRemoved(mRemovedUser2);
+        mCarServiceProxy.onUserRemoved(mRemovedUser3);
     }
 
-    private void callOnFactoryReset(ICarResultReceiver callback) {
+    private void callOnFactoryReset(IResultReceiver callback) {
         mCarServiceProxy.onFactoryReset(callback);
     }
 
@@ -204,20 +201,20 @@
     }
 
     private void verifyOnUserRemovedCalled() throws RemoteException {
-        verify(mCarService).onUserRemoved(mRemovedUser1.getUserHandle());
-        verify(mCarService).onUserRemoved(mRemovedUser2.getUserHandle());
-        verify(mCarService).onUserRemoved(mRemovedUser3.getUserHandle());
+        verify(mCarService).onUserRemoved(mRemovedUser1);
+        verify(mCarService).onUserRemoved(mRemovedUser2);
+        verify(mCarService).onUserRemoved(mRemovedUser3);
     }
 
     private void verifyOnUserRemovedNeverCalled() throws RemoteException {
         verify(mCarService, never()).onUserRemoved(any());
     }
 
-    private void verifyOnFactoryResetCalled(ICarResultReceiver callback) throws RemoteException {
+    private void verifyOnFactoryResetCalled(IResultReceiver callback) throws RemoteException {
         verify(mCarService).onFactoryReset(callback);
     }
 
-    private void verifyOnFactoryResetNotCalled(ICarResultReceiver callback) throws RemoteException {
+    private void verifyOnFactoryResetNotCalled(IResultReceiver callback) throws RemoteException {
         verify(mCarService, never()).onFactoryReset(callback);
     }
 
diff --git a/updatableServices/tests/src/com/android/internal/car/updatable/UserMetricsTest.java b/tests/src/com/android/internal/car/UserMetricsTest.java
similarity index 97%
rename from updatableServices/tests/src/com/android/internal/car/updatable/UserMetricsTest.java
rename to tests/src/com/android/internal/car/UserMetricsTest.java
index b778de4..67ed9f9 100644
--- a/updatableServices/tests/src/com/android/internal/car/updatable/UserMetricsTest.java
+++ b/tests/src/com/android/internal/car/UserMetricsTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.car.updatable;
+package com.android.internal.car;
 
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STARTING;
 import static com.android.car.internal.common.CommonConstants.USER_LIFECYCLE_EVENT_TYPE_STOPPED;
@@ -31,8 +31,8 @@
 import android.os.SystemClock;
 import android.util.SparseArray;
 
-import com.android.internal.car.updatable.UserMetrics.UserStartingMetric;
-import com.android.internal.car.updatable.UserMetrics.UserStoppingMetric;
+import com.android.internal.car.UserMetrics.UserStartingMetric;
+import com.android.internal.car.UserMetrics.UserStoppingMetric;
 
 import org.junit.Test;
 
diff --git a/updatableServices/tests/src/com/android/server/wm/CarLaunchParamsModifierUpdatableTest.java b/tests/src/com/android/server/wm/CarLaunchParamsModifierTest.java
similarity index 73%
rename from updatableServices/tests/src/com/android/server/wm/CarLaunchParamsModifierUpdatableTest.java
rename to tests/src/com/android/server/wm/CarLaunchParamsModifierTest.java
index 13dc733..d641cff 100644
--- a/updatableServices/tests/src/com/android/server/wm/CarLaunchParamsModifierUpdatableTest.java
+++ b/tests/src/com/android/server/wm/CarLaunchParamsModifierTest.java
@@ -25,46 +25,33 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
-import static org.testng.Assert.assertThrows;
 
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
-import android.car.app.CarActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
-import android.content.res.Configuration;
 import android.hardware.display.DisplayManager;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.view.Display;
 import android.view.SurfaceControl;
-import android.window.DisplayAreaOrganizer;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import com.android.internal.policy.AttributeCache;
 import com.android.server.LocalServices;
 import com.android.server.display.color.ColorDisplayService;
-import com.android.server.input.InputManagerService;
-import com.android.server.policy.WindowManagerPolicy;
 
 import org.junit.After;
 import org.junit.Before;
@@ -75,30 +62,24 @@
 import org.mockito.quality.Strictness;
 
 import java.util.Arrays;
-import java.util.function.Function;
 
 /**
  * Tests for {@link CarLaunchParamsModifier}
  * Build/Install/Run:
- *  atest FrameworkOptCarServicesUpdatableTest:CarLaunchParamsModifierUpdatableTest
+ *  atest CarServicesTest:CarLaunchParamsModifierTest
  */
 @RunWith(AndroidJUnit4.class)
-public class CarLaunchParamsModifierUpdatableTest {
+public class CarLaunchParamsModifierTest {
     private static final int PASSENGER_DISPLAY_ID_10 = 10;
     private static final int PASSENGER_DISPLAY_ID_11 = 11;
     private static final int VIRTUAL_DISPLAY_ID_2 = 2;
-    private static final int FEATURE_MAP_ID = 1111;
 
     private MockitoSession mMockingSession;
 
     private CarLaunchParamsModifier mModifier;
-    private CarLaunchParamsModifierUpdatableImpl mUpdatable;
-    private CarLaunchParamsModifierInterface mBuiltin;
 
+    @Mock
     private Context mContext;
-    private WindowManagerService mWindowManagerService;
-    private final WindowManagerGlobalLock mWindowManagerGlobalLock = new WindowManagerGlobalLock();
-
     @Mock
     private DisplayManager mDisplayManager;
     @Mock
@@ -108,15 +89,13 @@
     @Mock
     private RecentTasks mRecentTasks;
     @Mock
+    private WindowManagerService mWindowManagerService;
+    @Mock
     private ColorDisplayService.ColorDisplayServiceInternal mColorDisplayServiceInternal;
     @Mock
     private RootWindowContainer mRootWindowContainer;
     @Mock
     private LaunchParamsController mLaunchParamsController;
-    @Mock
-    private PackageConfigPersister mPackageConfigPersister;
-    @Mock
-    private InputManagerService mInputManagerService;
 
     @Mock
     private Display mDisplay0ForDriver;
@@ -138,7 +117,6 @@
     private Display mDisplay2Virtual;
     @Mock
     private TaskDisplayArea mDisplayArea2Virtual;
-    private TaskDisplayArea mMapTaskDisplayArea;
 
     // All mocks from here before CarLaunchParamsModifier are arguments for
     // LaunchParamsModifier.onCalculate() call.
@@ -167,7 +145,6 @@
         // Return the same id as the display for simplicity
         DisplayContent dc = mock(DisplayContent.class);
         defaultTaskDisplayArea.mDisplayContent = dc;
-        when(defaultTaskDisplayArea.getDisplayContent()).thenReturn(dc);
         when(mRootWindowContainer.getDisplayContentOrCreate(displayId)).thenReturn(dc);
         when(dc.getDisplay()).thenReturn(display);
         when(dc.getDefaultTaskDisplayArea()).thenReturn(defaultTaskDisplayArea);
@@ -181,46 +158,21 @@
                 .mockStatic(ActivityTaskManager.class)
                 .strictness(Strictness.LENIENT)
                 .startMocking();
-        mContext = getInstrumentation().getTargetContext();
-        spyOn(mContext);
-        doReturn(mDisplayManager).when(mContext).getSystemService(eq(DisplayManager.class));
-
+        when(mContext.getSystemService(DisplayManager.class)).thenReturn(mDisplayManager);
         doReturn(mActivityTaskManagerService).when(() -> ActivityTaskManager.getService());
         mActivityTaskManagerService.mTaskSupervisor = mActivityTaskSupervisor;
         when(mActivityTaskSupervisor.getLaunchParamsController()).thenReturn(
                 mLaunchParamsController);
-        mActivityTaskManagerService.mSupportsMultiDisplay = true;
         mActivityTaskManagerService.mRootWindowContainer = mRootWindowContainer;
-        mActivityTaskManagerService.mPackageConfigPersister = mPackageConfigPersister;
-        mActivityTaskManagerService.mWindowOrganizerController =
-                new WindowOrganizerController(mActivityTaskManagerService);
-        when(mActivityTaskManagerService.getTransitionController()).thenCallRealMethod();
-        when(mActivityTaskManagerService.getRecentTasks()).thenReturn(mRecentTasks);
-        when(mActivityTaskManagerService.getGlobalLock()).thenReturn(mWindowManagerGlobalLock);
-
-        mWindowManagerService = WindowManagerService.main(
-                mContext, mInputManagerService, /* showBootMsgs= */ false, /* onlyCore= */ false,
-                /* policy= */ null, mActivityTaskManagerService,
-                /* displayWindowSettingsProvider= */ null, () -> new SurfaceControl.Transaction(),
-                /* surfaceFactory= */ null, /* surfaceControlFactory= */ null);
         mActivityTaskManagerService.mWindowManager = mWindowManagerService;
-        mRootWindowContainer.mWindowManager = mWindowManagerService;
-
+        when(mActivityTaskManagerService.getRecentTasks()).thenReturn(mRecentTasks);
+        mWindowManagerService.mTransactionFactory = () -> new SurfaceControl.Transaction();
         AttributeCache.init(getInstrumentation().getTargetContext());
         LocalServices.addService(ColorDisplayService.ColorDisplayServiceInternal.class,
                 mColorDisplayServiceInternal);
         when(mActivityOptions.getLaunchDisplayId()).thenReturn(INVALID_DISPLAY);
         mockDisplay(mDisplay0ForDriver, mDisplayArea0ForDriver, DEFAULT_DISPLAY,
                 FLAG_TRUSTED, /* type= */ 0);
-        DisplayContent defaultDC = mRootWindowContainer.getDisplayContentOrCreate(DEFAULT_DISPLAY);
-        mMapTaskDisplayArea = new TaskDisplayArea(
-                defaultDC, mWindowManagerService, "MapTDA", FEATURE_MAP_ID);
-        doAnswer((invocation) -> {
-            Function<TaskDisplayArea, TaskDisplayArea> callback = invocation.getArgument(0);
-            return callback.apply(mMapTaskDisplayArea);
-        }).when(defaultDC).getItemFromTaskDisplayAreas(any());
-        when(mActivityRecordSource.getDisplayContent()).thenReturn(defaultDC);
-
         mockDisplay(mDisplay10ForPassenger, mDisplayArea10ForPassenger, PASSENGER_DISPLAY_ID_10,
                 FLAG_TRUSTED, /* type= */ 0);
         mockDisplay(mDisplay11ForPassenger, mDisplayArea11ForPassenger, PASSENGER_DISPLAY_ID_11,
@@ -229,26 +181,23 @@
                 FLAG_TRUSTED | FLAG_PRIVATE, /* type= */ 0);
         mockDisplay(mDisplay2Virtual, mDisplayArea2Virtual, VIRTUAL_DISPLAY_ID_2,
                 FLAG_PRIVATE, /* type= */ 0);
+        DisplayContent defaultDc = mRootWindowContainer.getDisplayContentOrCreate(DEFAULT_DISPLAY);
+        when(mActivityRecordSource.getDisplayContent()).thenReturn(defaultDc);
 
         mModifier = new CarLaunchParamsModifier(mContext);
-        mBuiltin = mModifier.getBuiltinInterface();
-        mUpdatable = new CarLaunchParamsModifierUpdatableImpl(mBuiltin);
-        mModifier.setUpdatable(mUpdatable);
         mModifier.init();
     }
 
     @After
     public void tearDown() {
-        LocalServices.removeServiceForTest(WindowManagerInternal.class);
-        LocalServices.removeServiceForTest(WindowManagerPolicy.class);
         LocalServices.removeServiceForTest(ColorDisplayService.ColorDisplayServiceInternal.class);
         mMockingSession.finishMocking();
     }
 
     private void assertDisplayIsAllowed(@UserIdInt int userId, Display display) {
         mTask.mUserId = userId;
-        mCurrentParams.mPreferredTaskDisplayArea = mBuiltin.getDefaultTaskDisplayAreaOnDisplay(
-                display.getDisplayId()).getTaskDisplayArea();
+        mCurrentParams.mPreferredTaskDisplayArea = mModifier
+                .getDefaultTaskDisplayAreaOnDisplay(display.getDisplayId());
         assertThat(mModifier.onCalculate(mTask, mWindowLayout, mActivityRecordActivity,
                 mActivityRecordSource, mActivityOptions, null /* request */, 0, mCurrentParams,
                 mOutParams))
@@ -259,10 +208,10 @@
             Display displayAssigned) {
         assertThat(displayRequested.getDisplayId()).isNotEqualTo(displayAssigned.getDisplayId());
         mTask.mUserId = userId;
-        TaskDisplayArea requestedTaskDisplayArea = mBuiltin.getDefaultTaskDisplayAreaOnDisplay(
-                displayRequested.getDisplayId()).getTaskDisplayArea();
-        TaskDisplayArea assignedTaskDisplayArea = mBuiltin.getDefaultTaskDisplayAreaOnDisplay(
-                displayAssigned.getDisplayId()).getTaskDisplayArea();
+        TaskDisplayArea requestedTaskDisplayArea = mModifier
+                .getDefaultTaskDisplayAreaOnDisplay(displayRequested.getDisplayId());
+        TaskDisplayArea assignedTaskDisplayArea = mModifier
+                .getDefaultTaskDisplayAreaOnDisplay(displayAssigned.getDisplayId());
         mCurrentParams.mPreferredTaskDisplayArea = requestedTaskDisplayArea;
         assertThat(mModifier.onCalculate(mTask, mWindowLayout, mActivityRecordActivity,
                 mActivityRecordSource, mActivityOptions, null /* request */, 0, mCurrentParams,
@@ -306,14 +255,9 @@
         return new ActivityRecord.Builder(mActivityTaskManagerService)
                 .setIntent(intent)
                 .setActivityInfo(info)
-                .setConfiguration(new Configuration())
                 .build();
     }
 
-    private ActivityRecord buildActivityRecord(ComponentName componentName) {
-        return buildActivityRecord(componentName.getPackageName(), componentName.getClassName());
-    }
-
     @Test
     public void testNoPolicySet() {
         final int randomUserId = 1000;
@@ -336,7 +280,7 @@
 
     @Test
     public void testAllowAllForDriverDuringBoot() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay10ForPassenger.getDisplayId()});
 
         // USER_SYSTEM should be allowed always
@@ -345,7 +289,7 @@
 
     @Test
     public void testAllowAllForDriverAfterUserSwitching() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay10ForPassenger.getDisplayId()});
 
         final int driver1 = 10;
@@ -361,11 +305,11 @@
 
     @Test
     public void testPassengerAllowed() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay11ForPassenger.getDisplayId()});
 
         final int passengerUserId = 100;
-        mUpdatable.setDisplayAllowListForUser(passengerUserId,
+        mModifier.setDisplayAllowListForUser(passengerUserId,
                 new int[]{mDisplay10ForPassenger.getDisplayId()});
 
         assertDisplayIsAllowed(passengerUserId, mDisplay10ForPassenger);
@@ -373,17 +317,17 @@
 
     @Test
     public void testPassengerChange() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay11ForPassenger.getDisplayId()});
 
         int passengerUserId1 = 100;
-        mUpdatable.setDisplayAllowListForUser(passengerUserId1,
+        mModifier.setDisplayAllowListForUser(passengerUserId1,
                 new int[]{mDisplay11ForPassenger.getDisplayId()});
 
         assertDisplayIsAllowed(passengerUserId1, mDisplay11ForPassenger);
 
         int passengerUserId2 = 101;
-        mUpdatable.setDisplayAllowListForUser(passengerUserId2,
+        mModifier.setDisplayAllowListForUser(passengerUserId2,
                 new int[]{mDisplay11ForPassenger.getDisplayId()});
 
         assertDisplayIsAllowed(passengerUserId2, mDisplay11ForPassenger);
@@ -393,11 +337,11 @@
 
     @Test
     public void testPassengerNotAllowed() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay11ForPassenger.getDisplayId()});
 
         final int passengerUserId = 100;
-        mUpdatable.setDisplayAllowListForUser(
+        mModifier.setDisplayAllowListForUser(
                 passengerUserId, new int[]{mDisplay10ForPassenger.getDisplayId()});
 
         assertDisplayIsReassigned(passengerUserId, mDisplay0ForDriver, mDisplay10ForPassenger);
@@ -406,11 +350,11 @@
 
     @Test
     public void testPassengerNotAllowedAfterUserSwitch() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay11ForPassenger.getDisplayId()});
 
         int passengerUserId = 100;
-        mUpdatable.setDisplayAllowListForUser(
+        mModifier.setDisplayAllowListForUser(
                 passengerUserId, new int[]{mDisplay11ForPassenger.getDisplayId()});
         assertDisplayIsAllowed(passengerUserId, mDisplay11ForPassenger);
 
@@ -422,15 +366,15 @@
 
     @Test
     public void testPassengerNotAllowedAfterAssigningCurrentUser() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay11ForPassenger.getDisplayId()});
 
         int passengerUserId = 100;
-        mUpdatable.setDisplayAllowListForUser(
+        mModifier.setDisplayAllowListForUser(
                 passengerUserId, new int[]{mDisplay11ForPassenger.getDisplayId()});
         assertDisplayIsAllowed(passengerUserId, mDisplay11ForPassenger);
 
-        mUpdatable.setDisplayAllowListForUser(
+        mModifier.setDisplayAllowListForUser(
                 UserHandle.USER_SYSTEM, new int[]{mDisplay11ForPassenger.getDisplayId()});
 
         assertDisplayIsReassigned(passengerUserId, mDisplay0ForDriver, mDisplay10ForPassenger);
@@ -439,18 +383,18 @@
 
     @Test
     public void testPassengerDisplayRemoved() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay11ForPassenger.getDisplayId()});
 
         final int passengerUserId = 100;
-        mUpdatable.setDisplayAllowListForUser(passengerUserId,
+        mModifier.setDisplayAllowListForUser(passengerUserId,
                 new int[]{mDisplay10ForPassenger.getDisplayId(),
                         mDisplay11ForPassenger.getDisplayId()});
 
         assertDisplayIsAllowed(passengerUserId, mDisplay10ForPassenger);
         assertDisplayIsAllowed(passengerUserId, mDisplay11ForPassenger);
 
-        mUpdatable.getDisplayListener().onDisplayRemoved(mDisplay11ForPassenger.getDisplayId());
+        mModifier.mDisplayListener.onDisplayRemoved(mDisplay11ForPassenger.getDisplayId());
 
         assertDisplayIsAllowed(passengerUserId, mDisplay10ForPassenger);
         assertDisplayIsReassigned(passengerUserId, mDisplay11ForPassenger, mDisplay10ForPassenger);
@@ -458,18 +402,18 @@
 
     @Test
     public void testPassengerDisplayRemovedFromSetPassengerDisplays() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay11ForPassenger.getDisplayId()});
 
         final int passengerUserId = 100;
-        mUpdatable.setDisplayAllowListForUser(passengerUserId,
+        mModifier.setDisplayAllowListForUser(passengerUserId,
                 new int[]{mDisplay10ForPassenger.getDisplayId(),
                         mDisplay11ForPassenger.getDisplayId()});
 
         assertDisplayIsAllowed(passengerUserId, mDisplay10ForPassenger);
         assertDisplayIsAllowed(passengerUserId, mDisplay11ForPassenger);
 
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId()});
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId()});
 
         assertDisplayIsAllowed(passengerUserId, mDisplay10ForPassenger);
         assertDisplayIsReassigned(passengerUserId, mDisplay11ForPassenger, mDisplay10ForPassenger);
@@ -477,11 +421,11 @@
 
     @Test
     public void testIgnorePrivateDisplay() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay11ForPassenger.getDisplayId()});
 
         final int passengerUserId = 100;
-        mUpdatable.setDisplayAllowListForUser(passengerUserId,
+        mModifier.setDisplayAllowListForUser(passengerUserId,
                 new int[]{mDisplay10ForPassenger.getDisplayId(),
                         mDisplay10ForPassenger.getDisplayId()});
 
@@ -490,13 +434,13 @@
 
     @Test
     public void testDriverPassengerSwap() {
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay10ForPassenger.getDisplayId(),
                 mDisplay11ForPassenger.getDisplayId()});
 
         final int wasDriver = 10;
         final int wasPassenger = 11;
         mModifier.handleCurrentUserSwitching(wasDriver);
-        mUpdatable.setDisplayAllowListForUser(wasPassenger,
+        mModifier.setDisplayAllowListForUser(wasPassenger,
                 new int[]{mDisplay10ForPassenger.getDisplayId(),
                         mDisplay11ForPassenger.getDisplayId()});
 
@@ -510,7 +454,7 @@
         final int driver = wasPassenger;
         final int passenger = wasDriver;
         mModifier.handleCurrentUserSwitching(driver);
-        mUpdatable.setDisplayAllowListForUser(passenger,
+        mModifier.setDisplayAllowListForUser(passenger,
                 new int[]{mDisplay10ForPassenger.getDisplayId(),
                         mDisplay11ForPassenger.getDisplayId()});
 
@@ -529,23 +473,22 @@
         // When no sourcePreferredComponents is set, it doesn't set the display for system user.
         assertNoDisplayIsAssigned(UserHandle.USER_SYSTEM);
 
-        mUpdatable.setSourcePreferredComponents(true, null);
+        mModifier.setSourcePreferredComponents(true, null);
         assertDisplayIsAssigned(UserHandle.USER_SYSTEM, mDisplayArea0ForDriver);
     }
 
     @Test
     public void testPreferSourceForPassenger() {
-        mUpdatable.setPassengerDisplays(
-                new int[]{PASSENGER_DISPLAY_ID_10, PASSENGER_DISPLAY_ID_11});
+        mModifier.setPassengerDisplays(new int[]{PASSENGER_DISPLAY_ID_10, PASSENGER_DISPLAY_ID_11});
         int passengerUserId = 100;
-        mUpdatable.setDisplayAllowListForUser(passengerUserId,
+        mModifier.setDisplayAllowListForUser(passengerUserId,
                 new int[]{PASSENGER_DISPLAY_ID_10, PASSENGER_DISPLAY_ID_11});
         when(mActivityRecordSource.getDisplayArea()).thenReturn(mDisplayArea11ForPassenger);
 
         // When no sourcePreferredComponents is set, it returns the default passenger display.
         assertDisplayIsAssigned(passengerUserId, mDisplayArea10ForPassenger);
 
-        mUpdatable.setSourcePreferredComponents(true, null);
+        mModifier.setSourcePreferredComponents(true, null);
         assertDisplayIsAssigned(passengerUserId, mDisplayArea11ForPassenger);
     }
 
@@ -554,7 +497,7 @@
         when(mActivityOptions.getLaunchDisplayId()).thenReturn(PASSENGER_DISPLAY_ID_10);
         when(mActivityRecordSource.getDisplayArea()).thenReturn(mDisplayArea0ForDriver);
 
-        mUpdatable.setSourcePreferredComponents(true, null);
+        mModifier.setSourcePreferredComponents(true, null);
         assertNoDisplayIsAssigned(UserHandle.USER_SYSTEM);
     }
 
@@ -562,7 +505,7 @@
     public void testPreferSourceForSpecifiedActivity() {
         when(mActivityRecordSource.getDisplayArea()).thenReturn(mDisplayArea0ForDriver);
         mActivityRecordActivity = buildActivityRecord("testPackage", "testActivity");
-        mUpdatable.setSourcePreferredComponents(true,
+        mModifier.setSourcePreferredComponents(true,
                 Arrays.asList(new ComponentName("testPackage", "testActivity")));
 
         assertDisplayIsAssigned(UserHandle.USER_SYSTEM, mDisplayArea0ForDriver);
@@ -572,7 +515,7 @@
     public void testPreferSourceDoNotAssignDisplayForNonSpecifiedActivity() {
         when(mActivityRecordSource.getDisplayArea()).thenReturn(mDisplayArea0ForDriver);
         mActivityRecordActivity = buildActivityRecord("placeholderPackage", "placeholderActivity");
-        mUpdatable.setSourcePreferredComponents(true,
+        mModifier.setSourcePreferredComponents(true,
                 Arrays.asList(new ComponentName("testPackage", "testActivity")));
 
         assertNoDisplayIsAssigned(UserHandle.USER_SYSTEM);
@@ -622,9 +565,9 @@
                 .thenReturn(processName);
         when(mActivityRecordActivity.getUid())
                 .thenReturn(processUid);
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay11ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay11ForPassenger.getDisplayId(),
                 mDisplay10ForPassenger.getDisplayId()});
-        mUpdatable.setDisplayAllowListForUser(userId,
+        mModifier.setDisplayAllowListForUser(userId,
                 new int[]{mDisplay10ForPassenger.getDisplayId()});
         WindowProcessController controller = mock(WindowProcessController.class);
         when(mActivityTaskManagerService.getProcessController(processName, processUid))
@@ -650,9 +593,9 @@
                 .thenReturn(launchedFromPid);
         when(mActivityRecordActivity.getLaunchedFromUid())
                 .thenReturn(launchedFromUid);
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay11ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay11ForPassenger.getDisplayId(),
                 mDisplay10ForPassenger.getDisplayId()});
-        mUpdatable.setDisplayAllowListForUser(userId,
+        mModifier.setDisplayAllowListForUser(userId,
                 new int[]{mDisplay10ForPassenger.getDisplayId()});
         WindowProcessController controller = mock(WindowProcessController.class);
         when(mActivityTaskManagerService.getProcessController(launchedFromPid, launchedFromUid))
@@ -673,9 +616,9 @@
     public void testSourceDisplayFromCallingDisplayIfAvailable() {
         int userId = 10;
         ActivityStarter.Request request = fakeRequest();
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay11ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay11ForPassenger.getDisplayId(),
                 mDisplay10ForPassenger.getDisplayId()});
-        mUpdatable.setDisplayAllowListForUser(userId,
+        mModifier.setDisplayAllowListForUser(userId,
                 new int[]{mDisplay10ForPassenger.getDisplayId()});
         WindowProcessController controller = mock(WindowProcessController.class);
         when(mActivityTaskManagerService.getProcessController(request.realCallingPid,
@@ -696,7 +639,7 @@
     @Test
     public void testSourceDisplayIgnoredIfNotInAllowList() {
         ActivityStarter.Request request = fakeRequest();
-        mUpdatable.setPassengerDisplays(new int[]{mDisplay11ForPassenger.getDisplayId(),
+        mModifier.setPassengerDisplays(new int[]{mDisplay11ForPassenger.getDisplayId(),
                 mDisplay10ForPassenger.getDisplayId()});
         WindowProcessController controller = mock(WindowProcessController.class);
         when(mActivityTaskManagerService.getProcessController(anyString(), anyInt()))
@@ -715,64 +658,7 @@
                 .isEqualTo(mDisplayArea11ForPassenger);
     }
 
-    @Test
-    public void testSetPersistentActivityThrowsExceptionForInvalidDisplayId() {
-        ComponentName mapActivity = new ComponentName("testMapPkg", "mapActivity");
-        int invalidDisplayId = 999990;
-
-        assertThrows(IllegalArgumentException.class,
-                () -> mUpdatable.setPersistentActivity(mapActivity,
-                        invalidDisplayId, DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER));
-    }
-
-    @Test
-    public void testSetPersistentActivityThrowsExceptionForInvalidFeatureId() {
-        ComponentName mapActivity = new ComponentName("testMapPkg", "mapActivity");
-        int invalidFeatureId = 999990;
-
-        assertThrows(IllegalArgumentException.class,
-                () -> mUpdatable.setPersistentActivity(mapActivity,
-                        DEFAULT_DISPLAY, invalidFeatureId));
-    }
-
-    @Test
-    public void testPersistentActivityOverridesTDA() {
-        ComponentName mapActivityName = new ComponentName("testMapPkg", "mapActivity");
-        mActivityRecordActivity = buildActivityRecord(mapActivityName);
-
-        int ret = mUpdatable.setPersistentActivity(
-                mapActivityName, DEFAULT_DISPLAY, FEATURE_MAP_ID);
-        assertThat(ret).isEqualTo(CarActivityManager.RESULT_SUCCESS);
-
-        assertDisplayIsAssigned(UserHandle.USER_SYSTEM, mMapTaskDisplayArea);
-    }
-
-    @Test
-    public void testRemovePersistentActivity() {
-        ComponentName mapActivityName = new ComponentName("testMapPkg", "mapActivity");
-        mActivityRecordActivity = buildActivityRecord(mapActivityName);
-
-        int ret = mUpdatable.setPersistentActivity(
-                mapActivityName, DEFAULT_DISPLAY, FEATURE_MAP_ID);
-        assertThat(ret).isEqualTo(CarActivityManager.RESULT_SUCCESS);
-        // Removes the existing persistent Activity assignment.
-        ret = mUpdatable.setPersistentActivity(mapActivityName, DEFAULT_DISPLAY,
-                DisplayAreaOrganizer.FEATURE_UNDEFINED);
-        assertThat(ret).isEqualTo(CarActivityManager.RESULT_SUCCESS);
-
-        assertNoDisplayIsAssigned(UserHandle.USER_SYSTEM);
-    }
-
-    @Test
-    public void testRemoveUnknownPersistentActivityThrowsException() {
-        ComponentName mapActivity = new ComponentName("testMapPkg", "mapActivity");
-
-        assertThrows(ServiceSpecificException.class,
-                () -> mUpdatable.setPersistentActivity(mapActivity, DEFAULT_DISPLAY,
-                        DisplayAreaOrganizer.FEATURE_UNDEFINED));
-    }
-
-    private static ActivityStarter.Request fakeRequest() {
+    private ActivityStarter.Request fakeRequest() {
         ActivityStarter.Request request = new ActivityStarter.Request();
         request.realCallingPid = 1324;
         request.realCallingUid = 235;
diff --git a/updatableServices/Android.bp b/updatableServices/Android.bp
deleted file mode 100644
index 2adcba7..0000000
--- a/updatableServices/Android.bp
+++ /dev/null
@@ -1,31 +0,0 @@
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-java_library {
-    name: "car-frameworks-service-module",
-    installable: true,
-    libs: [
-            "android.car",
-            "android.car.builtin",
-            "car-frameworks-service",
-            "framework-annotations-lib",
-            "modules-utils-preconditions",
-    ],
-    srcs: [
-        "src/**/*.java",
-    ],
-
-    sdk_version: "module_current",
-    min_sdk_version: "31",
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.car.framework"
-    ],
-    product_variables: {
-        pdk: {
-            enabled: false,
-        },
-    },
-}
-
diff --git a/updatableServices/src/com/android/internal/car/updatable/CarServiceHelperServiceUpdatableImpl.java b/updatableServices/src/com/android/internal/car/updatable/CarServiceHelperServiceUpdatableImpl.java
deleted file mode 100644
index 0b3b094..0000000
--- a/updatableServices/src/com/android/internal/car/updatable/CarServiceHelperServiceUpdatableImpl.java
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2021 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.internal.car.updatable;
-
-import static com.android.car.internal.SystemConstants.ICAR_SYSTEM_SERVER_CLIENT;
-import static com.android.car.internal.common.CommonConstants.CAR_SERVICE_INTERFACE;
-
-import android.annotation.Nullable;
-import android.car.ICar;
-import android.car.ICarResultReceiver;
-import android.car.builtin.os.UserManagerHelper;
-import android.car.builtin.util.EventLogHelper;
-import android.car.builtin.util.Slogf;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-
-import com.android.car.internal.ICarServiceHelper;
-import com.android.car.internal.ICarSystemServerClient;
-import com.android.car.internal.util.IndentingPrintWriter;
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.car.CarServiceHelperInterface;
-import com.android.internal.car.CarServiceHelperServiceUpdatable;
-import java.io.File;
-import com.android.server.wm.CarLaunchParamsModifierInterface;
-import com.android.server.wm.CarLaunchParamsModifierUpdatable;
-import com.android.server.wm.CarLaunchParamsModifierUpdatableImpl;
-
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.function.BiConsumer;
-
-/**
- * Implementation of the abstract class CarServiceHelperUpdatable
- */
-public final class CarServiceHelperServiceUpdatableImpl
-        implements CarServiceHelperServiceUpdatable, Executor {
-
-    @VisibleForTesting
-    static final String TAG = "CarServiceHelper";
-
-    private static final boolean DBG = false;
-
-    private static final String PROP_RESTART_RUNTIME = "ro.car.recovery.restart_runtime.enabled";
-
-    private static final long CAR_SERVICE_BINDER_CALL_TIMEOUT_MS = 15_000;
-
-    private final Runnable mCallbackForCarServiceUnresponsiveness;
-
-    // exit code for
-    private static final int STATUS_CODE_To_EXIT = 10;
-
-    private static final String CAR_SERVICE_PACKAGE = "com.android.car";
-
-    private final Context mContext;
-    private final Object mLock = new Object();
-    @GuardedBy("mLock")
-    private ICar mCarServiceBinder;
-
-    private final Handler mHandler;
-    private final HandlerThread mHandlerThread = new HandlerThread(
-            CarServiceHelperServiceUpdatableImpl.class.getSimpleName());
-
-    private final ICarServiceHelperImpl mHelper = new ICarServiceHelperImpl();
-
-    private final CarServiceConnectedCallback mCarServiceConnectedCallback =
-            new CarServiceConnectedCallback();
-
-    private final CarServiceProxy mCarServiceProxy;
-
-    private final CarServiceHelperInterface mCarServiceHelperInterface;
-
-    private final CarLaunchParamsModifierUpdatableImpl mCarLaunchParamsModifierUpdatable;
-
-    public CarServiceHelperServiceUpdatableImpl(Context context,
-            CarServiceHelperInterface carServiceHelperInterface,
-            CarLaunchParamsModifierInterface carLaunchParamsModifierInterface) {
-        this(context, carServiceHelperInterface, carLaunchParamsModifierInterface,
-                /* carServiceProxy= */ null);
-    }
-
-    @VisibleForTesting
-    CarServiceHelperServiceUpdatableImpl(Context context,
-            CarServiceHelperInterface carServiceHelperInterface,
-            CarLaunchParamsModifierInterface carLaunchParamsModifierInterface,
-            @Nullable CarServiceProxy carServiceProxy) {
-        mContext = context;
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-        mCarServiceHelperInterface = carServiceHelperInterface;
-        mCarLaunchParamsModifierUpdatable = new CarLaunchParamsModifierUpdatableImpl(
-                carLaunchParamsModifierInterface);
-        // carServiceProxy is Nullable because it is not possible to construct carServiceProxy with
-        // "this" object in the previous constructor as CarServiceHelperServiceUpdatableImpl has
-        // not been fully constructed.
-        mCarServiceProxy = carServiceProxy == null ? new CarServiceProxy(this) : carServiceProxy;
-        mCallbackForCarServiceUnresponsiveness = () -> handleCarServiceUnresponsive();
-    }
-
-    private final ServiceConnection mCarServiceConnection = new ServiceConnection() {
-        @Override
-        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
-            if (DBG) Slogf.d(TAG, "onServiceConnected: %s", iBinder);
-            handleCarServiceConnection(iBinder);
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName componentName) {
-            handleCarServiceCrash();
-        }
-    };
-
-    @Override
-    public void onStart() {
-        Intent intent = new Intent(CAR_SERVICE_INTERFACE).setPackage(CAR_SERVICE_PACKAGE);
-        Context userContext = mContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0);
-        if (!userContext.bindService(intent, Context.BIND_AUTO_CREATE, this,
-                mCarServiceConnection)) {
-            Slogf.wtf(TAG, "cannot start car service");
-        }
-    }
-
-    @Override // From Executor
-    public void execute(Runnable command) {
-        mHandler.post(command);
-    }
-
-    @Override
-    public void onUserRemoved(UserHandle user) {
-        mCarServiceProxy.onUserRemoved(user);
-    }
-
-    @Override
-    public void onFactoryReset(BiConsumer<Integer, Bundle> callback) {
-        ICarResultReceiver resultReceiver = new ICarResultReceiver.Stub() {
-            @Override
-            public void send(int resultCode, Bundle resultData) throws RemoteException {
-                callback.accept(resultCode, resultData);
-
-            }
-        };
-        mCarServiceProxy.onFactoryReset(resultReceiver);
-    }
-
-    @Override
-    public void initBootUser() {
-        mCarServiceProxy.initBootUser();
-    }
-
-    @Override
-    public CarLaunchParamsModifierUpdatable getCarLaunchParamsModifierUpdatable() {
-        return mCarLaunchParamsModifierUpdatable;
-    }
-
-    @VisibleForTesting
-    void handleCarServiceConnection(IBinder iBinder) {
-        synchronized (mLock) {
-            if (mCarServiceBinder == ICar.Stub.asInterface(iBinder)) {
-                return; // already connected.
-            }
-            if (DBG) {
-                Slogf.d(TAG, "car service binder changed, was %s new: %s", mCarServiceBinder,
-                        iBinder);
-            }
-            mCarServiceBinder = ICar.Stub.asInterface(iBinder);
-            Slogf.i(TAG, "**CarService connected**");
-        }
-
-        EventLogHelper.writeCarHelperServiceConnected();
-
-        // Post mCallbackForCarServiceUnresponsiveness before setting system server connection
-        // because CarService may respond before the sendSetSystemServerConnectionsCall call
-        // returns and try to remove mCallbackForCarServiceUnresponsiveness from the handler.
-        // Thus, posting this callback after setting system server connection may result in a race
-        // condition where the callback is never removed from the handler.
-        mHandler.removeCallbacks(mCallbackForCarServiceUnresponsiveness);
-        mHandler.postDelayed(mCallbackForCarServiceUnresponsiveness,
-                CAR_SERVICE_BINDER_CALL_TIMEOUT_MS);
-
-        sendSetSystemServerConnectionsCall();
-    }
-
-    @VisibleForTesting
-    void handleCarServiceCrash() {
-        // Recovery behavior.  Kill the system server and reset
-        // everything if enabled by the property.
-        boolean restartOnServiceCrash = SystemProperties.getBoolean(PROP_RESTART_RUNTIME, false);
-        mHandler.removeCallbacks(mCallbackForCarServiceUnresponsiveness);
-
-        mCarServiceHelperInterface.dumpServiceStacks();
-        if (restartOnServiceCrash) {
-            Slogf.w(TAG, "*** CARHELPER KILLING SYSTEM PROCESS: CarService crash");
-            Slogf.w(TAG, "*** GOODBYE!");
-            Process.killProcess(Process.myPid());
-            System.exit(STATUS_CODE_To_EXIT);
-        } else {
-            Slogf.w(TAG, "*** CARHELPER ignoring: CarService crash");
-        }
-    }
-
-    private void sendSetSystemServerConnectionsCall() {
-        ICar binder;
-        synchronized (mLock) {
-            binder = mCarServiceBinder;
-        }
-        try {
-            binder.setSystemServerConnections(mHelper, mCarServiceConnectedCallback);
-        } catch (RemoteException e) {
-            Slogf.w(TAG, e, "RemoteException from car service");
-            handleCarServiceCrash();
-        } catch (RuntimeException e) {
-            Slogf.wtf(TAG, e, "Exception calling setSystemServerConnections");
-            throw e;
-        }
-    }
-
-    private void handleCarServiceUnresponsive() {
-        // This should not happen. Calling this method means ICarSystemServerClient binder is not
-        // returned after service connection. and CarService has not connected in the given time.
-        Slogf.w(TAG, "*** CARHELPER KILLING SYSTEM PROCESS: CarService unresponsive.");
-        Slogf.w(TAG, "*** GOODBYE!");
-        Process.killProcess(Process.myPid());
-        System.exit(STATUS_CODE_To_EXIT);
-    }
-
-    @Override
-    public void sendUserLifecycleEvent(int eventType, UserHandle userFrom, UserHandle userTo) {
-        mCarServiceProxy.sendUserLifecycleEvent(eventType,
-                userFrom == null ? UserManagerHelper.USER_NULL : userFrom.getIdentifier(),
-                userTo.getIdentifier());
-    }
-
-    @Override
-    public void dump(PrintWriter writer,  String[] args) {
-        if (args != null && args.length > 0 && "--user-metrics-only".equals(args[0])) {
-            mCarServiceProxy.dumpUserMetrics(new IndentingPrintWriter(writer));
-            return;
-        }
-
-        if (args != null && args.length > 0 && "--dump-service-stacks".equals(args[0])) {
-            File file = mCarServiceHelperInterface.dumpServiceStacks();
-            if (file != null) {
-                writer.printf("dumpServiceStacks ANR file path=%s\n", file.getAbsolutePath());
-            } else {
-                writer.printf("dumpServiceStacks no ANR file.\n");
-            }
-            return;
-        }
-
-        mCarServiceProxy.dump(new IndentingPrintWriter(writer));
-    }
-
-    private final class ICarServiceHelperImpl extends ICarServiceHelper.Stub {
-
-        @Override
-        public void setDisplayAllowlistForUser(int userId, int[] displayIds) {
-            mCarLaunchParamsModifierUpdatable.setDisplayAllowListForUser(userId, displayIds);
-        }
-
-        @Override
-        public void setPassengerDisplays(int[] displayIdsForPassenger) {
-            mCarLaunchParamsModifierUpdatable.setPassengerDisplays(displayIdsForPassenger);
-        }
-
-        @Override
-        public void setSourcePreferredComponents(boolean enableSourcePreferred,
-                @Nullable List<ComponentName> sourcePreferredComponents) {
-            mCarLaunchParamsModifierUpdatable.setSourcePreferredComponents(
-                    enableSourcePreferred, sourcePreferredComponents);
-        }
-
-        @Override
-        public int setPersistentActivity(ComponentName activity, int displayId, int featureId) {
-            return mCarLaunchParamsModifierUpdatable.setPersistentActivity(
-                    activity, displayId, featureId);
-        }
-
-        @Override
-        public void setSafetyMode(boolean safe) {
-            mCarServiceHelperInterface.setSafetyMode(safe);
-        }
-
-        @Override
-        public UserHandle createUserEvenWhenDisallowed(String name, String userType, int flags) {
-            return mCarServiceHelperInterface.createUserEvenWhenDisallowed(name, userType, flags);
-        }
-
-        @Override
-        public void sendInitialUser(UserHandle user) {
-            mCarServiceProxy.saveInitialUser(user);
-        }
-    }
-
-    private final class CarServiceConnectedCallback extends ICarResultReceiver.Stub {
-        @Override
-        public void send(int resultCode, Bundle resultData) {
-            mHandler.removeCallbacks(mCallbackForCarServiceUnresponsiveness);
-
-            IBinder binder;
-            if (resultData == null
-                    || (binder = resultData.getBinder(ICAR_SYSTEM_SERVER_CLIENT)) == null) {
-                Slogf.wtf(TAG, "setSystemServerConnections return NULL data or Binder.");
-                handleCarServiceUnresponsive();
-                return;
-            }
-
-            ICarSystemServerClient carService = ICarSystemServerClient.Stub.asInterface(binder);
-            mCarServiceProxy.handleCarServiceConnection(carService);
-        }
-    }
-}
diff --git a/updatableServices/src/com/android/server/wm/CarLaunchParamsModifierUpdatableImpl.java b/updatableServices/src/com/android/server/wm/CarLaunchParamsModifierUpdatableImpl.java
deleted file mode 100644
index d836c03..0000000
--- a/updatableServices/src/com/android/server/wm/CarLaunchParamsModifierUpdatableImpl.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2022 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.wm;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.annotation.UserIdInt;
-import android.car.app.CarActivityManager;
-import android.car.builtin.os.UserManagerHelper;
-import android.car.builtin.util.Slogf;
-import android.car.builtin.view.DisplayHelper;
-import android.car.builtin.window.DisplayAreaOrganizerHelper;
-import android.content.ComponentName;
-import android.hardware.display.DisplayManager;
-import android.os.ServiceSpecificException;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.SparseIntArray;
-import android.view.Display;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Implementation of {@link CarLaunchParamsModifierUpdatable}.
- *
- * @hide
- */
-@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
-public final class CarLaunchParamsModifierUpdatableImpl
-        implements CarLaunchParamsModifierUpdatable {
-    private static final String TAG = "CAR.LAUNCH";
-    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
-
-    private final CarLaunchParamsModifierInterface mBuiltin;
-    private final Object mLock = new Object();
-
-    // Always start with USER_SYSTEM as the timing of handleCurrentUserSwitching(USER_SYSTEM) is not
-    // guaranteed to be earler than 1st Activity launch.
-    @GuardedBy("mLock")
-    private int mCurrentDriverUser = UserManagerHelper.USER_SYSTEM;
-
-    // TODO: Switch from tracking displays to tracking display areas instead
-    /**
-     * This one is for holding all passenger (=profile user) displays which are mostly static unless
-     * displays are added / removed. Note that {@link #mDisplayToProfileUserMapping} can be empty
-     * while user is assigned and that cannot always tell if specific display is for driver or not.
-     */
-    @GuardedBy("mLock")
-    private final ArrayList<Integer> mPassengerDisplays = new ArrayList<>();
-
-    /** key: display id, value: profile user id */
-    @GuardedBy("mLock")
-    private final SparseIntArray mDisplayToProfileUserMapping = new SparseIntArray();
-
-    /** key: profile user id, value: display id */
-    @GuardedBy("mLock")
-    private final SparseIntArray mDefaultDisplayForProfileUser = new SparseIntArray();
-
-    @GuardedBy("mLock")
-    private boolean mIsSourcePreferred;
-
-    @GuardedBy("mLock")
-    private List<ComponentName> mSourcePreferredComponents;
-
-    /** key: Activity, value: TaskDisplayAreaWrapper */
-    @GuardedBy("mLock")
-    private final ArrayMap<ComponentName, TaskDisplayAreaWrapper> mPersistentActivities =
-            new ArrayMap<>();
-
-    public CarLaunchParamsModifierUpdatableImpl(CarLaunchParamsModifierInterface builtin) {
-        mBuiltin = builtin;
-    }
-
-    public DisplayManager.DisplayListener getDisplayListener() {
-        return mDisplayListener;
-    }
-
-    private final DisplayManager.DisplayListener mDisplayListener =
-            new DisplayManager.DisplayListener() {
-                @Override
-                public void onDisplayAdded(int displayId) {
-                    // ignore. car service should update whiltelist.
-                }
-
-                @Override
-                public void onDisplayRemoved(int displayId) {
-                    synchronized (mLock) {
-                        mPassengerDisplays.remove(Integer.valueOf(displayId));
-                        updateProfileUserConfigForDisplayRemovalLocked(displayId);
-                    }
-                }
-
-                @Override
-                public void onDisplayChanged(int displayId) {
-                    // ignore
-                }
-            };
-
-    @GuardedBy("mLock")
-    private void updateProfileUserConfigForDisplayRemovalLocked(int displayId) {
-        mDisplayToProfileUserMapping.delete(displayId);
-        int i = mDefaultDisplayForProfileUser.indexOfValue(displayId);
-        if (i >= 0) {
-            mDefaultDisplayForProfileUser.removeAt(i);
-        }
-    }
-
-    /**
-     * Sets {@code sourcePreferred} configuration. When {@code sourcePreferred} is enabled and
-     * there is no pre-assigned display for the Activity, CarLauncherParamsModifier will launch
-     * the Activity in the display of the source. When {@code sourcePreferredComponents} isn't null
-     * the {@code sourcePreferred} is applied for the {@code sourcePreferredComponents} only.
-     *
-     * @param enableSourcePreferred whether to enable sourcePreferred mode
-     * @param sourcePreferredComponents null for all components, or the list of components to apply
-     */
-    public void setSourcePreferredComponents(boolean enableSourcePreferred,
-            @Nullable List<ComponentName> sourcePreferredComponents) {
-        synchronized (mLock) {
-            mIsSourcePreferred = enableSourcePreferred;
-            mSourcePreferredComponents = sourcePreferredComponents;
-            if (mSourcePreferredComponents != null) {
-                Collections.sort(mSourcePreferredComponents);
-            }
-        }
-    }
-
-    /** Notifies user starting. */
-    public void handleUserStarting(int startingUser) {
-       // Do nothing
-    }
-
-    /** Notifies user switching. */
-    public void handleCurrentUserSwitching(@UserIdInt int newUserId) {
-        synchronized (mLock) {
-            mCurrentDriverUser = newUserId;
-            mDefaultDisplayForProfileUser.clear();
-            mDisplayToProfileUserMapping.clear();
-        }
-    }
-
-    @GuardedBy("mLock")
-    private void removeUserFromAllowlistsLocked(int userId) {
-        for (int i = mDisplayToProfileUserMapping.size() - 1; i >= 0; i--) {
-            if (mDisplayToProfileUserMapping.valueAt(i) == userId) {
-                mDisplayToProfileUserMapping.removeAt(i);
-            }
-        }
-        mDefaultDisplayForProfileUser.delete(userId);
-    }
-
-    /** Notifies user stopped. */
-    public void handleUserStopped(@UserIdInt int stoppedUser) {
-        // Note that the current user is never stopped. It always takes switching into
-        // non-current user before stopping the user.
-        synchronized (mLock) {
-            removeUserFromAllowlistsLocked(stoppedUser);
-        }
-    }
-
-    /**
-     * Sets display allowlist for the {@code userId}. For passenger user, activity will be always
-     * launched to a display in the allowlist. If requested display is not in the allowlist, the 1st
-     * display in the allowlist will be selected as target display.
-     *
-     * <p>The allowlist is kept only for profile user. Assigning the current user unassigns users
-     * for the given displays.
-     */
-    public void setDisplayAllowListForUser(@UserIdInt int userId, int[] displayIds) {
-        if (DBG) {
-            Slogf.d(TAG, "setDisplayAllowlistForUser userId:%d displays:%s",
-                    userId, Arrays.toString(displayIds));
-        }
-        synchronized (mLock) {
-            for (int displayId : displayIds) {
-                if (!mPassengerDisplays.contains(displayId)) {
-                    Slogf.w(TAG, "setDisplayAllowlistForUser called with display:%d"
-                            + " not in passenger display list:%s", displayId, mPassengerDisplays);
-                    continue;
-                }
-                if (userId == mCurrentDriverUser) {
-                    mDisplayToProfileUserMapping.delete(displayId);
-                } else {
-                    mDisplayToProfileUserMapping.put(displayId, userId);
-                }
-                // now the display cannot be a default display for other user
-                int i = mDefaultDisplayForProfileUser.indexOfValue(displayId);
-                if (i >= 0) {
-                    mDefaultDisplayForProfileUser.removeAt(i);
-                }
-            }
-            if (displayIds.length > 0) {
-                mDefaultDisplayForProfileUser.put(userId, displayIds[0]);
-            } else {
-                removeUserFromAllowlistsLocked(userId);
-            }
-        }
-    }
-
-    /**
-     * Sets displays assigned to passenger. All other displays will be treated as assigned to
-     * driver.
-     *
-     * <p>The 1st display in the array will be considered as a default display to assign
-     * for any non-driver user if there is no display assigned for the user. </p>
-     */
-    public void setPassengerDisplays(int[] displayIdsForPassenger) {
-        if (DBG) {
-            Slogf.d(TAG, "setPassengerDisplays displays:%s",
-                    Arrays.toString(displayIdsForPassenger));
-        }
-        synchronized (mLock) {
-            for (int id : displayIdsForPassenger) {
-                mPassengerDisplays.remove(Integer.valueOf(id));
-            }
-            // handle removed displays
-            for (int i = 0; i < mPassengerDisplays.size(); i++) {
-                int displayId = mPassengerDisplays.get(i);
-                updateProfileUserConfigForDisplayRemovalLocked(displayId);
-            }
-            mPassengerDisplays.clear();
-            mPassengerDisplays.ensureCapacity(displayIdsForPassenger.length);
-            for (int id : displayIdsForPassenger) {
-                mPassengerDisplays.add(id);
-            }
-        }
-    }
-
-    /**
-     * Calculates {@code outParams} based on the given arguments.
-     * See {@code LaunchParamsController.LaunchParamsModifier.onCalculate()} for the detail.
-     */
-    public int calculate(CalculateParams params) {
-        TaskWrapper task = params.getTask();
-        ActivityRecordWrapper activity = params.getActivity();
-        ActivityRecordWrapper source = params.getSource();
-        ActivityOptionsWrapper options = params.getOptions();
-        RequestWrapper request = params.getRequest();
-        LaunchParamsWrapper currentParams = params.getCurrentParams();
-        LaunchParamsWrapper outParams = params.getOutParams();
-
-        int userId;
-        if (task != null) {
-            userId = task.getUserId();
-        } else if (activity != null) {
-            userId = activity.getUserId();
-        } else {
-            Slogf.w(TAG, "onCalculate, cannot decide user");
-            return LaunchParamsWrapper.RESULT_SKIP;
-        }
-        // DisplayArea where user wants to launch the Activity.
-        TaskDisplayAreaWrapper originalDisplayArea = currentParams.getPreferredTaskDisplayArea();
-        // DisplayArea where CarLaunchParamsModifier targets to launch the Activity.
-        TaskDisplayAreaWrapper targetDisplayArea = null;
-        if (DBG) {
-            Slogf.d(TAG, "onCalculate, userId:%d original displayArea:%s ActivityOptions:%s",
-                    userId, originalDisplayArea, options);
-        }
-        ComponentName activityName = activity.getComponentName();
-        decision:
-        synchronized (mLock) {
-            // If originalDisplayArea is set, respect that before ActivityOptions check.
-            if (originalDisplayArea == null) {
-                if (options != null) {
-                    originalDisplayArea = options.getLaunchTaskDisplayArea();
-                    if (originalDisplayArea == null) {
-                        originalDisplayArea = mBuiltin.getDefaultTaskDisplayAreaOnDisplay(
-                                options.getOptions().getLaunchDisplayId());
-                    }
-                }
-            }
-            if (mPersistentActivities.containsKey(activityName)) {
-                targetDisplayArea = mPersistentActivities.get(activityName);
-            } else if (originalDisplayArea == null  // No specified DA to launch the Activity
-                    && mIsSourcePreferred && source != null
-                    && (mSourcePreferredComponents == null || Collections.binarySearch(
-                    mSourcePreferredComponents, activityName) >= 0)) {
-                targetDisplayArea = source.isNoDisplay() ? source.getHandoverTaskDisplayArea()
-                        : source.getDisplayArea();
-            } else if (originalDisplayArea == null
-                    && task == null  // launching as a new task
-                    && source != null && !source.isDisplayTrusted()
-                    && !source.allowingEmbedded()) {
-                if (DBG) {
-                    Slogf.d(TAG, "Disallow launch on virtual display for not-embedded activity.");
-                }
-                targetDisplayArea = mBuiltin.getDefaultTaskDisplayAreaOnDisplay(
-                        Display.DEFAULT_DISPLAY);
-            }
-            if (userId == mCurrentDriverUser) {
-                // Respect the existing DisplayArea.
-                break decision;
-            }
-            if (userId == UserManagerHelper.USER_SYSTEM) {
-                // This will be only allowed if it has FLAG_SHOW_FOR_ALL_USERS.
-                // The flag is not immediately accessible here so skip the check.
-                // But other WM policy will enforce it.
-                break decision;
-            }
-            // Now user is a passenger.
-            if (mPassengerDisplays.isEmpty()) {
-                // No displays for passengers. This could be old user and do not do anything.
-                break decision;
-            }
-            if (targetDisplayArea == null) {
-                if (originalDisplayArea != null) {
-                    targetDisplayArea = originalDisplayArea;
-                } else {
-                    targetDisplayArea = mBuiltin.getDefaultTaskDisplayAreaOnDisplay(
-                            Display.DEFAULT_DISPLAY);
-                }
-            }
-            Display display = targetDisplayArea.getDisplay();
-            if ((display.getFlags() & Display.FLAG_PRIVATE) != 0) {
-                // private display should follow its own restriction rule.
-                break decision;
-            }
-            if (DisplayHelper.getType(display) == DisplayHelper.TYPE_VIRTUAL) {
-                // TODO(b/132903422) : We need to update this after the bug is resolved.
-                // For now, don't change anything.
-                break decision;
-            }
-            int userForDisplay = mDisplayToProfileUserMapping.get(display.getDisplayId(),
-                    UserManagerHelper.USER_NULL);
-            if (userForDisplay == userId) {
-                break decision;
-            }
-            targetDisplayArea = getAlternativeDisplayAreaForPassengerLocked(
-                    userId, activity, request);
-        }
-        if (targetDisplayArea != null && originalDisplayArea != targetDisplayArea) {
-            Slogf.i(TAG, "Changed launching display, user:%d requested display area:%s"
-                    + " target display area:", userId, originalDisplayArea, targetDisplayArea);
-            outParams.setPreferredTaskDisplayArea(targetDisplayArea);
-            return LaunchParamsWrapper.RESULT_DONE;
-        } else {
-            return LaunchParamsWrapper.RESULT_SKIP;
-        }
-    }
-
-    @GuardedBy("mLock")
-    @Nullable
-    private TaskDisplayAreaWrapper getAlternativeDisplayAreaForPassengerLocked(int userId,
-            @NonNull ActivityRecordWrapper activtyRecord, @Nullable RequestWrapper request) {
-        List<TaskDisplayAreaWrapper> fallbacks = mBuiltin.getFallbackDisplayAreasForActivity(
-                activtyRecord, request);
-        for (int i = 0, size = fallbacks.size(); i < size; ++i) {
-            TaskDisplayAreaWrapper fallbackTda = fallbacks.get(i);
-            int userForDisplay = getUserIdForDisplayLocked(fallbackTda.getDisplay().getDisplayId());
-            if (userForDisplay == userId) {
-                return fallbackTda;
-            }
-        }
-        return fallbackDisplayAreaForUserLocked(userId);
-    }
-
-    /**
-     * Returns {@code userId} who is allowed to use the given {@code displayId}, or
-     * {@code UserHandle.USER_NULL} if the display doesn't exist in the mapping.
-     */
-    @GuardedBy("mLock")
-    private int getUserIdForDisplayLocked(int displayId) {
-        return mDisplayToProfileUserMapping.get(displayId, UserManagerHelper.USER_NULL);
-    }
-
-    /**
-     * Return a {@link TaskDisplayAreaWrapper} that can be used if a source display area is
-     * not found. First check the default display for the user. If it is absent select
-     * the first passenger display if present.  If both are absent return {@code null}
-     *
-     * @param userId ID of the active user
-     * @return {@link TaskDisplayAreaWrapper} that is recommended when a display area is
-     *     not specified
-     */
-    @GuardedBy("mLock")
-    @Nullable
-    private TaskDisplayAreaWrapper fallbackDisplayAreaForUserLocked(@UserIdInt int userId) {
-        int displayIdForUserProfile = mDefaultDisplayForProfileUser.get(userId,
-                Display.INVALID_DISPLAY);
-        if (displayIdForUserProfile != Display.INVALID_DISPLAY) {
-            int displayId = mDefaultDisplayForProfileUser.get(userId);
-            return mBuiltin.getDefaultTaskDisplayAreaOnDisplay(displayId);
-        }
-        if (!mPassengerDisplays.isEmpty()) {
-            int displayId = mPassengerDisplays.get(0);
-            return mBuiltin.getDefaultTaskDisplayAreaOnDisplay(displayId);
-        }
-        return null;
-    }
-
-    /**
-     * See {@link CarActivityManager#setPersistentActivity(android.content.ComponentName,int, int)}
-     */
-    public int setPersistentActivity(ComponentName activity, int displayId, int featureId) {
-        if (DBG) {
-            Slogf.d(TAG, "setPersistentActivity: activity=%s, displayId=%d, featureId=%d",
-                    activity, displayId, featureId);
-        }
-        if (featureId == DisplayAreaOrganizerHelper.FEATURE_UNDEFINED) {
-            synchronized (mLock) {
-                TaskDisplayAreaWrapper removed = mPersistentActivities.remove(activity);
-                if (removed == null) {
-                    throw new ServiceSpecificException(
-                            CarActivityManager.ERROR_CODE_ACTIVITY_NOT_FOUND,
-                            "Failed to remove " + activity.toShortString());
-                }
-                return CarActivityManager.RESULT_SUCCESS;
-            }
-        }
-        TaskDisplayAreaWrapper tda = mBuiltin.findTaskDisplayArea(displayId, featureId);
-        if (tda == null) {
-            throw new IllegalArgumentException("Unknown display=" + displayId
-                    + " or feature=" + featureId);
-        }
-        synchronized (mLock) {
-            mPersistentActivities.put(activity, tda);
-        }
-        return CarActivityManager.RESULT_SUCCESS;
-    }
-}
\ No newline at end of file
diff --git a/updatableServices/tests/Android.bp b/updatableServices/tests/Android.bp
deleted file mode 100644
index 7d9e971..0000000
--- a/updatableServices/tests/Android.bp
+++ /dev/null
@@ -1,50 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    default_applicable_licenses: [
-        "Android-Apache-2.0",
-    ],
-}
-
-android_test {
-    name: "FrameworkOptCarServicesUpdatableTest",
-
-    srcs: [
-        "src/**/*.java",
-    ],
-
-    platform_apis: true,
-
-    certificate: "platform",
-
-    optimize: {
-        enabled: false,
-    },
-
-    libs: [
-        "android.car",
-        "android.car.builtin",
-        "android.test.runner",
-        "android.test.base",
-        "android.hardware.automotive.vehicle-V2.0-java",
-    ],
-
-    static_libs: [
-        "android.car.test.utils",
-        "android.car.watchdoglib",
-        "androidx.test.ext.junit",
-        "androidx.test.rules",
-        "car-frameworks-service.impl",
-        "car-frameworks-service-module",
-        "mockito-target-extended-minus-junit4",
-        "services.core",
-        "testng",
-        "truth-prebuilt",
-    ],
-
-    // mockito-target-extended dependencies
-    jni_libs: [
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-    ],
-
-}
diff --git a/updatableServices/tests/AndroidManifest.xml b/updatableServices/tests/AndroidManifest.xml
deleted file mode 100644
index 2a3e07f..0000000
--- a/updatableServices/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
-    package="com.android.internal.car.updatable"
-    android:sharedUserId="android.uid.system" >
-  <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-      android:targetPackage="com.android.internal.car.updatable"
-      android:label="Unit Tests for Car Framework Updatable Services"/>
-
-  <application android:label="FrameworkOptCarServicesUpdatableTest"
-               android:debuggable="true">
-    <uses-library android:name="android.test.runner" />
-  </application>
-</manifest>
diff --git a/updatableServices/tests/src/com/android/internal/car/updatable/CarServiceHelperServiceUpdatableImplTest.java b/updatableServices/tests/src/com/android/internal/car/updatable/CarServiceHelperServiceUpdatableImplTest.java
deleted file mode 100644
index 6e5231b..0000000
--- a/updatableServices/tests/src/com/android/internal/car/updatable/CarServiceHelperServiceUpdatableImplTest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2021 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.internal.car.updatable;
-
-import static com.android.car.internal.common.CommonConstants.CAR_SERVICE_INTERFACE;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doThrow;
-
-import android.car.ICar;
-import android.car.builtin.os.UserManagerHelper;
-import android.car.test.mocks.AbstractExtendedMockitoTestCase;
-import android.content.Context;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.internal.car.CarServiceHelperInterface;
-import com.android.server.wm.CarLaunchParamsModifierInterface;
-
-import java.util.function.BiConsumer;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-
-/**
- * This class contains unit tests for the {@link CarServiceHelperServiceUpdatableImpl}.
- */
-@RunWith(AndroidJUnit4.class)
-public final class CarServiceHelperServiceUpdatableImplTest
-        extends AbstractExtendedMockitoTestCase {
-
-    @Mock
-    private Context mMockContext;
-    @Mock
-    private CarServiceProxy mCarServiceProxy;
-    @Mock
-    private CarServiceHelperInterface mCarServiceHelperInterface;
-    @Mock
-    private CarLaunchParamsModifierInterface mCarLaunchParamsModifierInterface;
-    @Mock
-    private ICar mICarBinder;
-    @Mock
-    private IBinder mIBinder;
-
-    private CarServiceHelperServiceUpdatableImpl mCarServiceHelperServiceUpdatableImpl;
-
-    public CarServiceHelperServiceUpdatableImplTest() {
-        super(CarServiceHelperServiceUpdatableImpl.TAG);
-    }
-
-    @Before
-    public void setTestFixtures() {
-        mCarServiceHelperServiceUpdatableImpl = new CarServiceHelperServiceUpdatableImpl(
-                mMockContext,
-                mCarServiceHelperInterface,
-                mCarLaunchParamsModifierInterface,
-                mCarServiceProxy);
-    }
-
-    @Test
-    public void testCarServiceLaunched() throws Exception {
-        mockSystemContext();
-        mockBindService();
-
-        mCarServiceHelperServiceUpdatableImpl.onStart();
-
-        verifyBindService();
-    }
-
-    @Test
-    public void testHandleCarServiceConnection() throws Exception {
-        mockICarBinder();
-
-        mCarServiceHelperServiceUpdatableImpl.handleCarServiceConnection(mIBinder);
-
-        verify(mICarBinder).setSystemServerConnections(any(), any());
-    }
-
-    @Test
-    public void testHandleCarServiceCrash() throws Exception {
-        mockICarBinder();
-        doThrow(new RemoteException()).when(mICarBinder).setSystemServerConnections(any(), any());
-
-        mCarServiceHelperServiceUpdatableImpl.handleCarServiceConnection(mIBinder);
-
-        verify(mCarServiceHelperInterface).dumpServiceStacks();
-    }
-
-    @Test
-    public void testOnUserRemoved() throws Exception {
-        UserHandle user = UserHandle.of(101);
-        mCarServiceHelperServiceUpdatableImpl.onUserRemoved(user);
-
-        verify(mCarServiceProxy).onUserRemoved(user);
-    }
-
-    @Test
-    public void testOnFactoryReset() throws Exception {
-        BiConsumer<Integer, Bundle> callback = (x, y) -> {};
-        mCarServiceHelperServiceUpdatableImpl.onFactoryReset(callback);
-
-        verify(mCarServiceProxy).onFactoryReset(any());
-    }
-
-    @Test
-    public void testInitBootUser() throws Exception {
-        mCarServiceHelperServiceUpdatableImpl.initBootUser();
-
-        verify(mCarServiceProxy).initBootUser();
-    }
-
-    @Test
-    public void testSendUserLifecycleEvent_nullFromUser() throws Exception {
-        int eventType = 1;
-        UserHandle userFrom = null;
-        UserHandle userTo = UserHandle.SYSTEM;
-
-        mCarServiceHelperServiceUpdatableImpl.sendUserLifecycleEvent(eventType, userFrom, userTo);
-
-        verify(mCarServiceProxy).sendUserLifecycleEvent(eventType, UserManagerHelper.USER_NULL,
-                userTo.getIdentifier());
-    }
-
-    @Test
-    public void testSendUserLifecycleEvent() throws Exception {
-        int eventType = 1;
-        UserHandle userFrom = UserHandle.SYSTEM;
-        int userId = 101;
-        UserHandle userTo = UserHandle.of(userId);
-
-        mCarServiceHelperServiceUpdatableImpl.sendUserLifecycleEvent(eventType, userFrom, userTo);
-
-        verify(mCarServiceProxy).sendUserLifecycleEvent(eventType, userFrom.getIdentifier(),
-                userTo.getIdentifier());
-    }
-
-    private void mockICarBinder() {
-        when(ICar.Stub.asInterface(mIBinder)).thenReturn(mICarBinder);
-    }
-
-    private void mockSystemContext() {
-        when(mMockContext.createContextAsUser(UserHandle.SYSTEM, /* flags= */ 0))
-                .thenReturn(mMockContext);
-    }
-
-    private void mockBindService() {
-        when(mMockContext.bindService(any(), eq(Context.BIND_AUTO_CREATE), any(), any()))
-                .thenReturn(true);
-    }
-
-    private void verifyBindService() throws Exception {
-        verify(mMockContext).bindService(
-                argThat(intent -> intent.getAction().equals(CAR_SERVICE_INTERFACE)),
-                eq(Context.BIND_AUTO_CREATE), any(), any());
-    }
-}