Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // On Mac, shortcuts can't have command-line arguments. Instead, produce small | 5 // On Mac, shortcuts can't have command-line arguments. Instead, produce small |
| 6 // app bundles which locate the Chromium framework and load it, passing the | 6 // app bundles which locate the Chromium framework and load it, passing the |
| 7 // appropriate data. This is the code for such an app bundle. It should be kept | 7 // appropriate data. This is the code for such an app bundle. It should be kept |
| 8 // minimal and do as little work as possible (with as much work done on | 8 // minimal and do as little work as possible (with as much work done on |
| 9 // framework side as possible). | 9 // framework side as possible). |
| 10 | 10 |
| 11 #include <dlfcn.h> | 11 #include <dlfcn.h> |
| 12 | 12 |
| 13 #include <CoreFoundation/CoreFoundation.h> | 13 #include <CoreFoundation/CoreFoundation.h> |
| 14 #import <Foundation/Foundation.h> | 14 #import <Foundation/Foundation.h> |
| 15 | 15 |
| 16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 17 #include "base/file_util.h" | 17 #include "base/file_util.h" |
| 18 #include "base/files/file_path.h" | 18 #include "base/files/file_path.h" |
| 19 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "base/mac/foundation_util.h" | 20 #include "base/mac/foundation_util.h" |
| 21 #include "base/mac/launch_services_util.h" | 21 #include "base/mac/launch_services_util.h" |
| 22 #include "base/mac/scoped_nsautorelease_pool.h" | 22 #include "base/mac/scoped_nsautorelease_pool.h" |
| 23 #include "base/process/launch.h" | |
| 23 #include "base/strings/sys_string_conversions.h" | 24 #include "base/strings/sys_string_conversions.h" |
| 25 #include "chrome/common/chrome_switches.h" | |
| 24 #import "chrome/common/mac/app_mode_chrome_locator.h" | 26 #import "chrome/common/mac/app_mode_chrome_locator.h" |
| 25 #include "chrome/common/mac/app_mode_common.h" | 27 #include "chrome/common/mac/app_mode_common.h" |
| 26 | 28 |
| 27 namespace { | 29 namespace { |
| 28 | 30 |
| 29 typedef int (*StartFun)(const app_mode::ChromeAppModeInfo*); | 31 typedef int (*StartFun)(const app_mode::ChromeAppModeInfo*); |
| 30 | 32 |
| 31 int LoadFrameworkAndStart(app_mode::ChromeAppModeInfo* info) { | 33 int LoadFrameworkAndStart(app_mode::ChromeAppModeInfo* info) { |
| 32 using base::SysNSStringToUTF8; | 34 using base::SysNSStringToUTF8; |
| 33 using base::SysNSStringToUTF16; | 35 using base::SysNSStringToUTF16; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 60 if (!found_bundle) { | 62 if (!found_bundle) { |
| 61 // If no such bundle path exists, try to search by bundle ID. | 63 // If no such bundle path exists, try to search by bundle ID. |
| 62 if (!app_mode::FindBundleById(cr_bundle_id, &cr_bundle_path)) { | 64 if (!app_mode::FindBundleById(cr_bundle_id, &cr_bundle_path)) { |
| 63 // TODO(jeremy): Display UI to allow user to manually locate the Chrome | 65 // TODO(jeremy): Display UI to allow user to manually locate the Chrome |
| 64 // bundle. | 66 // bundle. |
| 65 LOG(FATAL) << "Failed to locate bundle by identifier"; | 67 LOG(FATAL) << "Failed to locate bundle by identifier"; |
| 66 } | 68 } |
| 67 } | 69 } |
| 68 | 70 |
| 69 // ** 2: Read information from the Chrome bundle. | 71 // ** 2: Read information from the Chrome bundle. |
| 72 base::FilePath executable_path; | |
| 70 base::string16 raw_version_str; | 73 base::string16 raw_version_str; |
| 71 base::FilePath version_path; | 74 base::FilePath version_path; |
| 72 base::FilePath framework_shlib_path; | 75 base::FilePath framework_shlib_path; |
| 73 if (!app_mode::GetChromeBundleInfo(cr_bundle_path, &raw_version_str, | 76 if (!app_mode::GetChromeBundleInfo(cr_bundle_path, |
| 74 &version_path, &framework_shlib_path)) { | 77 &executable_path, |
| 78 &raw_version_str, | |
| 79 &version_path, | |
| 80 &framework_shlib_path)) { | |
| 75 LOG(FATAL) << "Couldn't ready Chrome bundle info"; | 81 LOG(FATAL) << "Couldn't ready Chrome bundle info"; |
| 76 } | 82 } |
| 77 base::FilePath app_mode_bundle_path = | 83 base::FilePath app_mode_bundle_path = |
| 78 base::mac::NSStringToFilePath([app_bundle bundlePath]); | 84 base::mac::NSStringToFilePath([app_bundle bundlePath]); |
| 79 | 85 |
| 80 // ** 3: Fill in ChromeAppModeInfo. | 86 // ** 3: Fill in ChromeAppModeInfo. |
| 81 info->chrome_outer_bundle_path = cr_bundle_path; | 87 info->chrome_outer_bundle_path = cr_bundle_path; |
| 82 info->chrome_versioned_path = version_path; | 88 info->chrome_versioned_path = version_path; |
| 83 info->app_mode_bundle_path = app_mode_bundle_path; | 89 info->app_mode_bundle_path = app_mode_bundle_path; |
| 84 | 90 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 108 void* cr_dylib = dlopen(framework_shlib_path.value().c_str(), RTLD_LAZY); | 114 void* cr_dylib = dlopen(framework_shlib_path.value().c_str(), RTLD_LAZY); |
| 109 if (cr_dylib) { | 115 if (cr_dylib) { |
| 110 // Find the entry point. | 116 // Find the entry point. |
| 111 ChromeAppModeStart = (StartFun)dlsym(cr_dylib, "ChromeAppModeStart"); | 117 ChromeAppModeStart = (StartFun)dlsym(cr_dylib, "ChromeAppModeStart"); |
| 112 if (!ChromeAppModeStart) | 118 if (!ChromeAppModeStart) |
| 113 LOG(ERROR) << "Couldn't get entry point: " << dlerror(); | 119 LOG(ERROR) << "Couldn't get entry point: " << dlerror(); |
| 114 } else { | 120 } else { |
| 115 LOG(ERROR) << "Couldn't load framework: " << dlerror(); | 121 LOG(ERROR) << "Couldn't load framework: " << dlerror(); |
| 116 } | 122 } |
| 117 | 123 |
| 118 if (ChromeAppModeStart) { | 124 if (ChromeAppModeStart) { |
|
tapted
2014/05/05 07:02:01
nit: doesn't need curlies
jackhou1
2014/05/06 04:47:58
Done.
| |
| 119 return ChromeAppModeStart(info); | 125 return ChromeAppModeStart(info); |
| 120 } else { | 126 } |
| 121 LOG(ERROR) << "Loading Chrome failed, launching with command line."; | 127 |
| 122 // Launch Chrome instead and have it update this app_mode_loader bundle. | 128 LOG(ERROR) << "Loading Chrome failed, launching Chrome with command line"; |
| 123 CommandLine command_line(CommandLine::NO_PROGRAM); | 129 CommandLine command_line(executable_path); |
| 130 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 131 app_mode::kLaunchedByChromeProcessId) || | |
| 132 info->app_mode_id == app_mode::kAppListModeId) { | |
| 133 // Pass --app-shim-error to have Chrome rebuild this shim. | |
| 124 command_line.AppendSwitchPath(app_mode::kAppShimError, | 134 command_line.AppendSwitchPath(app_mode::kAppShimError, |
| 125 app_mode_bundle_path); | 135 app_mode_bundle_path); |
| 126 if (!base::mac::OpenApplicationWithPath( | 136 } else { |
| 127 cr_bundle_path, command_line, kLSLaunchDefaults, NULL)) { | 137 // Just launch the app. |
|
tapted
2014/05/05 07:02:01
nit: maybe clarify why this branching exists and t
jackhou1
2014/05/06 04:47:58
Done.
| |
| 128 LOG(ERROR) << "Could not launch Chrome from: " << cr_bundle_path.value(); | 138 command_line.AppendSwitchPath(switches::kProfileDirectory, |
| 129 return 1; | 139 info->profile_dir); |
| 130 } | 140 command_line.AppendSwitchASCII(switches::kAppId, info->app_mode_id); |
| 141 } | |
| 142 if (!base::LaunchProcess(command_line, base::LaunchOptions(), NULL)) { | |
|
tapted
2014/05/05 07:02:01
why was this change needed? (i.e. changing from ba
jackhou1
2014/05/06 04:47:58
Updated the comment. LSOpenApplication doesn't pas
| |
| 143 LOG(ERROR) << "Could not launch Chrome: " | |
| 144 << command_line.GetCommandLineString(); | |
| 145 return 1; | |
| 146 } | |
| 131 | 147 |
| 132 return 0; | 148 return 0; |
|
tapted
2014/05/05 07:02:01
Maybe really unlikely.. but is there a potential r
jackhou1
2014/05/06 04:47:58
Yeah there is, but I don't think it's worth trying
| |
| 133 } | |
| 134 } | 149 } |
| 135 | 150 |
| 136 } // namespace | 151 } // namespace |
| 137 | 152 |
| 138 __attribute__((visibility("default"))) | 153 __attribute__((visibility("default"))) |
| 139 int main(int argc, char** argv) { | 154 int main(int argc, char** argv) { |
| 155 CommandLine::Init(argc, argv); | |
|
tapted
2014/05/05 07:02:01
Hm - this will be called again at ChromeAppModeSta
| |
| 140 app_mode::ChromeAppModeInfo info; | 156 app_mode::ChromeAppModeInfo info; |
| 141 | 157 |
| 142 // Hard coded info parameters. | 158 // Hard coded info parameters. |
| 143 info.major_version = app_mode::kCurrentChromeAppModeInfoMajorVersion; | 159 info.major_version = app_mode::kCurrentChromeAppModeInfoMajorVersion; |
| 144 info.minor_version = app_mode::kCurrentChromeAppModeInfoMinorVersion; | 160 info.minor_version = app_mode::kCurrentChromeAppModeInfoMinorVersion; |
| 145 info.argc = argc; | 161 info.argc = argc; |
| 146 info.argv = argv; | 162 info.argv = argv; |
| 147 | 163 |
| 148 // Exit instead of returning to avoid the the removal of |main()| from stack | 164 // Exit instead of returning to avoid the the removal of |main()| from stack |
| 149 // backtraces under tail call optimization. | 165 // backtraces under tail call optimization. |
| 150 exit(LoadFrameworkAndStart(&info)); | 166 exit(LoadFrameworkAndStart(&info)); |
| 151 } | 167 } |
| OLD | NEW |