arc: implement arc data removal in upstart job

Move implementation of arc data removal from session_manager to an
upstart job. This is done with the goal of having the arc data removal
initiated directly from the chrome process instead of needed to proxy it
through session_manager.

BUG=b:115779632
TEST=Ensure arc data is removed after opting out of ARC++
CQ-DEPEND=CL:1226183

Change-Id: Ie9b6cefcea1ccca6c0e6c56f23b267fd7082248d
Reviewed-on: https://chromium-review.googlesource.com/1227386
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Christopher Morin <cmtm@google.com>
Reviewed-by: Luis Hector Chavez <lhchavez@chromium.org>
diff --git a/arc/scripts/arc-remove-data.conf b/arc/scripts/arc-remove-data.conf
new file mode 100644
index 0000000..e9dd85d
--- /dev/null
+++ b/arc/scripts/arc-remove-data.conf
@@ -0,0 +1,24 @@
+# Copyright 2018 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+description   "Remove ARC data for user"
+author        "chromium-os-dev@chromium.org"
+
+# Started by session_manager.
+start on remove-arc-data
+# Stop the job on 'stopping ui' because once ui is stopped, ARC data files
+# in the user's home directory will not be accessible anyway.
+stop on stopping ui
+
+task
+
+import CHROMEOS_USER
+# export for arc-stale-directory-remover.conf
+export CHROMEOS_USER
+
+pre-start exec /sbin/minijail0 -c 0x6 -- \
+    /usr/sbin/arc-setup --log_tag=arc-setup-remove-data --mode=remove-data
+
+# This is needed to ensure this job doesn't remain in the started state.
+exec /bin/true
diff --git a/arc/scripts/arc-stale-directory-remover.conf b/arc/scripts/arc-stale-directory-remover.conf
index a237d4e..07fc2b3 100644
--- a/arc/scripts/arc-stale-directory-remover.conf
+++ b/arc/scripts/arc-stale-directory-remover.conf
@@ -5,35 +5,36 @@
 description   "Remove stale ARC directories."
 author        "chromium-os-dev@chromium.org"
 
-start on remove-old-arc-data or arc-booted
+start on started arc-remove-data or arc-booted
 
 # Stop the job on 'stopping ui' because once ui is stopped, ARC data files
 # in the user's home directory will not be accessible anyway.
 stop on stopping ui
 
