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

Side by Side Diff: chrome/browser/web_applications/web_app_mac.mm

Issue 16304005: Create a copy of each app's shim bundle in the app's app_data_path. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments. Created 7 years, 6 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 #import "chrome/browser/web_applications/web_app_mac.h" 5 #import "chrome/browser/web_applications/web_app_mac.h"
6 6
7 #import <Carbon/Carbon.h> 7 #import <Carbon/Carbon.h>
8 #import <Cocoa/Cocoa.h> 8 #import <Cocoa/Cocoa.h>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 return false; 159 return false;
160 } 160 }
161 161
162 } // namespace 162 } // namespace
163 163
164 namespace web_app { 164 namespace web_app {
165 165
166 const char kChromeAppDirName[] = "Chrome Apps.localized"; 166 const char kChromeAppDirName[] = "Chrome Apps.localized";
167 167
168 WebAppShortcutCreator::WebAppShortcutCreator( 168 WebAppShortcutCreator::WebAppShortcutCreator(
169 const base::FilePath& user_data_dir, 169 const base::FilePath& web_app_path,
170 const ShellIntegration::ShortcutInfo& shortcut_info, 170 const ShellIntegration::ShortcutInfo& shortcut_info,
171 const string16& chrome_bundle_id) 171 const string16& chrome_bundle_id)
172 : user_data_dir_(user_data_dir), 172 : web_app_path_(web_app_path),
173 info_(shortcut_info), 173 info_(shortcut_info),
174 chrome_bundle_id_(chrome_bundle_id) { 174 chrome_bundle_id_(chrome_bundle_id) {
175 } 175 }
176 176
177 WebAppShortcutCreator::~WebAppShortcutCreator() { 177 WebAppShortcutCreator::~WebAppShortcutCreator() {
178 } 178 }
179 179
180 base::FilePath WebAppShortcutCreator::GetShortcutPath() const { 180 base::FilePath WebAppShortcutCreator::GetShortcutPath() const {
181 base::FilePath dst_path = GetDestinationPath(); 181 base::FilePath dst_path = GetDestinationPath();
182 if (dst_path.empty()) 182 if (dst_path.empty())
183 return dst_path; 183 return dst_path;
184 184
185 base::FilePath app_name = internals::GetSanitizedFileName(UTF8ToUTF16( 185 base::FilePath app_name = internals::GetSanitizedFileName(UTF8ToUTF16(
186 info_.profile_path.BaseName().value() + " " + info_.extension_id)); 186 info_.profile_path.BaseName().value() + " " + info_.extension_id));
187 return dst_path.Append(app_name.ReplaceExtension("app")); 187 return dst_path.Append(app_name.ReplaceExtension("app"));
188 } 188 }
189 189
190 bool WebAppShortcutCreator::CreateShortcut() { 190 bool WebAppShortcutCreator::CreateShortcut() {
191 base::FilePath app_path = GetShortcutPath(); 191 base::FilePath app_path = GetShortcutPath();
192 base::FilePath app_name = app_path.BaseName(); 192 base::FilePath app_name = app_path.BaseName();
193 base::FilePath dst_path = app_path.DirName(); 193 base::FilePath dst_path = app_path.DirName();
194 if (app_path.empty() || !file_util::DirectoryExists(dst_path.DirName())) { 194 if (app_path.empty() || !file_util::DirectoryExists(dst_path.DirName())) {
195 LOG(ERROR) << "Couldn't find an Applications directory to copy app to."; 195 LOG(ERROR) << "Couldn't find an Applications directory to copy app to.";
196 return false; 196 return false;
197 } 197 }
198 if (!file_util::CreateDirectory(web_app_path_)) {
199 LOG(ERROR) << "Creating web_app_path " << web_app_path_.value()
200 << " failed.";
201 return false;
202 }
198 if (!file_util::CreateDirectory(dst_path)) { 203 if (!file_util::CreateDirectory(dst_path)) {
199 LOG(ERROR) << "Creating directory " << dst_path.value() << " failed."; 204 LOG(ERROR) << "Creating directory " << dst_path.value() << " failed.";
200 return false; 205 return false;
201 } 206 }
202 207
203 base::ScopedTempDir scoped_temp_dir; 208 base::ScopedTempDir scoped_temp_dir;
204 if (!scoped_temp_dir.CreateUniqueTempDir()) 209 if (!scoped_temp_dir.CreateUniqueTempDir())
205 return false; 210 return false;
206 base::FilePath staging_path = scoped_temp_dir.path().Append(app_name); 211 base::FilePath staging_path = scoped_temp_dir.path().Append(app_name);
207 212
208 // Update the app's plist and icon in a temp directory. This works around 213 // Update the app's plist and icon in a temp directory. This works around
209 // a Finder bug where the app's icon doesn't properly update. 214 // a Finder bug where the app's icon doesn't properly update.
210 if (!file_util::CopyDirectory(GetAppLoaderPath(), staging_path, true)) { 215 if (!file_util::CopyDirectory(GetAppLoaderPath(), staging_path, true)) {
211 LOG(ERROR) << "Copying app to staging path: " << staging_path.value() 216 LOG(ERROR) << "Copying app to staging path: " << staging_path.value()
212 << " failed"; 217 << " failed.";
213 return false; 218 return false;
214 } 219 }
215 220
216 if (!UpdatePlist(staging_path)) 221 if (!UpdatePlist(staging_path))
217 return false; 222 return false;
218 223
219 if (!UpdateDisplayName(staging_path)) 224 if (!UpdateDisplayName(staging_path))
220 return false; 225 return false;
221 226
222 if (!UpdateIcon(staging_path)) 227 if (!UpdateIcon(staging_path))
223 return false; 228 return false;
224 229
225 if (!file_util::CopyDirectory(staging_path, dst_path, true)) { 230 // Put one copy in the app's web_app_path so we can still run it if the user
benwells 2013/06/13 00:13:31 What happens if the shortcut is being created in r
jackhou1 2013/06/13 01:33:43 It will replace the shim with the same files (thou
benwells 2013/06/13 03:57:43 On other platforms we have used the shortcut locat
jackhou1 2013/06/14 03:31:27 At the moment, there's no dialog to choose where t
226 LOG(ERROR) << "Copying app to dst path: " << dst_path.value() << " failed"; 231 // deletes the one in the applications folder.
232 if (!file_util::CopyDirectory(staging_path, web_app_path_, true)) {
233 NOTREACHED();
227 return false; 234 return false;
228 } 235 }
236 base::mac::RemoveQuarantineAttribute(web_app_path_.Append(app_name));
237
238 if (!file_util::CopyDirectory(staging_path, dst_path, true))
239 return false;
229 240
230 base::mac::RemoveQuarantineAttribute(app_path); 241 base::mac::RemoveQuarantineAttribute(app_path);
242
231 RevealGeneratedBundleInFinder(app_path); 243 RevealGeneratedBundleInFinder(app_path);
232 244
233 return true; 245 return true;
234 } 246 }
235 247
236 base::FilePath WebAppShortcutCreator::GetAppLoaderPath() const { 248 base::FilePath WebAppShortcutCreator::GetAppLoaderPath() const {
237 return base::mac::PathForFrameworkBundleResource( 249 return base::mac::PathForFrameworkBundleResource(
238 base::mac::NSToCFCast(@"app_mode_loader.app")); 250 base::mac::NSToCFCast(@"app_mode_loader.app"));
239 } 251 }
240 252
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 [value substringWithRange:NSMakeRange(1, [value length] - 2)]; 287 [value substringWithRange:NSMakeRange(1, [value length] - 2)];
276 288
277 NSString* substitution = [replacement_dict valueForKey:variable]; 289 NSString* substitution = [replacement_dict valueForKey:variable];
278 if (substitution) 290 if (substitution)
279 [plist setObject:substitution forKey:key]; 291 [plist setObject:substitution forKey:key];
280 } 292 }
281 293
282 // 2. Fill in other values. 294 // 2. Fill in other values.
283 [plist setObject:GetBundleIdentifier(plist) 295 [plist setObject:GetBundleIdentifier(plist)
284 forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]; 296 forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)];
285 [plist setObject:base::mac::FilePathToNSString(user_data_dir_) 297 [plist setObject:base::mac::FilePathToNSString(web_app_path_)
286 forKey:app_mode::kCrAppModeUserDataDirKey]; 298 forKey:app_mode::kCrAppModeUserDataDirKey];
287 [plist setObject:base::mac::FilePathToNSString(info_.profile_path.BaseName()) 299 [plist setObject:base::mac::FilePathToNSString(info_.profile_path.BaseName())
288 forKey:app_mode::kCrAppModeProfileDirKey]; 300 forKey:app_mode::kCrAppModeProfileDirKey];
289 [plist setObject:base::SysUTF8ToNSString(info_.profile_name) 301 [plist setObject:base::SysUTF8ToNSString(info_.profile_name)
290 forKey:app_mode::kCrAppModeProfileNameKey]; 302 forKey:app_mode::kCrAppModeProfileNameKey];
291 [plist setObject:[NSNumber numberWithBool:YES] 303 [plist setObject:[NSNumber numberWithBool:YES]
292 forKey:app_mode::kLSHasLocalizedDisplayNameKey]; 304 forKey:app_mode::kLSHasLocalizedDisplayNameKey];
293 305
294 base::FilePath app_name = app_path.BaseName().RemoveExtension(); 306 base::FilePath app_name = app_path.BaseName().RemoveExtension();
295 [plist setObject:base::mac::FilePathToNSString(app_name) 307 [plist setObject:base::mac::FilePathToNSString(app_name)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 const base::FilePath& generated_bundle) const { 387 const base::FilePath& generated_bundle) const {
376 [[NSWorkspace sharedWorkspace] 388 [[NSWorkspace sharedWorkspace]
377 selectFile:base::mac::FilePathToNSString(generated_bundle) 389 selectFile:base::mac::FilePathToNSString(generated_bundle)
378 inFileViewerRootedAtPath:nil]; 390 inFileViewerRootedAtPath:nil];
379 } 391 }
380 392
381 void LaunchShimOnFileThread( 393 void LaunchShimOnFileThread(
382 const ShellIntegration::ShortcutInfo& shortcut_info) { 394 const ShellIntegration::ShortcutInfo& shortcut_info) {
383 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE)); 395 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
384 base::FilePath shim_path = web_app::GetAppInstallPath(shortcut_info); 396 base::FilePath shim_path = web_app::GetAppInstallPath(shortcut_info);
385 if (shim_path.empty()) 397
386 return; 398 if (shim_path.empty() || !file_util::PathExists(shim_path)) {
399 // The user may have deleted the copy in the Applications folder, use the
400 // one in the web app's web_app_path.
401 base::FilePath web_app_path = GetWebAppDataDirectory(
402 shortcut_info.profile_path, shortcut_info.extension_id, GURL());
403 shim_path = web_app_path.Append(shim_path.BaseName());
404 }
387 405
388 CommandLine command_line(CommandLine::NO_PROGRAM); 406 CommandLine command_line(CommandLine::NO_PROGRAM);
389 command_line.AppendSwitch(app_mode::kNoLaunchApp); 407 command_line.AppendSwitch(app_mode::kNoLaunchApp);
390 base::mac::OpenApplicationWithPath(shim_path, command_line, NULL); 408 base::mac::OpenApplicationWithPath(shim_path, command_line, NULL);
391 } 409 }
392 410
393 } // namespace 411 } // namespace
394 412
395 namespace web_app { 413 namespace web_app {
396 414
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 const base::FilePath& web_app_path, 474 const base::FilePath& web_app_path,
457 const string16& old_app_title, 475 const string16& old_app_title,
458 const ShellIntegration::ShortcutInfo& shortcut_info) { 476 const ShellIntegration::ShortcutInfo& shortcut_info) {
459 // TODO(benwells): Implement this when shortcuts / weblings are enabled on 477 // TODO(benwells): Implement this when shortcuts / weblings are enabled on
460 // mac. 478 // mac.
461 } 479 }
462 480
463 } // namespace internals 481 } // namespace internals
464 482
465 } // namespace web_app 483 } // namespace web_app
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698