Revert "cvd start will always run devices in daemon mode"

This reverts commit f2133376486b66ffec788549f166987d7fa94bb2.

Bug: 312643212
Change-Id: I3ea19bdb9cdf26b0a4e5862e4d187b82882dfc67
diff --git a/host/commands/cvd/server_command/Android.bp b/host/commands/cvd/server_command/Android.bp
index 837c808..8bcf7f3 100644
--- a/host/commands/cvd/server_command/Android.bp
+++ b/host/commands/cvd/server_command/Android.bp
@@ -56,3 +56,18 @@
     ],
     defaults: ["cvd_lib_defaults"],
 }
+
+cc_test_host {
+    name: "libcvd_sub_commands_test",
+    srcs: [
+        "start_test.cpp",
+    ],
+    test_options: {
+        unit_test: true,
+    },
+    static_libs: [
+        "libcvd_sub_commands",
+        "libgmock",
+    ],
+    defaults: ["cvd_and_fetch_cvd_defaults"],
+}
diff --git a/host/commands/cvd/server_command/start.cpp b/host/commands/cvd/server_command/start.cpp
index 84492b9..c9858b3 100644
--- a/host/commands/cvd/server_command/start.cpp
+++ b/host/commands/cvd/server_command/start.cpp
@@ -30,9 +30,9 @@
 #include <regex>
 #include <sstream>
 #include <string>
-#include <string_view>
 #include <thread>
 
+#include <android-base/parseint.h>
 #include <android-base/strings.h>
 
 #include "common/libs/fs/shared_fd.h"
@@ -149,7 +149,7 @@
    */
   Result<cvd::Response> PostStartExecutionActions(
       std::optional<selector::GroupCreationInfo>& group_creation_info,
-      const uid_t uid);
+      const uid_t uid, const bool is_daemonized);
   Result<void> AcloudCompatActions(
       const selector::GroupCreationInfo& group_creation_info,
       const RequestWithStdio& request);
@@ -489,7 +489,9 @@
   return start_bin;
 }
 
