// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/mac/launch_application.h"

#include <sys/select.h>

#include "base/apple/bridging.h"
#include "base/apple/foundation_util.h"
#include "base/base_paths.h"
#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/mac/mac_util.h"
#include "base/path_service.h"
#include "base/process/launch.h"
#include "base/strings/string_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/task/bind_post_task.h"
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "base/threading/platform_thread.h"
#include "base/types/expected.h"
#include "base/uuid.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "testing/gtest_mac.h"

namespace base::mac {
namespace {

// Reads XML encoded property lists from `fifo_path`, calling `callback` for
// each succesfully parsed dictionary. Loops indefinitely until the string
// "<!FINISHED>" is read from `fifo_path`.
void ReadLaunchEventsFromFifo(
    const FilePath& fifo_path,
    RepeatingCallback<void(NSDictionary* event)> callback) {
  File f(fifo_path, File::FLAG_OPEN | File::FLAG_READ);
  std::string data;
  while (true) {
    char buf[4096];
    std::optional<size_t> read_count =
        f.ReadAtCurrentPosNoBestEffort(base::as_writable_byte_span(buf));
    ASSERT_TRUE(read_count.has_value());
    if (read_count.value()) {
      data += std::string_view(buf, read_count.value());
      // Assume that at any point the beginning of the data buffer is the start
      // of a plist. Search for the first end, and parse that substring.
      size_t end_of_plist;
      while ((end_of_plist = data.find("</plist>")) != std::string::npos) {
        std::string plist = data.substr(0, end_of_plist + 8);
        data = data.substr(plist.length());
        NSDictionary* event = apple::ObjCCastStrict<NSDictionary>(
            SysUTF8ToNSString(TrimWhitespaceASCII(plist, TRIM_ALL))
                .propertyList);
        callback.Run(event);
      }
      // No more plists found, check if the termination marker was send.
      if (data.find("<!FINISHED>") != std::string::npos) {
        break;
      }
    } else {
      // No data was read, wait for the file descriptor to become readable
      // again.
      fd_set fds;
      UNSAFE_TODO(FD_ZERO(&fds));
      FD_SET(f.GetPlatformFile(), &fds);
      select(FD_SETSIZE, &fds, nullptr, nullptr, nullptr);
    }
  }
}

// This test harness creates an app bundle with a random bundle identifier to
// avoid conflicts with concurrently running other tests. The binary in this app
// bundle writes various events to a named pipe, allowing tests here to verify
// that correct events were received by the app.
class LaunchApplicationTest : public testing::Test {
 public:
  void SetUp() override {
    helper_bundle_id_ =
        SysUTF8ToNSString("org.chromium.LaunchApplicationTestHelper." +
                          Uuid::GenerateRandomV4().AsLowercaseString());

    FilePath data_root;
    ASSERT_TRUE(PathService::Get(DIR_OUT_TEST_DATA_ROOT, &data_root));
    const FilePath helper_app_executable =
        data_root.AppendASCII("launch_application_test_helper");

    // Put helper app inside home dir, as the default temp location gets special
    // treatment by launch services, effecting the behavior of some of these
    // tests.
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDirUnderPath(base::GetHomeDir()));

    helper_app_bundle_path_ =
        temp_dir_.GetPath().AppendASCII("launch_application_test_helper.app");

    const base::FilePath destination_contents_path =
        helper_app_bundle_path_.AppendASCII("Contents");
    const base::FilePath destination_executable_path =
        destination_contents_path.AppendASCII("MacOS");

    // First create the .app bundle directory structure.
    // Use NSFileManager so that the permissions can be set appropriately. The
    // base::CreateDirectory() routine forces mode 0700.
    NSError* error = nil;
    ASSERT_TRUE([NSFileManager.defaultManager
               createDirectoryAtURL:base::apple::FilePathToNSURL(
                                        destination_executable_path)
        withIntermediateDirectories:YES
                         attributes:@{
                           NSFilePosixPermissions : @(0755)
                         }
                              error:&error])
        << SysNSStringToUTF8(error.description);

