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 |