-static Result<void> ConsumeDaemonModeFlag(cvd_common::Args& args) {
+Result<bool> IsDaemonModeFlag(const cvd_common::Args& args) {
+  bool flag_set = false;
+  bool is_daemon = true;
   Flag flag =
       Flag()
           .Alias({FlagAliasMode::kFlagPrefix, "-daemon="})
@@ -498,26 +500,29 @@
           .Alias({FlagAliasMode::kFlagExact, "--daemon"})
           .Alias({FlagAliasMode::kFlagExact, "-nodaemon"})
           .Alias({FlagAliasMode::kFlagExact, "--nodaemon"})
-          .Setter([](const FlagMatch& match) -> Result<void> {
+          .Setter([&is_daemon,
+                   &flag_set](const FlagMatch& match) -> Result<void> {
+            flag_set = true;
             if (match.key == match.value) {
+              is_daemon = match.key.find("no") == std::string::npos;
               return {};
             }
-            std::vector<std::string> values =
-                android::base::Split(match.value, ",");
-            const std::vector<std::string_view> kFalseStrings{"n", "no",
-                                                              "false"};
-            const std::vector<std::string_view> kTrueStrings{"y", "yes",
-                                                             "true"};
-            for (const auto& value : values) {
-              CF_EXPECTF(Contains(kTrueStrings, value) ||
-                             Contains(kFalseStrings, value),
-                         "{} is not a valid value for --daemon=", match.value);
+            CF_EXPECTF(match.value.find(",") == std::string::npos,
+                       "{} had a comma", match.value);
+            static constexpr std::string_view kFalseStrings[] = {"n", "no",
+                                                                 "false"};
+            for (const auto& falseString : kFalseStrings) {
+              if (android::base::EqualsIgnoreCase(falseString, match.value)) {
+                is_daemon = false;
+              }
             }
+            // Allow `cvd_internal_start` to produce its own error for other
+            // invalid strings.
             return {};
           });
-  CF_EXPECT(ParseFlags({flag}, args));
-  args.push_back("--daemon=true");
-  return {};
+  auto args_copy = args;
+  CF_EXPECT(ParseFlags({flag}, args_copy));
+  return flag_set && is_daemon;
 }
 
 // For backward compatibility, we add extra symlink in system wide home
@@ -652,7 +657,7 @@
   CF_EXPECT(Contains(supported_commands_, subcmd),
             "subcmd should be start but is " << subcmd);
   const bool is_help = HasHelpOpts(subcmd_args);
-  CF_EXPECT(ConsumeDaemonModeFlag(subcmd_args));
+  const bool is_daemon = CF_EXPECT(IsDaemonModeFlag(subcmd_args));
 
   std::optional<selector::GroupCreationInfo> group_creation_info;
   if (!is_help) {
@@ -706,12 +711,12 @@
     LOG(ERROR) << "AcloudCompatActions() failed"
                << " but continue as they are minor errors.";
   }
-  return PostStartExecutionActions(group_creation_info, uid);
+  return PostStartExecutionActions(group_creation_info, uid, is_daemon);
 }
 
 Result<cvd::Response> CvdStartCommandHandler::PostStartExecutionActions(
     std::optional<selector::GroupCreationInfo>& group_creation_info,
-    const uid_t uid) {
+    const uid_t uid, const bool is_daemonized) {
   auto infop = CF_EXPECT(subprocess_waiter_.Wait());
   if (infop.si_code != CLD_EXITED || infop.si_status != EXIT_SUCCESS) {
     // perhaps failed in launch
@@ -722,10 +727,14 @@
       final_response.status().code() != cvd::Status::OK) {
     return final_response;
   }
-
-  MarkLockfilesInUse(*group_creation_info);
-  LOG(INFO) << "The Cuttlefish devices are now always daemonized";
-
+  if (is_daemonized) {
+    // If not daemonized, reaching here means the instance group terminated.
+    // Thus, it's enough to release the file lock in the destructor.
+    // If daemonized, reaching here means the group started successfully
+    // As the destructor will release the file lock, the instance lock
+    // files must be marked as used
+    MarkLockfilesInUse(*group_creation_info);
+  }
   // group_creation_info is nullopt only if is_help is false
   return FillOutNewInstanceInfo(std::move(final_response),
                                 *group_creation_info);
diff --git a/host/commands/cvd/server_command/start_test.cpp b/host/commands/cvd/server_command/start_test.cpp
new file mode 100644
index 0000000..6b32f52
--- /dev/null
+++ b/host/commands/cvd/server_command/start_test.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+//
+
+#include "host/commands/cvd/server_command/start.h"
+
+#include <gmock/gmock-matchers.h>
+#include <gtest/gtest.h>
+
+#include "common/libs/utils/result_matchers.h"
+
+namespace cuttlefish {
+
+TEST(CvdStart, DaemonFlag) {
+  ASSERT_THAT(IsDaemonModeFlag({}), IsOkAndValue(false));
+  ASSERT_THAT(IsDaemonModeFlag({"--daemon"}), IsOkAndValue(true));
+  ASSERT_THAT(IsDaemonModeFlag({"--nodaemon"}), IsOkAndValue(false));
+  ASSERT_THAT(IsDaemonModeFlag({"--daemon=y"}), IsOkAndValue(true));
+  ASSERT_THAT(IsDaemonModeFlag({"--daemon=TRUE"}), IsOkAndValue(true));
+  ASSERT_THAT(IsDaemonModeFlag({"--daemon=true"}), IsOkAndValue(true));
+  ASSERT_THAT(IsDaemonModeFlag({"--daemon=false"}), IsOkAndValue(false));
+  ASSERT_THAT(IsDaemonModeFlag({"--daemon=FALSE"}), IsOkAndValue(false));
+  ASSERT_THAT(IsDaemonModeFlag({"--daemon=no"}), IsOkAndValue(false));
+
+  ASSERT_THAT(IsDaemonModeFlag({"--daemon=true,false"}), IsError());
+  ASSERT_THAT(IsDaemonModeFlag({"--daemon=hello"}), IsOkAndValue(true));
+}
+
+}  // namespace cuttlefish