    // Copy the executable file.
    helper_app_executable_path_ =
        destination_executable_path.Append(helper_app_executable.BaseName());
    ASSERT_TRUE(
        base::CopyFile(helper_app_executable, helper_app_executable_path_));

    // Write the PkgInfo file.
    constexpr char kPkgInfoData[] = "APPL????";
    ASSERT_TRUE(base::WriteFile(
        destination_contents_path.AppendASCII("PkgInfo"), kPkgInfoData));

#if defined(ADDRESS_SANITIZER)
    const base::FilePath asan_library_path =
        data_root.AppendASCII("libclang_rt.asan_osx_dynamic.dylib");
    ASSERT_TRUE(base::CopyFile(
        asan_library_path,
        destination_executable_path.Append(asan_library_path.BaseName())));
#endif

#if defined(UNDEFINED_SANITIZER)
    const base::FilePath ubsan_library_path =
        data_root.AppendASCII("libclang_rt.ubsan_osx_dynamic.dylib");
    ASSERT_TRUE(base::CopyFile(
        ubsan_library_path,
        destination_executable_path.Append(ubsan_library_path.BaseName())));
#endif

    // Generate the Plist file
    NSDictionary* plist = @{
      @"CFBundleExecutable" :
          apple::FilePathToNSString(helper_app_executable.BaseName()),
      @"CFBundleIdentifier" : helper_bundle_id_,
    };
    ASSERT_TRUE([plist
        writeToURL:apple::FilePathToNSURL(
                       destination_contents_path.AppendASCII("Info.plist"))
             error:nil]);

    // Register the app with LaunchServices.
    LSRegisterURL(base::apple::FilePathToCFURL(helper_app_bundle_path_).get(),
                  true);

    // Ensure app was registered with LaunchServices. Sometimes it takes a
    // little bit of time for this to happen, and some tests might fail if the
    // app wasn't registered yet.
    while (true) {
      NSArray<NSURL*>* apps = nil;
      if (@available(macOS 12.0, *)) {
        apps = [[NSWorkspace sharedWorkspace]
            URLsForApplicationsWithBundleIdentifier:helper_bundle_id_];
      } else {
        apps =
            apple::CFToNSOwnershipCast(LSCopyApplicationURLsForBundleIdentifier(
                apple::NSToCFPtrCast(helper_bundle_id_), /*outError=*/nullptr));
      }
      if (apps.count > 0) {
        break;
      }
      PlatformThread::Sleep(Milliseconds(50));
    }

    // Setup fifo to receive logs from the helper app.
    helper_app_fifo_path_ =
        temp_dir_.GetPath().AppendASCII("launch_application_test_helper.fifo");
    ASSERT_EQ(0, mkfifo(helper_app_fifo_path_.value().c_str(),
                        S_IWUSR | S_IRUSR | S_IWGRP | S_IWGRP));

    // Create array to store received events in, and start listening for events.
    launch_events_ = [[NSMutableArray alloc] init];
    base::ThreadPool::PostTask(
        FROM_HERE, {MayBlock()},
        base::BindOnce(
            &ReadLaunchEventsFromFifo, helper_app_fifo_path_,
            BindPostTaskToCurrentDefault(BindRepeating(
                &LaunchApplicationTest::OnLaunchEvent, Unretained(this)))));
  }

  void TearDown() override {
    if (temp_dir_.IsValid()) {
      // Make sure fifo reading task stops reading/waiting.
      WriteFile(helper_app_fifo_path_, "<!FINISHED>");

      // Make sure all apps that were launched by this test are terminated.
      NSArray<NSRunningApplication*>* apps =
          NSWorkspace.sharedWorkspace.runningApplications;
      for (NSRunningApplication* app in apps) {
        if (temp_dir_.GetPath().IsParent(
                apple::NSURLToFilePath(app.bundleURL)) ||
            [app.bundleIdentifier isEqualToString:helper_bundle_id_]) {
          [app forceTerminate];
        }
      }

      // And make sure the temp dir was successfully deleted.
      EXPECT_TRUE(temp_dir_.Delete());
    }
  }

