Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: chrome/app/app_mode_loader_mac.mm

Issue 265163006: [Mac] Rebuild app shims when they fail to dyload Chrome Framework. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync and rebase Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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)
119 return ChromeAppModeStart(info); 125 return ChromeAppModeStart(info);
120 } else { 126
121 LOG(ERROR) << "Loading Chrome failed, launching with command line."; 127 LOG(ERROR) << "Loading Chrome failed, launching Chrome with command line";
122 // Launch Chrome instead and have it update this app_mode_loader bundle. 128 CommandLine command_line(executable_path);
123 CommandLine command_line(CommandLine::NO_PROGRAM); 129 if (CommandLine::ForCurrentProcess()->HasSwitch(
130 app_mode::kLaunchedByChromeProcessId) ||
131 info->app_mode_id == app_mode::kAppListModeId) {
132 // Pass --app-shim-error to have Chrome rebuild this shim.
124 command_line.AppendSwitchPath(app_mode::kAppShimError, 133 command_line.AppendSwitchPath(app_mode::kAppShimError,
125 app_mode_bundle_path); 134 app_mode_bundle_path);
126 if (!base::mac::OpenApplicationWithPath( 135 } else {
127 cr_bundle_path, command_line, kLSLaunchDefaults, NULL)) { 136 // If the shim was launched directly (instead of by Chrome), first ask
128 LOG(ERROR) << "Could not launch Chrome from: " << cr_bundle_path.value(); 137 // Chrome to launch the app. Chrome will launch the shim again, the same
129 return 1; 138 // error will occur and be handled above. This approach allows the app to be
130 } 139 // started without blocking on fixing the shim and guarantees that the
140 // profile is loaded when Chrome receives --app-shim-error.
141 command_line.AppendSwitchPath(switches::kProfileDirectory,
142 info->profile_dir);
143 command_line.AppendSwitchASCII(switches::kAppId, info->app_mode_id);
144 }
145 // Launch the executable directly since base::mac::OpenApplicationWithPath
146 // uses LSOpenApplication which doesn't pass command line arguments if the
147 // application is already running.
148 if (!base::LaunchProcess(command_line, base::LaunchOptions(), NULL)) {
149 LOG(ERROR) << "Could not launch Chrome: "
150 << command_line.GetCommandLineString();
151 return 1;
152 }
131 153
132 return 0; 154 return 0;
133 }
134 } 155 }
135 156
136 } // namespace 157 } // namespace
137 158
138 __attribute__((visibility("default"))) 159 __attribute__((visibility("default")))
139 int main(int argc, char** argv) { 160 int main(int argc, char** argv) {
161 CommandLine::Init(argc, argv);
140 app_mode::ChromeAppModeInfo info; 162 app_mode::ChromeAppModeInfo info;
141 163
142 // Hard coded info parameters. 164 // Hard coded info parameters.
143 info.major_version = app_mode::kCurrentChromeAppModeInfoMajorVersion; 165 info.major_version = app_mode::kCurrentChromeAppModeInfoMajorVersion;
144 info.minor_version = app_mode::kCurrentChromeAppModeInfoMinorVersion; 166 info.minor_version = app_mode::kCurrentChromeAppModeInfoMinorVersion;
tapted 2014/05/06 07:13:24 we should increment this again, for the bulk updat
jackhou1 2014/05/06 08:38:17 Done.
145 info.argc = argc; 167 info.argc = argc;
146 info.argv = argv; 168 info.argv = argv;
147 169
148 // Exit instead of returning to avoid the the removal of |main()| from stack 170 // Exit instead of returning to avoid the the removal of |main()| from stack
149 // backtraces under tail call optimization. 171 // backtraces under tail call optimization.
150 exit(LoadFrameworkAndStart(&info)); 172 exit(LoadFrameworkAndStart(&info));
151 } 173 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698