-# The following environment variable is passed from session_manager
-# and is imported from the event that starts the job.
-import ANDROID_DATA_OLD_DIR
+import CHROMEOS_USER
 
 script
   {
+    set -u
     echo "Start arc-stale-directory-remover"
-    set -x
 
-    # Do nothing unless the variable is set. Currently this script only handles
-    # that directory.
-    [ -z "$ANDROID_DATA_OLD_DIR" ] && \
-      (echo "\$ANDROID_DATA_OLD_DIR is not set, do nothing." && exit 1)
+    user_root_path="$(cryptohome-path system $CHROMEOS_USER)"
+    # Ensure the user directory exists
+    if [ ! -d "$user_root_path" ]; then
+        echo "<3> ${user_root_path} doesn't exist"
+        exit 1
+    fi
 
-    if [ -d "$ANDROID_DATA_OLD_DIR" ]; then
+    android_data_old_dir="${user_root_path}"/android-data-old
+
+    if [ -d "$android_data_old_dir" ]; then
       # Remove contents of the directory, /home/root/<hash>/android-data-old/.
       # Note that this script does not remove the directory itself to ensure
-      # that RemoveArcData() in session_manager always works regardless of
-      # whether this script is running. Also note that the directory does not
-      # have any dot files and hence "/*" always matches all entries in the
-      # directory.
-      nice rm -rf "$ANDROID_DATA_OLD_DIR"/*
+      # that arc-remove-data.conf always works regardless of whether this
+      # script is running. Also note that the directory does not have any dot
+      # files and hence "/*" always matches all entries in the directory.
+      nice rm -rf "$android_data_old_dir"/*
     fi
     echo "Done."
-  } 2>&1 | logger -t "${UPSTART_JOB}"
+  } 2>&1 | logger --prio-prefix -t "${UPSTART_JOB}"
 end script
diff --git a/arc/setup/arc_setup.cc b/arc/setup/arc_setup.cc
index 9cece54..423a2c3 100644
--- a/arc/setup/arc_setup.cc
+++ b/arc/setup/arc_setup.cc
@@ -40,6 +40,7 @@
 #include <base/threading/platform_thread.h>
 #include <base/time/time.h>
 #include <base/timer/elapsed_timer.h>
+#include <brillo/cryptohome.h>
 #include <brillo/file_utils.h>
 #include <chromeos-config/libcros_config/cros_config.h>
 #include <crypto/random.h>
@@ -2185,6 +2186,19 @@
   EmulateArcUreadahead(arc_paths_->android_rootfs_directory, kReadAheadTimeout);
 }
 
+void ArcSetup::OnRemoveData() {
+  const std::string chromeos_user = config_.GetStringOrDie("CHROMEOS_USER");
+  const base::FilePath root_path =
+      brillo::cryptohome::home::GetRootPath(chromeos_user);
+  // Ensure the user directory exists.
+  EXIT_IF(!base::DirectoryExists(root_path));
+
+  const base::FilePath android_data = root_path.Append("android-data");
+  const base::FilePath android_data_old = root_path.Append("android-data-old");
+
+  EXIT_IF(!MoveDirIntoDataOldDir(android_data, android_data_old));
+}
+
 void ArcSetup::OnMountSdcard() {
   // Set up sdcard asynchronously from arc-sdcard so that waiting on installd
   // does not add latency to boot-continue (and result in session-manager
@@ -2276,6 +2290,9 @@
     case Mode::READ_AHEAD:
       OnReadAhead();
       break;
+    case Mode::REMOVE_DATA:
+      OnRemoveData();
+      break;
     case Mode::MOUNT_SDCARD:
       OnMountSdcard();
       break;
diff --git a/arc/setup/arc_setup.h b/arc/setup/arc_setup.h
index e57bb11..3724e17 100644
--- a/arc/setup/arc_setup.h
+++ b/arc/setup/arc_setup.h
@@ -67,6 +67,7 @@
 
   PRE_CHROOT,
   READ_AHEAD,
+  REMOVE_DATA,
   MOUNT_SDCARD,
   UNMOUNT_SDCARD,
   UPDATE_RESTORECON_LAST,
@@ -353,6 +354,9 @@
   // Called when arc-setup is called with --mode=read-ahead.
   void OnReadAhead();
 
+  // Called when arc-setup is called with --mode=remove-data.
+  void OnRemoveData();
+
   // Called when arc-setup is called with --mode=mount-sdcard.
   void OnMountSdcard();
 
diff --git a/arc/setup/main.cc b/arc/setup/main.cc
index 0fc3b68..a42e938 100644
--- a/arc/setup/main.cc
+++ b/arc/setup/main.cc
@@ -33,6 +33,7 @@
       {"onetime-stop", arc::Mode::ONETIME_STOP},
       {"pre-chroot", arc::Mode::PRE_CHROOT},
       {"read-ahead", arc::Mode::READ_AHEAD},
+      {"remove-data", arc::Mode::REMOVE_DATA},
       {"mount-sdcard", arc::Mode::MOUNT_SDCARD},
       {"unmount-sdcard", arc::Mode::UNMOUNT_SDCARD},
       {"update-restorecon-last", arc::Mode::UPDATE_RESTORECON_LAST},
diff --git a/login_manager/session_manager_impl.cc b/login_manager/session_manager_impl.cc
index 6aa7906..5747844 100644
--- a/login_manager/session_manager_impl.cc
+++ b/login_manager/session_manager_impl.cc
@@ -107,8 +107,7 @@
 constexpr char SessionManagerImpl::kContinueArcBootImpulse[] =
     "continue-arc-boot";
 constexpr char SessionManagerImpl::kArcBootedImpulse[] = "arc-booted";
-constexpr char SessionManagerImpl::kRemoveOldArcDataImpulse[] =
-    "remove-old-arc-data";
+constexpr char SessionManagerImpl::kRemoveArcDataImpulse[] = "remove-arc-data";
 
 // Lock state related impulse (systemd unit start or Upstart signal).
 constexpr char SessionManagerImpl::kScreenLockedImpulse[] = "screen-locked";
@@ -1268,10 +1267,7 @@
       DCHECK(*error);
       return false;
     }
-    const base::FilePath android_data_old_dir =
-        GetAndroidDataOldDirForUser(actual_account_id);
-    env_vars.emplace_back("ANDROID_DATA_OLD_DIR=" +
-                          android_data_old_dir.value());
+    env_vars.emplace_back("CHROMEOS_USER=" + actual_account_id);
   }
 
   init_controller_->TriggerImpulse(kArcBootedImpulse, env_vars,
@@ -1301,35 +1297,19 @@
 bool SessionManagerImpl::RemoveArcData(brillo::ErrorPtr* error,
                                        const std::string& in_account_id) {
 #if USE_CHEETS
-  pid_t pid = 0;
-  if (android_container_->GetContainerPID(&pid) &&
-      android_container_->GetStatefulMode() != StatefulMode::STATELESS) {
-    *error = CreateError(dbus_error::kArcInstanceRunning,
-                         "ARC is currently running in a stateful mode.");
-    return false;
-  }
-
   std::string actual_account_id;
   if (!NormalizeAccountId(in_account_id, &actual_account_id, error)) {
     DCHECK(*error);
     return false;
   }
-  const base::FilePath android_data_dir =
-      GetAndroidDataDirForUser(actual_account_id);
-  const base::FilePath android_data_old_dir =
-      GetAndroidDataOldDirForUser(actual_account_id);
-
-  if (RemoveArcDataInternal(android_data_dir, android_data_old_dir))
-    return true;  // all done.
-
-  PLOG(WARNING) << "Failed to rename " << android_data_dir.value()
-                << "; directly deleting it instead";
-  // As a last resort, directly delete the directory although it's not always
-  // safe to do. If session_manager is killed or the device is shut down while
-  // doing the removal, the directory will have an unusual set of files which
-  // may confuse ARC and prevent it from booting.
-  system_->RemoveDirTree(android_data_dir);
-  LOG(INFO) << "Finished removing " << android_data_dir.value();
+  if (!init_controller_->TriggerImpulse(
+          kRemoveArcDataImpulse, {"CHROMEOS_USER=" + actual_account_id},
+          InitDaemonController::TriggerMode::SYNC)) {
+    constexpr char kMessage[] = "Emitting remove-arc-data impulse failed.";
+    LOG(ERROR) << kMessage;
+    *error = CreateError(dbus_error::kEmitFailed, kMessage);
+    return false;
+  }
   return true;
 #else
   *error = CreateError(dbus_error::kNotAvailable, "ARC not supported.");
@@ -1337,64 +1317,6 @@
 #endif  // USE_CHEETS
 }
 
-#if USE_CHEETS
-bool SessionManagerImpl::RemoveArcDataInternal(
-    const base::FilePath& android_data_dir,
-    const base::FilePath& android_data_old_dir) {
-  // It should never happen, but in case |android_data_old_dir| is a file,
-  // remove it. RemoveFile() immediately returns false (i.e. no-op) when
-  // |android_data_old_dir| is a directory.
-  system_->RemoveFile(android_data_old_dir);
-
-  // Create |android_data_old_dir| if it doesn't exist.
-  if (!system_->DirectoryExists(android_data_old_dir)) {
-    if (!system_->CreateDir(android_data_old_dir)) {
-      PLOG(ERROR) << "Failed to create " << android_data_old_dir.value();
-      return false;
-    }
-  }
-
-  if (!system_->DirectoryExists(android_data_dir) &&
-      system_->IsDirectoryEmpty(android_data_old_dir)) {
-    return true;  // nothing to do.
-  }
-
-  // Create a random temporary directory in |android_data_old_dir|.
-  // Note: Renaming a directory to an existing empty directory works.
-  base::FilePath target_dir_name;
-  if (!system_->CreateTemporaryDirIn(android_data_old_dir, &target_dir_name)) {
-    LOG(WARNING) << "Failed to create a temporary directory in "
-                 << android_data_old_dir.value();
-    return false;
-  }
-  LOG(INFO) << "Renaming " << android_data_dir.value() << " to "
-            << target_dir_name.value();
-
-  // Does the actual renaming here with rename(2). Note that if the process
-  // (or the device itself) is killed / turned off right before the rename(2)
-  // operation, both |android_data_dir| and |android_data_old_dir| will remain
-  // while ARC is disabled in the browser side. In that case, the browser will
-  // call RemoveArcData() later as needed, and both directories will disappear.
-  if (system_->DirectoryExists(android_data_dir)) {
-    if (!system_->RenameDir(android_data_dir, target_dir_name)) {
-      LOG(WARNING) << "Failed to rename " << android_data_dir.value() << " to "
-                   << target_dir_name.value();
-      return false;
-    }
-  }
-
-  // Ask init to remove all files and directories in |android_data_old_dir|.
-  // Note that the init job never deletes |android_data_old_dir| itself so the
-  // rename() operation above never fails.
-  LOG(INFO) << "Removing contents in " << android_data_old_dir.value();
-  init_controller_->TriggerImpulse(
-      kRemoveOldArcDataImpulse,
-      {"ANDROID_DATA_OLD_DIR=" + android_data_old_dir.value()},
-      InitDaemonController::TriggerMode::ASYNC);
-  return true;
-}
-#endif  // USE_CHEETS
-
 void SessionManagerImpl::OnPolicyPersisted(bool success) {
   device_local_account_manager_->UpdateDeviceSettings(
       device_policy_->GetSettings());
diff --git a/login_manager/session_manager_impl.h b/login_manager/session_manager_impl.h
index 728eb55..e879c91 100644
--- a/login_manager/session_manager_impl.h
+++ b/login_manager/session_manager_impl.h
@@ -104,7 +104,7 @@
   static const char kStopArcInstanceImpulse[];
   static const char kContinueArcBootImpulse[];
   static const char kArcBootedImpulse[];
-  static const char kRemoveOldArcDataImpulse[];
+  static const char kRemoveArcDataImpulse[];
 
   // Lock screen state messages.
   static const char kScreenLockedImpulse[];
diff --git a/login_manager/session_manager_impl_test.cc b/login_manager/session_manager_impl_test.cc
index 57badd9..355cf08 100644
--- a/login_manager/session_manager_impl_test.cc
+++ b/login_manager/session_manager_impl_test.cc
@@ -203,17 +203,6 @@
 
 constexpr pid_t kAndroidPid = 10;
 
-enum class DataDirType {
-  DATA_DIR_AVAILABLE = 0,
-  DATA_DIR_MISSING = 1,
-};
-
-enum class OldDataDirType {
-  OLD_DATA_DIR_NOT_EMPTY = 0,
-  OLD_DATA_DIR_EMPTY = 1,
-  OLD_DATA_FILE_EXISTS = 2,
-};
-
 constexpr char kSaneEmail[] = "user@somewhere.com";
 constexpr char kDeviceLocalAccountsDir[] = "device_local_accounts";
 
@@ -607,21 +596,6 @@
                                          false,   // mitigating
                                          false);  // key_gen
   }
-  void ExpectRemoveArcData(DataDirType data_dir_type,
-                           OldDataDirType old_data_dir_type) {
-#if USE_CHEETS
-    if (data_dir_type == DataDirType::DATA_DIR_MISSING &&
-        old_data_dir_type == OldDataDirType::OLD_DATA_DIR_EMPTY) {
-      return;  // RemoveArcDataInternal does nothing in this case.
-    }
-    EXPECT_CALL(
-        *init_controller_,
-        TriggerImpulseInternal(SessionManagerImpl::kRemoveOldArcDataImpulse,
-                               ElementsAre(StartsWith("ANDROID_DATA_OLD_DIR=")),
-                               InitDaemonController::TriggerMode::ASYNC))
-        .WillOnce(Return(nullptr));
-#endif
-  }
 
   void ExpectLockScreen() { expected_locks_ = 1; }
 
@@ -2709,229 +2683,15 @@
 }
 
 TEST_F(SessionManagerImplTest, ArcRemoveData) {
-  // Test that RemoveArcData() removes |android_data_dir_| and reports success
-  // even if the directory is not empty.
-  ASSERT_TRUE(utils_.CreateDir(android_data_dir_));
-  ASSERT_TRUE(utils_.AtomicFileWrite(android_data_dir_.Append("foo"), "test"));
-  ASSERT_FALSE(utils_.Exists(android_data_old_dir_));
-  ExpectRemoveArcData(DataDirType::DATA_DIR_AVAILABLE,
-                      OldDataDirType::OLD_DATA_DIR_EMPTY);
-  brillo::ErrorPtr error;
-  EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
-  EXPECT_FALSE(error.get());
-  EXPECT_FALSE(utils_.Exists(android_data_dir_));
-}
-
-TEST_F(SessionManagerImplTest, ArcRemoveData_NoSourceDirectory) {
-  // Test that RemoveArcData() reports success when the directory does not
-  // exist.
-  ASSERT_FALSE(utils_.Exists(android_data_dir_));
-  ASSERT_FALSE(utils_.Exists(android_data_old_dir_));
-  ExpectRemoveArcData(DataDirType::DATA_DIR_MISSING,
-                      OldDataDirType::OLD_DATA_DIR_EMPTY);
-  brillo::ErrorPtr error;
-  EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
-  EXPECT_FALSE(error.get());
-  EXPECT_FALSE(utils_.Exists(android_data_dir_));
-}
-
-TEST_F(SessionManagerImplTest, ArcRemoveData_OldDirectoryExists) {
-  // Test that RemoveArcData() can remove |android_data_dir_| and
-  // reports success even if the "old" directory already exists.
-  ASSERT_TRUE(utils_.CreateDir(android_data_dir_));
-  ASSERT_TRUE(utils_.AtomicFileWrite(android_data_dir_.Append("foo"), "test"));
-  ASSERT_TRUE(utils_.CreateDir(android_data_old_dir_));
-  ExpectRemoveArcData(DataDirType::DATA_DIR_AVAILABLE,
-                      OldDataDirType::OLD_DATA_DIR_EMPTY);
-  brillo::ErrorPtr error;
-  EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
-  EXPECT_FALSE(error.get());
-  EXPECT_FALSE(utils_.Exists(android_data_dir_));
-}
-
-TEST_F(SessionManagerImplTest, ArcRemoveData_NonEmptyOldDirectoryExists) {
-  // Test that RemoveArcData() can remove |android_data_dir_| and
-  // reports success even if the "old" directory already exists and is not
-  // empty.
-  ASSERT_TRUE(utils_.CreateDir(android_data_dir_));
-  ASSERT_TRUE(utils_.AtomicFileWrite(android_data_dir_.Append("foo"), "test"));
-  ASSERT_TRUE(utils_.CreateDir(android_data_old_dir_));
-  ASSERT_TRUE(
-      utils_.AtomicFileWrite(android_data_old_dir_.Append("bar"), "test2"));
-  ExpectRemoveArcData(DataDirType::DATA_DIR_AVAILABLE,
-                      OldDataDirType::OLD_DATA_DIR_NOT_EMPTY);
-  brillo::ErrorPtr error;
-  EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
-  EXPECT_FALSE(error.get());
-  EXPECT_FALSE(utils_.Exists(android_data_dir_));
-}
-
-TEST_F(SessionManagerImplTest,
-       ArcRemoveData_NoSourceDirectoryButOldDirectoryExists) {
-  // Test that RemoveArcData() removes the "old" directory and reports success
-  // even when |android_data_dir_| does not exist at all.
-  ASSERT_FALSE(utils_.Exists(android_data_dir_));
-  ASSERT_TRUE(utils_.CreateDir(android_data_old_dir_));
-  ExpectRemoveArcData(DataDirType::DATA_DIR_MISSING,
-                      OldDataDirType::OLD_DATA_DIR_EMPTY);
-  brillo::ErrorPtr error;
-  EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
-  EXPECT_FALSE(error.get());
-  EXPECT_FALSE(utils_.Exists(android_data_dir_));
-}
-
-TEST_F(SessionManagerImplTest,
-       ArcRemoveData_NoSourceDirectoryButNonEmptyOldDirectoryExists) {
-  // Test that RemoveArcData() removes the "old" directory and returns
-  // true even when |android_data_dir_| does not exist at all.
-  ASSERT_FALSE(utils_.Exists(android_data_dir_));
-  ASSERT_TRUE(utils_.CreateDir(android_data_old_dir_));
-  ASSERT_TRUE(
-      utils_.AtomicFileWrite(android_data_old_dir_.Append("foo"), "test"));
-  ExpectRemoveArcData(DataDirType::DATA_DIR_MISSING,
-                      OldDataDirType::OLD_DATA_DIR_NOT_EMPTY);
-  brillo::ErrorPtr error;
-  EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
-  EXPECT_FALSE(error.get());
-  EXPECT_FALSE(utils_.Exists(android_data_dir_));
-}
-
-TEST_F(SessionManagerImplTest, ArcRemoveData_OldFileExists) {
-  // Test that RemoveArcData() can remove |android_data_dir_| and
-  // returns true even if the "old" path exists as a file. This should never
-  // happen, but RemoveArcData() can handle the case.
-  ASSERT_TRUE(utils_.CreateDir(android_data_dir_));
-  ASSERT_TRUE(utils_.AtomicFileWrite(android_data_dir_.Append("foo"), "test"));
-  ASSERT_TRUE(utils_.AtomicFileWrite(android_data_old_dir_, "test2"));
-  ExpectRemoveArcData(DataDirType::DATA_DIR_AVAILABLE,
-                      OldDataDirType::OLD_DATA_FILE_EXISTS);
-  brillo::ErrorPtr error;
-  EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
-  EXPECT_FALSE(error.get());
-  EXPECT_FALSE(utils_.Exists(android_data_dir_));
-}
-
-TEST_F(SessionManagerImplTest, ArcRemoveData_ArcRunning_Stateless) {
-  // Test that RemoveArcData proceeds when ARC is running in a stateless mode.
-  ExpectAndRunStartSession(kSaneEmail);
-  ASSERT_TRUE(utils_.CreateDir(android_data_dir_));
-  ASSERT_TRUE(utils_.AtomicFileWrite(android_data_dir_.Append("foo"), "test"));
-  ASSERT_FALSE(utils_.Exists(android_data_old_dir_));
-
+  // Test that RemoveArcData() triggers Upstart event.
   EXPECT_CALL(*init_controller_,
-              TriggerImpulseInternal(
-                  SessionManagerImpl::kStartArcInstanceImpulse,
-                  ElementsAre("CHROMEOS_DEV_MODE=0", "CHROMEOS_INSIDE_VM=0",
-                              "NATIVE_BRIDGE_EXPERIMENT=0"),
-                  InitDaemonController::TriggerMode::ASYNC))
+              TriggerImpulseInternal(SessionManagerImpl::kRemoveArcDataImpulse,
+                                     ElementsAre(StartsWith("CHROMEOS_USER=")),
+                                     InitDaemonController::TriggerMode::SYNC))
       .WillOnce(WithoutArgs(Invoke(CreateEmptyResponse)));
-  {
-    brillo::ErrorPtr error;
-    EXPECT_CALL(utils_, CreateServerHandle(_)).Times(0);
-    std::string container_instance_id;
-    EXPECT_TRUE(impl_->StartArcMiniContainer(
-        &error, SerializeAsBlob(StartArcMiniContainerRequest()),
-        &container_instance_id));
-    EXPECT_FALSE(error.get());
-    EXPECT_FALSE(container_instance_id.empty());
-  }
-
-  ExpectRemoveArcData(DataDirType::DATA_DIR_AVAILABLE,
-                      OldDataDirType::OLD_DATA_DIR_NOT_EMPTY);
-  {
-    brillo::ErrorPtr error;
-    EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
-    ASSERT_FALSE(error.get());
-  }
-  EXPECT_FALSE(utils_.Exists(android_data_dir_));
-}
-
-TEST_F(SessionManagerImplTest, ArcRemoveData_ArcRunning_Stateful) {
-  // Test that RemoveArcData does nothing when ARC is running.
-  ExpectAndRunStartSession(kSaneEmail);
-  ASSERT_TRUE(utils_.CreateDir(android_data_dir_));
-  ASSERT_TRUE(utils_.AtomicFileWrite(android_data_dir_.Append("foo"), "test"));
-  ASSERT_FALSE(utils_.Exists(android_data_old_dir_));
-
-  SetUpArcMiniContainer();
-
-  EXPECT_CALL(
-      *init_controller_,
-      TriggerImpulseInternal(SessionManagerImpl::kContinueArcBootImpulse,
-                             UpgradeContainerExpectationsBuilder(this).Build(),
-                             InitDaemonController::TriggerMode::SYNC))
-      .WillOnce(WithoutArgs(Invoke(CreateEmptyResponse)));
-  {
-    brillo::ErrorPtr error;
-    UpgradeArcContainerRequest request = CreateUpgradeArcContainerRequest();
-    ExpectUpgradeArcContainer();
-    brillo::dbus_utils::FileDescriptor server_socket_fd;
-    EXPECT_TRUE(impl_->UpgradeArcContainer(&error, SerializeAsBlob(request),
-                                           &server_socket_fd));
-    EXPECT_FALSE(error.get());
-    EXPECT_LE(0, server_socket_fd.get());
-  }
-  {
-    brillo::ErrorPtr error;
-    EXPECT_FALSE(impl_->RemoveArcData(&error, kSaneEmail));
-    ASSERT_TRUE(error.get());
-    EXPECT_EQ(dbus_error::kArcInstanceRunning, error->GetCode());
-    EXPECT_TRUE(utils_.Exists(android_data_dir_));
-  }
-}
-
-TEST_F(SessionManagerImplTest, ArcRemoveData_ArcStopped) {
-  ExpectAndRunStartSession(kSaneEmail);
-  ASSERT_TRUE(utils_.CreateDir(android_data_dir_));
-  ASSERT_TRUE(utils_.AtomicFileWrite(android_data_dir_.Append("foo"), "test"));
-  ASSERT_TRUE(utils_.CreateDir(android_data_old_dir_));
-  ASSERT_TRUE(
-      utils_.AtomicFileWrite(android_data_old_dir_.Append("bar"), "test2"));
-
-  std::string container_instance_id = SetUpArcMiniContainer();
-
-  EXPECT_CALL(
-      *init_controller_,
-      TriggerImpulseInternal(SessionManagerImpl::kContinueArcBootImpulse,
-                             UpgradeContainerExpectationsBuilder(this).Build(),
-                             InitDaemonController::TriggerMode::SYNC))
-      .WillOnce(WithoutArgs(Invoke(CreateEmptyResponse)));
-
-  {
-    brillo::ErrorPtr error;
-    UpgradeArcContainerRequest request = CreateUpgradeArcContainerRequest();
-    ExpectUpgradeArcContainer();
-    brillo::dbus_utils::FileDescriptor server_socket_fd;
-    EXPECT_TRUE(impl_->UpgradeArcContainer(&error, SerializeAsBlob(request),
-                                           &server_socket_fd));
-    EXPECT_FALSE(error.get());
-    EXPECT_LE(0, server_socket_fd.get());
-  }
-
-  EXPECT_CALL(*init_controller_,
-              TriggerImpulseInternal(
-                  SessionManagerImpl::kStopArcInstanceImpulse, ElementsAre(),
-                  InitDaemonController::TriggerMode::SYNC))
-      .WillOnce(WithoutArgs(Invoke(CreateEmptyResponse)));
-  EXPECT_CALL(*exported_object(),
-              SendSignal(SignalEq(login_manager::kArcInstanceStopped,
-                                  ArcContainerStopReason::USER_REQUEST,
-                                  container_instance_id)))
-      .Times(1);
-  {
-    brillo::ErrorPtr error;
-    EXPECT_TRUE(impl_->StopArcInstance(&error));
-    EXPECT_FALSE(error.get());
-  }
-
-  ExpectRemoveArcData(DataDirType::DATA_DIR_AVAILABLE,
-                      OldDataDirType::OLD_DATA_DIR_NOT_EMPTY);
-  {
-    brillo::ErrorPtr error;
-    EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
-    EXPECT_FALSE(error.get());
-  }
-  EXPECT_FALSE(utils_.Exists(android_data_dir_));
+  brillo::ErrorPtr error;
+  EXPECT_TRUE(impl_->RemoveArcData(&error, kSaneEmail));
+  EXPECT_FALSE(error.get());
 }
 #else  // !USE_CHEETS
 
@@ -2976,11 +2736,11 @@
 
 TEST_F(SessionManagerImplTest, EmitArcBooted) {
 #if USE_CHEETS
-  EXPECT_CALL(
-      *init_controller_,
-      TriggerImpulseInternal(SessionManagerImpl::kArcBootedImpulse,
-                             ElementsAre(StartsWith("ANDROID_DATA_OLD_DIR=")),
-                             InitDaemonController::TriggerMode::ASYNC))
+  ASSERT_TRUE(utils_.CreateDir(android_data_dir_));
+  EXPECT_CALL(*init_controller_,
+              TriggerImpulseInternal(SessionManagerImpl::kArcBootedImpulse,
+                                     ElementsAre(StartsWith("CHROMEOS_USER=")),
+                                     InitDaemonController::TriggerMode::ASYNC))
       .WillOnce(Return(nullptr));
   {
     brillo::ErrorPtr error;