  // Calls `LaunchApplication` with the given parameters, expecting the launch
  // to succeed. Returns the `NSRunningApplication*` the callback passed to
  // `LaunchApplication` was called with.
  NSRunningApplication* LaunchApplicationSyncExpectSuccess(
      const FilePath& app_bundle_path,
      const CommandLineArgs& command_line_args,
      const std::vector<std::string>& url_specs,
      LaunchApplicationOptions options) {
    test::TestFuture<NSRunningApplication*, NSError*> result;
    LaunchApplication(app_bundle_path, command_line_args, url_specs, options,
                      result.GetCallback());
    EXPECT_FALSE(result.Get<1>());
    EXPECT_TRUE(result.Get<0>());
    return result.Get<0>();
  }

  // Similar to the above method, except that this version expects the launch to
  // fail, returning the error.
  NSError* LaunchApplicationSyncExpectError(
      const FilePath& app_bundle_path,
      const CommandLineArgs& command_line_args,
      const std::vector<std::string>& url_specs,
      LaunchApplicationOptions options) {
    test::TestFuture<NSRunningApplication*, NSError*> result;
    LaunchApplication(app_bundle_path, command_line_args, url_specs, options,
                      result.GetCallback());
    EXPECT_FALSE(result.Get<0>());
    EXPECT_TRUE(result.Get<1>());
    return result.Get<1>();
  }

  // Waits for the total number of received launch events to reach at least
  // `expected_count`.
  void WaitForLaunchEvents(unsigned expected_count) {
    if (LaunchEventCount() >= expected_count) {
      return;
    }
    base::RunLoop loop;
    launch_event_callback_ = BindLambdaForTesting([&] {
      if (LaunchEventCount() >= expected_count) {
        launch_event_callback_ = NullCallback();
        loop.Quit();
      }
    });
    loop.Run();
  }

  unsigned LaunchEventCount() { return launch_events_.count; }
  NSString* LaunchEventName(unsigned i) {
    if (i >= launch_events_.count) {
      return nil;
    }
    return apple::ObjCCastStrict<NSString>(launch_events_[i][@"name"]);
  }
  NSDictionary* LaunchEventData(unsigned i) {
    if (i >= launch_events_.count) {
      return nil;
    }
    return apple::ObjCCastStrict<NSDictionary>(launch_events_[i][@"data"]);
  }

 protected:
  ScopedTempDir temp_dir_;

  NSString* helper_bundle_id_;
  FilePath helper_app_bundle_path_;
  FilePath helper_app_executable_path_;
  FilePath helper_app_fifo_path_;

  NSMutableArray<NSDictionary*>* launch_events_;
  RepeatingClosure launch_event_callback_;

  test::TaskEnvironment task_environment_{
      test::TaskEnvironment::MainThreadType::UI};

 private:
  void OnLaunchEvent(NSDictionary* event) {
    NSLog(@"Event: %@", event);
    [launch_events_ addObject:event];
    if (launch_event_callback_) {
      launch_event_callback_.Run();
    }
  }
};

TEST_F(LaunchApplicationTest, Basic) {
  std::vector<std::string> command_line_args;
  NSRunningApplication* app = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {}, {});
  ASSERT_TRUE(app);
  EXPECT_NSEQ(app.bundleIdentifier, helper_bundle_id_);
  EXPECT_EQ(apple::NSURLToFilePath(app.bundleURL), helper_app_bundle_path_);

  WaitForLaunchEvents(1);
  EXPECT_NSEQ(LaunchEventName(0), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(0)[@"activationPolicy"],
              @(NSApplicationActivationPolicyRegular));
  EXPECT_EQ(app.activationPolicy, NSApplicationActivationPolicyRegular);
  EXPECT_NSEQ(LaunchEventData(0)[@"commandLine"],
              (@[ apple::FilePathToNSString(helper_app_executable_path_) ]));
  EXPECT_NSEQ(LaunchEventData(0)[@"processIdentifier"],
              @(app.processIdentifier));
}

TEST_F(LaunchApplicationTest, BundleDoesntExist) {
  std::vector<std::string> command_line_args;
  NSError* err = LaunchApplicationSyncExpectError(
      temp_dir_.GetPath().AppendASCII("notexists.app"), command_line_args, {},
      {});
  ASSERT_TRUE(err);
  err = LaunchApplicationSyncExpectError(
      temp_dir_.GetPath().AppendASCII("notexists.app"), command_line_args, {},
      {.hidden_in_background = true});
  ASSERT_TRUE(err);
}

