diff options
-rw-r--r-- | base/base.gypi | 2 | ||||
-rw-r--r-- | base/mac/launch_services_util.cc | 67 | ||||
-rw-r--r-- | base/mac/launch_services_util.h | 29 | ||||
-rw-r--r-- | chrome/app/chrome_main_app_mode_mac.mm | 35 |
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 |