summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/app_mode-Info.plist6
-rw-r--r--chrome/app/app_mode_loader_mac.mm6
-rw-r--r--chrome/app/chrome_main_app_mode_mac.mm6
-rw-r--r--chrome/browser/web_applications/web_app_mac.h27
-rw-r--r--chrome/browser/web_applications/web_app_mac.mm37
-rw-r--r--chrome/browser/web_applications/web_app_mac_unittest.mm24
-rw-r--r--chrome/chrome.gyp38
-rw-r--r--chrome/chrome_dll.gypi6
-rw-r--r--chrome/chrome_tests.gypi2
-rw-r--r--chrome/common/mac/app_mode_common.h17
-rw-r--r--chrome/common/mac/app_mode_common.mm5
11 files changed, 140 insertions, 34 deletions
diff --git a/chrome/app/app_mode-Info.plist b/chrome/app/app_mode-Info.plist
index 611f7c5..1603382 100644
--- a/chrome/app/app_mode-Info.plist
+++ b/chrome/app/app_mode-Info.plist
@@ -6,12 +6,14 @@
<string>en</string>
<key>CFBundleDisplayName</key>
<string>@APP_MODE_SHORTCUT_SHORT_NAME@</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
<key>CFBundleExecutable</key>
- <string>@APP_MODE_SHORTCUT_ID@</string>
+ <string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>app.icns</string>
<key>CFBundleIdentifier</key>
- <string>????</string>
+ <string>${APP_MODE_APP_BUNDLE_ID}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
diff --git a/chrome/app/app_mode_loader_mac.mm b/chrome/app/app_mode_loader_mac.mm
index 3d10145..a691b15 100644
--- a/chrome/app/app_mode_loader_mac.mm
+++ b/chrome/app/app_mode_loader_mac.mm
@@ -39,8 +39,8 @@ void LoadFramework(void** cr_dylib, app_mode::ChromeAppModeInfo* info) {
// ** 1: Get path to outer Chrome bundle.
// Get the bundle ID of the browser that created this app bundle.
- NSString* cr_bundle_id = [app_bundle
- objectForInfoDictionaryKey:app_mode::kBrowserBundleIDKey];
+ NSString* cr_bundle_id = base::mac::ObjCCast<NSString>(
+ [app_bundle objectForInfoDictionaryKey:app_mode::kBrowserBundleIDKey]);
CHECK(cr_bundle_id) << "couldn't get browser bundle ID";
// First check if Chrome exists at the last known location.
@@ -72,6 +72,7 @@ void LoadFramework(void** cr_dylib, app_mode::ChromeAppModeInfo* info) {
}
// ** 3: Fill in ChromeAppModeInfo.
+ info->chrome_outer_bundle_path = cr_bundle_path;
info->chrome_versioned_path = version_path;
info->app_mode_bundle_path =
base::mac::NSStringToFilePath([app_bundle bundlePath]);
@@ -93,7 +94,6 @@ void LoadFramework(void** cr_dylib, app_mode::ChromeAppModeInfo* info) {
info->app_mode_url = SysNSStringToUTF8(
[info_plist objectForKey:app_mode::kCrAppModeShortcutURLKey]);
- CHECK(info->app_mode_url.size()) << "couldn't get app shortcut URL";
info->user_data_dir = base::mac::NSStringToFilePath(
[info_plist objectForKey:app_mode::kCrAppModeUserDataDirKey]);
diff --git a/chrome/app/chrome_main_app_mode_mac.mm b/chrome/app/chrome_main_app_mode_mac.mm
index b32ae31..043f87f 100644
--- a/chrome/app/chrome_main_app_mode_mac.mm
+++ b/chrome/app/chrome_main_app_mode_mac.mm
@@ -13,6 +13,8 @@
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/logging.h"
+#include "base/mac/bundle_locations.h"
+#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/mac/app_mode_common.h"
@@ -43,9 +45,13 @@ int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info) {
FilePath* chrome_versioned_path = new FilePath(info->chrome_versioned_path);
RAW_CHECK(!chrome_versioned_path->empty());
chrome::SetOverrideVersionedDirectory(chrome_versioned_path);
+ base::mac::SetOverrideOuterBundlePath(info->chrome_outer_bundle_path);
+ base::mac::SetOverrideFrameworkBundlePath(
+ chrome_versioned_path->Append(chrome::kFrameworkName));
CommandLine command_line(CommandLine::NO_PROGRAM);
command_line.AppendSwitch(info->argv[0]);
+
RAW_CHECK(info->app_mode_id.size());
command_line.AppendSwitchASCII(switches::kAppId, info->app_mode_id);
command_line.AppendSwitchPath(switches::kUserDataDir, info->user_data_dir);
diff --git a/chrome/browser/web_applications/web_app_mac.h b/chrome/browser/web_applications/web_app_mac.h
index 1723ac1..968bb8c 100644
--- a/chrome/browser/web_applications/web_app_mac.h
+++ b/chrome/browser/web_applications/web_app_mac.h
@@ -8,8 +8,17 @@
#include "base/file_path.h"
#include "base/gtest_prod_util.h"
+#include "base/string16.h"
#include "chrome/browser/shell_integration.h"
+#ifdef __OBJC__
+@class NSDictionary;
+@class NSString;
+#else // __OBJC__
+class NSDictionary;
+class NSString;
+#endif // __OBJC__
+
namespace web_app {
// Creates a shortcut for a web application. The shortcut is a stub app
@@ -18,12 +27,16 @@ class WebAppShortcutCreator {
public:
// Creates a new shortcut based on information in |shortcut_info|.
// The shortcut stores its user data directory in |user_data_dir|.
- explicit WebAppShortcutCreator(
+ // |chrome_bundle_id| is the CFBundleIdentifier of the Chrome browser bundle.
+ WebAppShortcutCreator(
const FilePath& user_data_dir,
- const ShellIntegration::ShortcutInfo& shortcut_info);
+ const ShellIntegration::ShortcutInfo& shortcut_info,
+ const string16& chrome_bundle_id);
+
virtual ~WebAppShortcutCreator();
- // Creates a shortcut.
+ // Copies the app launcher template into place and fills in all relevant
+ // information.
bool CreateShortcut();
protected:
@@ -47,8 +60,16 @@ class WebAppShortcutCreator {
// Note, the user data directory is the parent of the profile directory.
FilePath user_data_dir_;
+ // Returns the bundle identifier to use for this app bundle.
+ // |plist| is a dictionary containg a copy of the template plist file to
+ // be used for creating the app bundle.
+ NSString* GetBundleIdentifier(NSDictionary* plist) const;
+
// Information about the app.
ShellIntegration::ShortcutInfo info_;
+
+ // The CFBundleIdentifier of the Chrome browser bundle.
+ string16 chrome_bundle_id_;
};
} // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_mac.mm b/chrome/browser/web_applications/web_app_mac.mm
index 2bdfe1a..33adce3 100644
--- a/chrome/browser/web_applications/web_app_mac.mm
+++ b/chrome/browser/web_applications/web_app_mac.mm
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/web_applications/web_app_mac.h"
+#import "chrome/browser/web_applications/web_app_mac.h"
#import <Cocoa/Cocoa.h>
@@ -13,7 +13,9 @@
#include "base/memory/scoped_nsobject.h"
#include "base/scoped_temp_dir.h"
#include "base/sys_string_conversions.h"
+#include "base/utf_string_conversions.h"
#include "chrome/browser/web_applications/web_app.h"
+#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/mac/app_mode_common.h"
#include "content/public/browser/browser_thread.h"
#include "grit/chromium_strings.h"
@@ -40,9 +42,11 @@ namespace web_app {
WebAppShortcutCreator::WebAppShortcutCreator(
const FilePath& user_data_dir,
- const ShellIntegration::ShortcutInfo& shortcut_info)
+ const ShellIntegration::ShortcutInfo& shortcut_info,
+ const string16& chrome_bundle_id)
: user_data_dir_(user_data_dir),
- info_(shortcut_info) {
+ info_(shortcut_info),
+ chrome_bundle_id_(chrome_bundle_id) {
}
WebAppShortcutCreator::~WebAppShortcutCreator() {
@@ -83,10 +87,8 @@ bool WebAppShortcutCreator::CreateShortcut() {
}
FilePath WebAppShortcutCreator::GetAppLoaderPath() const {
- NSString* app_loader = [l10n_util::GetNSString(IDS_PRODUCT_NAME)
- stringByAppendingString:@" App Mode Loader.app"];
return base::mac::PathForFrameworkBundleResource(
- base::mac::NSToCFCast(app_loader));
+ base::mac::NSToCFCast(@"app_mode_loader.app"));
}
FilePath WebAppShortcutCreator::GetDestinationPath(
@@ -109,6 +111,8 @@ bool WebAppShortcutCreator::UpdatePlist(const FilePath& app_path) const {
NSMutableDictionary* dict =
[NSMutableDictionary dictionaryWithContentsOfFile:plist_path];
+ [dict setObject:GetBundleIdentifier(dict)
+ forKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)];
[dict setObject:base::SysUTF8ToNSString(info_.extension_id)
forKey:app_mode::kCrAppModeShortcutIDKey];
[dict setObject:base::SysUTF16ToNSString(info_.title)
@@ -119,6 +123,8 @@ bool WebAppShortcutCreator::UpdatePlist(const FilePath& app_path) const {
forKey:app_mode::kCrAppModeUserDataDirKey];
[dict setObject:base::mac::FilePathToNSString(info_.extension_path)
forKey:app_mode::kCrAppModeExtensionPathKey];
+ [dict setObject:base::SysUTF16ToNSString(chrome_bundle_id_)
+ forKey:app_mode::kBrowserBundleIDKey];
return [dict writeToFile:plist_path atomically:YES];
}
@@ -152,6 +158,21 @@ bool WebAppShortcutCreator::UpdateIcon(const FilePath& app_path) const {
return [icon_family writeToFile:base::mac::FilePathToNSString(icon_path)];
}
+NSString* WebAppShortcutCreator::GetBundleIdentifier(NSDictionary* plist) const
+{
+ NSString* bundle_id_template =
+ base::mac::ObjCCast<NSString>(
+ [plist objectForKey:base::mac::CFToNSCast(kCFBundleIdentifierKey)]);
+ NSString* extension_id = base::SysUTF8ToNSString(info_.extension_id);
+ NSString* placeholder =
+ [NSString stringWithFormat:@"@%@@", app_mode::kShortcutIdPlaceholder];
+ NSString* bundle_id =
+ [bundle_id_template
+ stringByReplacingOccurrencesOfString:placeholder
+ withString:extension_id];
+ return bundle_id;
+}
+
} // namespace
namespace web_app {
@@ -161,7 +182,9 @@ void CreateShortcutTask(const FilePath& web_app_path,
const FilePath& profile_path,
const ShellIntegration::ShortcutInfo& shortcut_info) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::FILE));
- WebAppShortcutCreator shortcut_creator(web_app_path, shortcut_info);
+ string16 bundle_id = UTF8ToUTF16(base::mac::BaseBundleID());
+ WebAppShortcutCreator shortcut_creator(web_app_path, shortcut_info,
+ bundle_id);
shortcut_creator.CreateShortcut();
}
diff --git a/chrome/browser/web_applications/web_app_mac_unittest.mm b/chrome/browser/web_applications/web_app_mac_unittest.mm
index 6d95261..fa11eaa 100644
--- a/chrome/browser/web_applications/web_app_mac_unittest.mm
+++ b/chrome/browser/web_applications/web_app_mac_unittest.mm
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/web_applications/web_app_mac.h"
+#import "chrome/browser/web_applications/web_app_mac.h"
#import <Cocoa/Cocoa.h>
@@ -30,7 +30,8 @@ class WebAppShortcutCreatorMock : public web_app::WebAppShortcutCreator {
public:
explicit WebAppShortcutCreatorMock(
const ShellIntegration::ShortcutInfo& shortcut_info)
- : WebAppShortcutCreator(FilePath(), shortcut_info) {
+ : WebAppShortcutCreator(FilePath(), shortcut_info,
+ UTF8ToUTF16("fake.cfbundleidentifier")) {
}
MOCK_CONST_METHOD1(GetDestinationPath, FilePath(const FilePath&));
@@ -48,8 +49,11 @@ ShellIntegration::ShortcutInfo GetShortcutInfo() {
namespace web_app {
-// This test currently fails because the Mac app loader isn't built yet.
-TEST(WebAppShortcutCreatorTest, FAILS_CreateShortcut) {
+// This test is disabled for the following reasons:
+// * The plist still isn't filled in correctly.
+// * WebAppShortcutCreator::CreateShortcut() opens a Finder window which it
+// shouldn't be doing when run from a unit test.
+TEST(WebAppShortcutCreatorTest, DISABLED_CreateShortcut) {
ScopedTempDir scoped_temp_dir;
EXPECT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
FilePath dst_path = scoped_temp_dir.path().Append("a.app");
@@ -72,11 +76,17 @@ TEST(WebAppShortcutCreatorTest, FAILS_CreateShortcut) {
[plist objectForKey:app_mode::kCrAppModeShortcutURLKey]);
// Make sure all values in the plist are actually filled in.
- for (NSString* value in [plist allValues])
- EXPECT_FALSE([value hasPrefix:@"@APP_"]);
+ for (id key in plist) {
+ id value = [plist valueForKey:key];
+ if (!base::mac::ObjCCast<NSString>(value))
+ continue;
+
+ EXPECT_EQ([value rangeOfString:@"@APP_"].location, NSNotFound)
+ << [key UTF8String] << ":" << [value UTF8String];
+ }
}
-TEST(WebAppShortcutCreatorTest, CreateFailure) {
+TEST(WebAppShortcutCreatorTest, DISABLED_CreateFailure) {
NiceMock<WebAppShortcutCreatorMock> shortcut_creator(GetShortcutInfo());
EXPECT_CALL(shortcut_creator, GetDestinationPath(_))
.WillRepeatedly(Return(FilePath("/non-existant/path/")));
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index ccac7c4..f07d554 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -781,7 +781,7 @@
# Modify the Info.plist as needed. The script explains why this
# is needed. This is also done in the chrome and chrome_dll
# targets. In this case, --breakpad=0, -k0, and -s0 are used
- # because Breakpad, Keystone, and Subersion keys are never
+ # because Breakpad, Keystone, and Subversion keys are never
# placed into the helper.
'postbuild_name': 'Tweak Info.plist',
'action': ['<(tweak_info_plist_path)',
@@ -841,17 +841,21 @@
],
}, # target app_mode_app_support
{
- # This produces the app mode loader, but not as a bundle. Chromium
- # itself is responsible for producing bundles.
+ # This produces the template for app mode loader bundles. It's a
+ # template in the sense that parts of it need to be "filled in" by
+ # Chrome before it can be executed.
'target_name': 'app_mode_app',
'type': 'executable',
+ 'mac_bundle' : 1,
'variables': { 'enable_wexit_time_destructors': 1, },
- 'product_name': '<(mac_product_name) App Mode Loader',
+ 'product_name': 'app_mode_loader',
'dependencies': [
'app_mode_app_support',
+ 'infoplist_strings_tool',
],
'sources': [
'app/app_mode_loader_mac.mm',
+ 'app/app_mode-Info.plist',
],
'include_dirs': [
'..',
@@ -862,6 +866,32 @@
'$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
],
},
+ 'mac_bundle_resources!': [
+ 'app/app_mode-Info.plist',
+ ],
+ 'mac_bundle_resources/': [
+ ['exclude', '.*'],
+ ],
+ 'xcode_settings': {
+ 'INFOPLIST_FILE': 'app/app_mode-Info.plist',
+ 'APP_MODE_APP_BUNDLE_ID': '<(mac_bundle_id).app.@APP_MODE_SHORTCUT_ID@',
+ },
+ 'postbuilds' : [
+ {
+ # Modify the Info.plist as needed. The script explains why this
+ # is needed. This is also done in the chrome and chrome_dll
+ # targets. In this case, --breakpad=0, -k0, and -s0 are used
+ # because Breakpad, Keystone, and Subversion keys are never
+ # placed into the app mode loader.
+ 'postbuild_name': 'Tweak Info.plist',
+ 'action': ['<(tweak_info_plist_path)',
+ '--breakpad=0',
+ '-k0',
+ '-s0',
+ '<(branding)',
+ '<(mac_bundle_id)'],
+ },
+ ],
}, # target app_mode_app
{
# Convenience target to build a disk image.
diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi
index afd6034..14d89de 100644
--- a/chrome/chrome_dll.gypi
+++ b/chrome/chrome_dll.gypi
@@ -310,6 +310,7 @@
'app/framework-Info.plist',
],
'dependencies': [
+ 'app_mode_app',
# Bring in pdfsqueeze and run it on all pdfs
'../build/temp_gyp/pdfsqueeze.gyp:pdfsqueeze',
'../crypto/crypto.gyp:crypto',
@@ -444,7 +445,10 @@
},
{
'destination': '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)/resources',
- 'files': [],
+ 'files': [
+ # Loader bundle for platform apps.
+ '<(PRODUCT_DIR)/app_mode_loader.app',
+ ],
'conditions': [
['debug_devtools!=0', {
'files': [
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index eda65a0..555f224 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -4241,7 +4241,7 @@
# Tests for Mac app launcher.
'target_name': 'app_mode_app_tests',
'type': 'executable',
- 'product_name': 'App Mode Loader Tests',
+ 'product_name': 'app_mode_app_tests',
'dependencies': [
'../base/base.gyp:test_support_base',
'../testing/gtest.gyp:gtest',
diff --git a/chrome/common/mac/app_mode_common.h b/chrome/common/mac/app_mode_common.h
index 930d22d..b8bc539 100644
--- a/chrome/common/mac/app_mode_common.h
+++ b/chrome/common/mac/app_mode_common.h
@@ -20,10 +20,6 @@ namespace app_mode {
// app mode launcher bundle's Info.plist.
extern NSString* const kBrowserBundleIDKey;
-// The key under which to record the path to the (user-visible) application
-// bundle; this key is recorded under the ID given by |kAppPrefsID|.
-extern NSString* const kLastRunAppBundlePathPrefsKey;
-
// Key for the shortcut ID.
extern NSString* const kCrAppModeShortcutIDKey;
@@ -42,6 +38,14 @@ extern NSString* const kCrAppModeUserDataDirKey;
// Key for the app's extension path.
extern NSString* const kCrAppModeExtensionPathKey;
+// When the Chrome browser is run, it stores it's location in the defaults
+// system using this key.
+extern NSString* const kLastRunAppBundlePathPrefsKey;
+
+// Placeholder used in the Info.plist, meant to be replaced by the extension
+// shortcut ID.
+extern NSString* const kShortcutIdPlaceholder;
+
// Current major/minor version numbers of |ChromeAppModeInfo| (defined below).
const unsigned kCurrentChromeAppModeInfoMajorVersion = 1;
const unsigned kCurrentChromeAppModeInfoMinorVersion = 0;
@@ -68,9 +72,12 @@ struct ChromeAppModeInfo {
// Versioned path to the browser which is being loaded.
FilePath chrome_versioned_path; // Required: v1.0
+ // Path to Chrome app bundle.
+ FilePath chrome_outer_bundle_path; // Required: v1.0
+
// Information about the App Mode shortcut:
- // Path to the App Mode Loader application bundle originally run.
+ // Path to the App Mode Loader application bundle that launched the process.
FilePath app_mode_bundle_path; // Optional: v1.0
// Short ID string, preferably derived from |app_mode_short_name|. Should be
diff --git a/chrome/common/mac/app_mode_common.mm b/chrome/common/mac/app_mode_common.mm
index 48bf38e..bb8c267 100644
--- a/chrome/common/mac/app_mode_common.mm
+++ b/chrome/common/mac/app_mode_common.mm
@@ -7,7 +7,6 @@
namespace app_mode {
NSString* const kBrowserBundleIDKey = @"CrBundleIdentifier";
-NSString* const kLastRunAppBundlePathPrefsKey = @"LastRunAppBundlePath";
NSString* const kCrAppModeShortcutIDKey = @"CrAppModeShortcutID";
NSString* const kCrAppModeShortcutShortNameKey = @"CrAppModeShortcutShortName";
NSString* const kCrAppModeShortcutNameKey = @"CrAppModeShortcutName";
@@ -15,6 +14,10 @@ NSString* const kCrAppModeShortcutURLKey = @"CrAppModeShortcutURL";
NSString* const kCrAppModeUserDataDirKey = @"CrAppModeUserDataDir";
NSString* const kCrAppModeExtensionPathKey = @"CrAppModeExtensionPath";
+NSString* const kLastRunAppBundlePathPrefsKey = @"LastRunAppBundlePath";
+
+NSString* const kShortcutIdPlaceholder = @"APP_MODE_SHORTCUT_ID";
+
ChromeAppModeInfo::ChromeAppModeInfo()
: major_version(0),
minor_version(0),