TEST_F(LaunchApplicationTest, BundleCorrupt) {
  base::DeleteFile(helper_app_executable_path_);
  std::vector<std::string> command_line_args;
  NSError* err = LaunchApplicationSyncExpectError(helper_app_bundle_path_,
                                                  command_line_args, {}, {});
  ASSERT_TRUE(err);
  err = LaunchApplicationSyncExpectError(helper_app_bundle_path_,
                                         command_line_args, {},
                                         {.hidden_in_background = true});
  ASSERT_TRUE(err);
}

TEST_F(LaunchApplicationTest, CommandLineArgs_StringVector) {
  std::vector<std::string> command_line_args = {"--foo", "bar", "-v"};
  NSRunningApplication* app = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {}, {});
  ASSERT_TRUE(app);

  WaitForLaunchEvents(1);
  EXPECT_NSEQ(LaunchEventName(0), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(0)[@"commandLine"], (@[
                apple::FilePathToNSString(helper_app_executable_path_),
                @"--foo", @"bar", @"-v"
              ]));
}

TEST_F(LaunchApplicationTest, CommandLineArgs_BaseCommandLine) {
  CommandLine command_line(CommandLine::NO_PROGRAM);
  command_line.AppendSwitchASCII("foo", "bar");
  command_line.AppendSwitch("v");
  command_line.AppendSwitchPath("path", FilePath("/tmp"));

  NSRunningApplication* app = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line, {}, {});
  ASSERT_TRUE(app);

  WaitForLaunchEvents(1);
  EXPECT_NSEQ(LaunchEventName(0), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(0)[@"commandLine"], (@[
                apple::FilePathToNSString(helper_app_executable_path_),
                @"--foo=bar", @"--v", @"--path=/tmp"
              ]));
}

TEST_F(LaunchApplicationTest, UrlSpecs) {
  std::vector<std::string> command_line_args;
  std::vector<std::string> urls = {"https://example.com",
                                   "x-chrome-launch://1"};
  NSRunningApplication* app = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, urls, {});
  ASSERT_TRUE(app);
  WaitForLaunchEvents(3);

  EXPECT_NSEQ(LaunchEventName(0), @"openURLs");
  EXPECT_NSEQ(LaunchEventName(1), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventName(2), @"openURLs");

  if (MacOSMajorVersion() == 11) {
    // macOS 11 (and only macOS 11) appears to sometimes trigger the openURLs
    // calls in reverse order.
    std::vector<std::string> received_urls;
    for (NSString* url in apple::ObjCCastStrict<NSArray>(
             LaunchEventData(0)[@"urls"])) {
      received_urls.push_back(SysNSStringToUTF8(url));
    }
    EXPECT_EQ(received_urls.size(), 1u);
    for (NSString* url in apple::ObjCCastStrict<NSArray>(
             LaunchEventData(2)[@"urls"])) {
      received_urls.push_back(SysNSStringToUTF8(url));
    }
    EXPECT_THAT(received_urls, testing::UnorderedElementsAreArray(urls));
  } else {
    EXPECT_NSEQ(LaunchEventData(0)[@"urls"], @[ @"https://example.com" ]);
    EXPECT_NSEQ(LaunchEventData(2)[@"urls"], @[ @"x-chrome-launch://1" ]);
  }
}

