summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/base.gypi2
-rw-r--r--base/mac/launch_services_util.cc67
-rw-r--r--base/mac/launch_services_util.h29
-rw-r--r--chrome/app/chrome_main_app_mode_mac.mm35
4 files changed, 108 insertions, 25 deletions
diff --git a/base/base.gypi b/base/base.gypi
index c8c5c37..de000d1 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -224,6 +224,8 @@
'mac/cocoa_protocols.h',
'mac/foundation_util.h',
'mac/foundation_util.mm',
+ 'mac/launch_services_util.cc',
+ 'mac/launch_services_util.h',
'mac/launchd.cc',
'mac/launchd.h',
'mac/libdispatch_task_runner.cc',
diff --git a/base/mac/launch_services_util.cc b/base/mac/launch_services_util.cc
new file mode 100644
index 0000000..c24d864
--- /dev/null
+++ b/base/mac/launch_services_util.cc
@@ -0,0 +1,67 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/mac/launch_services_util.h"
+
+#include <ApplicationServices/ApplicationServices.h>
+
+#include "base/logging.h"
+#include "base/mac/mac_logging.h"
+#include "base/mac/mac_util.h"
+#include "base/strings/sys_string_conversions.h"
+
+namespace base {
+namespace mac {
+
+bool OpenApplicationWithPath(const base::FilePath& bundle_path,
+ const CommandLine& command_line,
+ ProcessSerialNumber* out_psn) {
+ FSRef app_fsref;
+ if (!base::mac::FSRefFromPath(bundle_path.value(), &app_fsref)) {
+ LOG(ERROR) << "base::mac::FSRefFromPath failed for " << bundle_path.value();
+ return false;
+ }
+
+ std::vector<std::string> argv = command_line.argv();
+ int argc = argv.size();
+ base::mac::ScopedCFTypeRef<CFMutableArrayRef> launch_args(
+ CFArrayCreateMutable(NULL, argc - 1, &kCFTypeArrayCallBacks));
+ if (!launch_args) {
+ LOG(ERROR) << "CFArrayCreateMutable failed, size was " << argc;
+ return false;
+ }
+
+ for (int i = 1; i < argc; ++i) {
+ const std::string& arg(argv[i]);
+
+ base::mac::ScopedCFTypeRef<CFStringRef> arg_cf(
+ base::SysUTF8ToCFStringRef(arg));
+ if (!arg_cf) {
+ LOG(ERROR) << "base::SysUTF8ToCFStringRef failed for " << arg;
+ return false;
+ }
+ CFArrayAppendValue(launch_args, arg_cf);
+ }
+
+ LSApplicationParameters ls_parameters = {
+ 0, // version
+ kLSLaunchDefaults,
+ &app_fsref,
+ NULL, // asyncLaunchRefCon
+ NULL, // environment
+ launch_args,
+ NULL // initialEvent
+ };
+ // TODO(jeremya): this opens a new browser window if Chrome is already
+ // running without any windows open.
+ OSStatus status = LSOpenApplication(&ls_parameters, out_psn);
+ if (status != noErr) {
+ OSSTATUS_LOG(ERROR, status) << "LSOpenApplication";
+ return false;
+ }
+ return true;
+}
+
+} // namespace mac
+} // namespace base
diff --git a/base/mac/launch_services_util.h b/base/mac/launch_services_util.h
new file mode 100644
index 0000000..cd17950
--- /dev/null
+++ b/base/mac/launch_services_util.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_MAC_LAUNCH_SERVICES_UTIL_H_
+#define BASE_MAC_LAUNCH_SERVICES_UTIL_H_
+
+#include "base/base_export.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+
+struct ProcessSerialNumber;
+
+namespace base {
+namespace mac {
+
+// Launches the application bundle at |bundle_path|, passing argv[1..] from
+// |command_line| as command line arguments if the app isn't already running.
+// |out_psn|, if not NULL, will be set to the process serial number of the
+// application's main process if the app was successfully launched.
+// Returns true if the app was successfully launched.
+BASE_EXPORT bool OpenApplicationWithPath(const base::FilePath& bundle_path,
+ const CommandLine& command_line,
+ ProcessSerialNumber* out_psn);
+
+} // namespace mac
+} // namespace base
+
+#endif // BASE_MAC_LAUNCH_SERVICES_UTIL_H_
diff --git a/chrome/app/chrome_main_app_mode_mac.mm b/chrome/app/chrome_main_app_mode_mac.mm
index b028c39..ee7793c 100644
--- a/chrome/app/chrome_main_app_mode_mac.mm
+++ b/chrome/app/chrome_main_app_mode_mac.mm
@@ -11,7 +11,9 @@
#include "apps/app_shim/app_shim_messages.h"
#include "base/at_exit.h"
+#include "base/command_line.h"
#include "base/logging.h"
+#include "base/mac/launch_services_util.h"
#include "base/mac/mac_logging.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_nsautorelease_pool.h"
@@ -280,34 +282,17 @@ int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info) {
g_io_thread = io_thread;
// Launch Chrome if it isn't already running.
- FSRef app_fsref;
- if (!base::mac::FSRefFromPath(info->chrome_outer_bundle_path.value(),
- &app_fsref)) {
- LOG(ERROR) << "base::mac::FSRefFromPath failed for "
- << info->chrome_outer_bundle_path.value();
- return 1;
- }
- std::string silent = std::string("--") + switches::kSilentLaunch;
- CFArrayRef launch_args =
- base::mac::NSToCFCast(@[base::SysUTF8ToNSString(silent)]);
-
- LSApplicationParameters ls_parameters = {
- 0, // version
- kLSLaunchDefaults,
- &app_fsref,
- NULL, // asyncLaunchRefCon
- NULL, // environment
- launch_args,
- NULL // initialEvent
- };
- ProcessSerialNumber psn;
// TODO(jeremya): this opens a new browser window if Chrome is already
// running without any windows open.
- OSStatus status = LSOpenApplication(&ls_parameters, &psn);
- if (status != noErr) {
- OSSTATUS_LOG(ERROR, status) << "LSOpenApplication";
+ CommandLine command_line(CommandLine::NO_PROGRAM);
+ command_line.AppendSwitch(switches::kSilentLaunch);
+ ProcessSerialNumber psn;
+ bool success =
+ base::mac::OpenApplicationWithPath(info->chrome_outer_bundle_path,
+ command_line,
+ &psn);
+ if (!success)
return 1;
- }
// This code abuses the fact that Apple Events sent before the process is
// fully initialized don't receive a reply until its run loop starts. Once