TEST_F(LaunchApplicationTest, CreateNewInstance) {
  std::vector<std::string> command_line_args;
  NSRunningApplication* app1 = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {},
      {.create_new_instance = false});
  WaitForLaunchEvents(1);
  EXPECT_NSEQ(LaunchEventName(0), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(0)[@"processIdentifier"],
              @(app1.processIdentifier));

  NSRunningApplication* app2 = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {"x-chrome-launch://0"},
      {.create_new_instance = false});
  EXPECT_NSEQ(app1, app2);
  EXPECT_EQ(app1.processIdentifier, app2.processIdentifier);
  WaitForLaunchEvents(2);
  EXPECT_NSEQ(LaunchEventName(1), @"openURLs");
  EXPECT_NSEQ(LaunchEventData(1)[@"processIdentifier"],
              @(app2.processIdentifier));

  NSRunningApplication* app3 = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {"x-chrome-launch://1"},
      {.create_new_instance = true});
  EXPECT_NSNE(app1, app3);
  EXPECT_NE(app1.processIdentifier, app3.processIdentifier);
  WaitForLaunchEvents(4);
  EXPECT_NSEQ(LaunchEventName(2), @"openURLs");
  EXPECT_NSEQ(LaunchEventName(3), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(3)[@"processIdentifier"],
              @(app3.processIdentifier));
}

TEST_F(LaunchApplicationTest, HiddenInBackground) {
  std::vector<std::string> command_line_args = {"--test", "--foo"};
  NSRunningApplication* app = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {},
      {.hidden_in_background = true});
  ASSERT_TRUE(app);
  EXPECT_NSEQ(app.bundleIdentifier, helper_bundle_id_);
  EXPECT_EQ(helper_app_bundle_path_, apple::NSURLToFilePath(app.bundleURL));

  WaitForLaunchEvents(1);
  EXPECT_NSEQ(LaunchEventName(0), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(0)[@"activationPolicy"],
              @(NSApplicationActivationPolicyProhibited));
  EXPECT_EQ(app.activationPolicy, NSApplicationActivationPolicyProhibited);
  EXPECT_NSEQ(LaunchEventData(0)[@"commandLine"], (@[
                apple::FilePathToNSString(helper_app_executable_path_),
                @"--test", @"--foo"
              ]));
  EXPECT_NSEQ(LaunchEventData(0)[@"processIdentifier"],
              @(app.processIdentifier));

  NSRunningApplication* app2 = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {},
      {.create_new_instance = false, .hidden_in_background = true});
  EXPECT_NSEQ(app, app2);
  EXPECT_EQ(app.processIdentifier, app2.processIdentifier);
  EXPECT_EQ(app.activationPolicy, NSApplicationActivationPolicyProhibited);
  EXPECT_EQ(app2.activationPolicy, NSApplicationActivationPolicyProhibited);
  // Launching without opening anything should not trigger any launch events.

  // Opening a URL in a new instance, should leave both instances in the
  // background.
  NSRunningApplication* app3 = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {"x-chrome-launch://2"},
      {.create_new_instance = true, .hidden_in_background = true});
  EXPECT_NSNE(app, app3);
  EXPECT_NE(app.processIdentifier, app3.processIdentifier);
  WaitForLaunchEvents(3);
  EXPECT_NSEQ(LaunchEventName(1), @"openURLs");
  EXPECT_NSEQ(LaunchEventName(2), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(2)[@"processIdentifier"],
              @(app3.processIdentifier));
  EXPECT_EQ(app.activationPolicy, NSApplicationActivationPolicyProhibited);
  EXPECT_EQ(app2.activationPolicy, NSApplicationActivationPolicyProhibited);
  EXPECT_EQ(app3.activationPolicy, NSApplicationActivationPolicyProhibited);
}

TEST_F(LaunchApplicationTest,
       HiddenInBackground_OpenUrlChangesActivationPolicy) {
  std::vector<std::string> command_line_args = {"--test", "--foo"};
  NSRunningApplication* app = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {},
      {.hidden_in_background = true});
  ASSERT_TRUE(app);
  EXPECT_NSEQ(app.bundleIdentifier, helper_bundle_id_);
  EXPECT_EQ(helper_app_bundle_path_, apple::NSURLToFilePath(app.bundleURL));

  WaitForLaunchEvents(1);
  EXPECT_NSEQ(LaunchEventName(0), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(0)[@"activationPolicy"],
              @(NSApplicationActivationPolicyProhibited));
  EXPECT_EQ(app.activationPolicy, NSApplicationActivationPolicyProhibited);
  EXPECT_NSEQ(LaunchEventData(0)[@"commandLine"], (@[
                apple::FilePathToNSString(helper_app_executable_path_),
                @"--test", @"--foo"
              ]));
  EXPECT_NSEQ(LaunchEventData(0)[@"processIdentifier"],
              @(app.processIdentifier));

  NSRunningApplication* app2 = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {"chrome://app-launch/0"},
      {.create_new_instance = false, .hidden_in_background = true});
  EXPECT_NSEQ(app, app2);
  EXPECT_EQ(app.processIdentifier, app2.processIdentifier);
  // Unexpected to me, but opening a URL seems to always change the activation
  // policy.
  EXPECT_EQ(app.activationPolicy, NSApplicationActivationPolicyRegular);
  EXPECT_EQ(app2.activationPolicy, NSApplicationActivationPolicyRegular);
  WaitForLaunchEvents(3);
  EXPECT_THAT(
      std::vector<std::string>({SysNSStringToUTF8(LaunchEventName(1)),
                                SysNSStringToUTF8(LaunchEventName(2))}),
      testing::UnorderedElementsAre("activationPolicyChanged", "openURLs"));
}

TEST_F(LaunchApplicationTest, HiddenInBackground_TransitionToForeground) {
  std::vector<std::string> command_line_args;
  NSRunningApplication* app = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {"x-chrome-launch://1"},
      {.hidden_in_background = true});
  ASSERT_TRUE(app);

  WaitForLaunchEvents(2);
  EXPECT_NSEQ(LaunchEventName(0), @"openURLs");
  EXPECT_NSEQ(LaunchEventName(1), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(1)[@"activationPolicy"],
              @(NSApplicationActivationPolicyProhibited));
  EXPECT_EQ(app.activationPolicy, NSApplicationActivationPolicyProhibited);
  EXPECT_NSEQ(LaunchEventData(1)[@"processIdentifier"],
              @(app.processIdentifier));

  // Second launch with hidden_in_background set to false should cause the first
  // app to switch activation policy.
  NSRunningApplication* app2 = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {},
      {.hidden_in_background = false});
  EXPECT_NSEQ(app, app2);
  WaitForLaunchEvents(3);
  EXPECT_NSEQ(LaunchEventName(2), @"activationPolicyChanged");
  EXPECT_NSEQ(LaunchEventData(2)[@"activationPolicy"],
              @(NSApplicationActivationPolicyRegular));
  EXPECT_EQ(app2.activationPolicy, NSApplicationActivationPolicyRegular);
}

TEST_F(LaunchApplicationTest, HiddenInBackground_AlreadyInForeground) {
  std::vector<std::string> command_line_args;
  NSRunningApplication* app = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {"x-chrome-launch://1"},
      {.hidden_in_background = false});
  ASSERT_TRUE(app);

  WaitForLaunchEvents(2);
  EXPECT_NSEQ(LaunchEventName(0), @"openURLs");
  EXPECT_NSEQ(LaunchEventName(1), @"applicationDidFinishLaunching");
  EXPECT_NSEQ(LaunchEventData(1)[@"activationPolicy"],
              @(NSApplicationActivationPolicyRegular));
  EXPECT_EQ(app.activationPolicy, NSApplicationActivationPolicyRegular);
  EXPECT_NSEQ(LaunchEventData(1)[@"processIdentifier"],
              @(app.processIdentifier));

  // Second (and third) launch with hidden_in_background set to true should
  // reuse the existing app and keep it visible.
  NSRunningApplication* app2 = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {},
      {.hidden_in_background = true});
  EXPECT_NSEQ(app, app2);
  EXPECT_EQ(app2.activationPolicy, NSApplicationActivationPolicyRegular);
  NSRunningApplication* app3 = LaunchApplicationSyncExpectSuccess(
      helper_app_bundle_path_, command_line_args, {"x-chrome-launch://23"},
      {.hidden_in_background = true});
  EXPECT_NSEQ(app, app3);
  WaitForLaunchEvents(3);
  EXPECT_NSEQ(LaunchEventName(2), @"openURLs");
  EXPECT_NSEQ(LaunchEventData(2)[@"processIdentifier"],
              @(app.processIdentifier));
  EXPECT_EQ(app3.activationPolicy, NSApplicationActivationPolicyRegular);
}

}  // namespace
}  // namespace base::mac
