summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-22 04:52:56 +0000
committerviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-22 04:52:56 +0000
commitddf124cb8f239ecfbe2339d16f4e3dc849798d20 (patch)
treeefd60310a937d87d9dfd48816779dad690111d83 /chrome/browser
parent0f7a0191f603800bbf7e387277ed29a6209063bc (diff)
downloadchromium_src-ddf124cb8f239ecfbe2339d16f4e3dc849798d20.zip
chromium_src-ddf124cb8f239ecfbe2339d16f4e3dc849798d20.tar.gz
chromium_src-ddf124cb8f239ecfbe2339d16f4e3dc849798d20.tar.bz2
Getting perf numbers. Will revert.
BUG=none TEST=none TBR=viettrungluu@chromium.org Review URL: http://codereview.chromium.org/502099 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35137 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/app_controller_mac.h18
-rw-r--r--chrome/browser/app_controller_mac.mm76
-rw-r--r--chrome/browser/browser_init.cc10
-rw-r--r--chrome/browser/browser_main.cc17
-rw-r--r--chrome/browser/browser_main.h22
-rw-r--r--chrome/browser/browser_main_mac.mm18
6 files changed, 103 insertions, 58 deletions
diff --git a/chrome/browser/app_controller_mac.h b/chrome/browser/app_controller_mac.h
index ba04a49..4ff1eb0 100644
--- a/chrome/browser/app_controller_mac.h
+++ b/chrome/browser/app_controller_mac.h
@@ -33,10 +33,12 @@ class Profile;
PreferencesWindowController* prefsController_; // Weak.
AboutWindowController* aboutController_; // Weak.
- // URLs that need to be opened when the app is fully initialized. Because it's
- // only needed during early startup, it points to a valid vector during early
- // startup and is NULL during the rest of app execution.
- scoped_ptr<std::vector<GURL> > pendingURLs_;
+ // If we're told to open URLs (in particular, via |-application:openFiles:| by
+ // Launch Services) before we've launched the browser, we queue them up in
+ // |startupURLs_| so that they can go in the first browser window/tab.
+ // |startupComplete_| is automatically initialized to |NO|.
+ std::vector<GURL> startupURLs_;
+ BOOL startupComplete_;
// Outlets for the close tab/window menu items so that we can adjust the
// commmand-key equivalent depending on the kind of window and how many
@@ -50,6 +52,8 @@ class Profile;
IBOutlet NSMenu* helpMenu_;
}
+@property(readonly, nonatomic) BOOL startupComplete;
+
- (void)didEndMainMessageLoop;
- (Profile*)defaultProfile;
@@ -64,6 +68,12 @@ class Profile;
// Delegate method to return the dock menu.
- (NSMenu*)applicationDockMenu:(NSApplication*)sender;
+// Get the URLs that Launch Services expects the browser to open at startup.
+- (const std::vector<GURL>&)startupURLs;
+
+// Clear the list of startup URLs.
+- (void)clearStartupURLs;
+
@end
#endif
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm
index 08d61b8..f465b17 100644
--- a/chrome/browser/app_controller_mac.mm
+++ b/chrome/browser/app_controller_mac.mm
@@ -45,6 +45,7 @@
#include "chrome/common/temp_scaffolding_stubs.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
+#include "net/base/net_util.h"
// 10.6 adds a public API for the Spotlight-backed search menu item in the Help
// menu. Provide the declaration so it can be called below when building with
@@ -80,12 +81,12 @@ static bool g_is_opening_new_window = false;
@implementation AppController
+@synthesize startupComplete = startupComplete_;
+
// This method is called very early in application startup (ie, before
// the profile is loaded or any preferences have been registered). Defer any
// user-data initialization until -applicationDidFinishLaunching:.
- (void)awakeFromNib {
- pendingURLs_.reset(new std::vector<GURL>());
-
// We need to register the handlers early to catch events fired on launch.
NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
[em setEventHandler:self
@@ -96,10 +97,6 @@ static bool g_is_opening_new_window = false;
andSelector:@selector(getUrl:withReply:)
forEventClass:'WWW!' // A particularly ancient AppleEvent that dates
andEventID:'OURL']; // back to the Spyglass days.
- [em setEventHandler:self
- andSelector:@selector(openFiles:withReply:)
- forEventClass:kCoreEventClass
- andEventID:kAEOpenDocuments];
// Register for various window layering changes. We use these to update
// various UI elements (command-key equivalents, etc) when the frontmost
@@ -353,12 +350,10 @@ static bool g_is_opening_new_window = false;
// Since Chrome is localized to more languages than the OS, tell Cocoa which
// menu is the Help so it can add the search item to it.
- if (helpMenu_ && [NSApp respondsToSelector:@selector(setHelpMenu:)]) {
+ if (helpMenu_ && [NSApp respondsToSelector:@selector(setHelpMenu:)])
[NSApp setHelpMenu:helpMenu_];
- }
- // Now that we're initialized we can open any URLs we've been holding onto.
- [self openPendingURLs];
+ startupComplete_ = YES;
}
// This is called after profiles have been loaded and preferences registered.
@@ -659,9 +654,9 @@ static bool g_is_opening_new_window = false;
// openings through that for uniform handling.
- (void)openURLs:(const std::vector<GURL>&)urls {
- if (pendingURLs_.get()) {
- // too early to open; save for later
- pendingURLs_->insert(pendingURLs_->end(), urls.begin(), urls.end());
+ // If the browser hasn't started yet, just queue up the URLs.
+ if (!startupComplete_) {
+ startupURLs_.insert(startupURLs_.end(), urls.begin(), urls.end());
return;
}
@@ -677,17 +672,6 @@ static bool g_is_opening_new_window = false;
launch.OpenURLsInBrowser(browser, false, urls);
}
-- (void)openPendingURLs {
- // Since the existence of pendingURLs_ is a flag that it's too early to
- // open URLs, we need to reset pendingURLs_.
- std::vector<GURL> urls;
- swap(urls, *pendingURLs_);
- pendingURLs_.reset();
-
- if (urls.size())
- [self openURLs:urls];
-}
-
- (void)getUrl:(NSAppleEventDescriptor*)event
withReply:(NSAppleEventDescriptor*)reply {
NSString* urlStr = [[event paramDescriptorForKeyword:keyDirectObject]
@@ -700,37 +684,19 @@ static bool g_is_opening_new_window = false;
[self openURLs:gurlVector];
}
-- (void)openFiles:(NSAppleEventDescriptor*)event
- withReply:(NSAppleEventDescriptor*)reply {
- // Ordinarily we'd use the NSApplication delegate method
- // -application:openFiles:, but Cocoa tries to be smart and it sends files
- // specified on the command line into that delegate method. That's too smart
- // for us (our setup isn't done by the time Cocoa triggers the delegate method
- // and we crash). Since all we want are files dropped on the app icon, and we
- // have cross-platform code to handle the command-line files anyway, an Apple
- // Event handler fits the bill just right.
- NSAppleEventDescriptor* fileList =
- [event paramDescriptorForKeyword:keyDirectObject];
- if (!fileList)
- return;
+- (void)application:(NSApplication*)sender
+ openFiles:(NSArray*)filenames {
std::vector<GURL> gurlVector;
-
- for (NSInteger i = 1; i <= [fileList numberOfItems]; ++i) {
- NSAppleEventDescriptor* fileAliasDesc = [fileList descriptorAtIndex:i];
- if (!fileAliasDesc)
- continue;
- NSAppleEventDescriptor* fileURLDesc =
- [fileAliasDesc coerceToDescriptorType:typeFileURL];
- if (!fileURLDesc)
- continue;
- NSData* fileURLData = [fileURLDesc data];
- if (!fileURLData)
- continue;
- GURL gurl(std::string((char*)[fileURLData bytes], [fileURLData length]));
+ for (NSString* file in filenames) {
+ GURL gurl = net::FilePathToFileURL(FilePath(base::SysNSStringToUTF8(file)));
gurlVector.push_back(gurl);
}
+ if (!gurlVector.empty())
+ [self openURLs:gurlVector];
+ else
+ NOTREACHED() << "Nothing to open!";
- [self openURLs:gurlVector];
+ [sender replyToOpenOrPrint:NSApplicationDelegateReplySuccess];
}
// Called when the preferences window is closed. We use this to release the
@@ -834,6 +800,14 @@ static bool g_is_opening_new_window = false;
return dockMenu;
}
+- (const std::vector<GURL>&)startupURLs {
+ return startupURLs_;
+}
+
+- (void)clearStartupURLs {
+ startupURLs_.clear();
+}
+
@end
//---------------------------------------------------------------------------
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc
index 3ccb82f..aa8f451 100644
--- a/chrome/browser/browser_init.cc
+++ b/chrome/browser/browser_init.cc
@@ -47,6 +47,7 @@
#include "webkit/glue/webkit_glue.h"
#if defined(OS_MACOSX)
+#include "chrome/browser/browser_main.h"
#include "chrome/browser/cocoa/keystone_infobar.h"
#endif
@@ -647,6 +648,15 @@ std::vector<GURL> BrowserInit::LaunchWithProfile::GetURLsFromCommandLine(
void BrowserInit::LaunchWithProfile::AddStartupURLs(
std::vector<GURL>* startup_urls) const {
+#if defined(OS_MACOSX)
+ // On Mac, startup URLs are usually delivered by Launch Services, not on the
+ // command line. Get them.
+ DCHECK(Platform::IsStartupComplete());
+ startup_urls->insert(startup_urls->end(), Platform::GetStartupURLs().begin(),
+ Platform::GetStartupURLs().end());
+ Platform::ClearStartupURLs();
+#endif
+
// If we have urls specified beforehand (i.e. from command line) use them
// and nothing else.
if (!startup_urls->empty())
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index ff1d17d..f8cbfd1 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -451,7 +451,6 @@ int BrowserMain(const MainFunctionParams& parameters) {
views::ViewsDelegate::views_delegate = new ChromeViewsDelegate;
#endif
-
if (is_first_run) {
#if defined(OS_WIN)
// During first run we read the google_update registry key to find what
@@ -901,8 +900,20 @@ int BrowserMain(const MainFunctionParams& parameters) {
MessageLoopForUI::current()->PostTask(FROM_HERE, parameters.ui_task);
RunUIMessageLoop(browser_process.get());
} else {
- // We are in regular browser boot sequence. Open initial stabs and enter
- // the main message loop.
+ // We are in regular browser boot sequence.
+#if defined(OS_MACOSX)
+ // On Mac, the message which provides the browser with the startup URLs and
+ // the Apple Event which generates |-applicationDidFinishLaunching:| are
+ // queued up.
+ // TODO(viettrungluu): This is what seems to happen *AFAICT*. This is a bit
+ // fragile. The DCHECK() below will fail if |-aDFL:| is not reached, but
+ // there is currently no way to tell if subsequent messages are processed.
+ // This is evidently fragile, and should be made more robust.
+ MessageLoopForUI::current()->RunAllPending();
+ DCHECK(Platform::IsStartupComplete());
+#endif
+
+ // Open initial tabs and enter the main message loop.
if (browser_init.Start(parsed_command_line, std::wstring(), profile,
&result_code)) {
// Call Recycle() here as late as possible, before going into the loop
diff --git a/chrome/browser/browser_main.h b/chrome/browser/browser_main.h
index 44bc6ab..5f675dd 100644
--- a/chrome/browser/browser_main.h
+++ b/chrome/browser/browser_main.h
@@ -7,6 +7,11 @@
#include "build/build_config.h"
+#if defined(OS_MACOSX)
+#include <vector>
+class GURL;
+#endif
+
struct MainFunctionParams;
class MetricsService;
@@ -26,6 +31,23 @@ void DidEndMainMessageLoop();
// are registered with the UMA metrics service.
void RecordBreakpadStatusUMA(MetricsService* metrics);
+#if defined(OS_MACOSX)
+// On Mac, files/URLs to open at startup aren't typically provided on the
+// command line, but rather by Launch Services via an Apple Event. We spin a UI
+// message loop early to catch this event in the app controller and store the
+// URLs.
+
+// Has the app controller been told that it is done? (I.e., has it received
+// |-applicationDidFinishLaunching:|?)
+bool IsStartupComplete();
+
+// The following functions retrieves the URLs and clears the list of URLs,
+// respectively.
+const std::vector<GURL>& GetStartupURLs();
+void ClearStartupURLs();
+
+#endif
+
} // namespace Platform
#endif // CHROME_BROWSER_BROWSER_MAIN_H_
diff --git a/chrome/browser/browser_main_mac.mm b/chrome/browser/browser_main_mac.mm
index f325713..85351db 100644
--- a/chrome/browser/browser_main_mac.mm
+++ b/chrome/browser/browser_main_mac.mm
@@ -62,6 +62,24 @@ void RecordBreakpadStatusUMA(MetricsService* metrics) {
metrics->RecordBreakpadHasDebugger(DebugUtil::BeingDebugged());
}
+bool IsStartupComplete() {
+ AppController* appController = [NSApp delegate];
+ DCHECK(appController);
+ return static_cast<bool>([appController startupComplete]);
+}
+
+const std::vector<GURL>& GetStartupURLs() {
+ AppController* appController = [NSApp delegate];
+ DCHECK(appController);
+ return [appController startupURLs];
+}
+
+void ClearStartupURLs() {
+ AppController* appController = [NSApp delegate];
+ DCHECK(appController);
+ [appController clearStartupURLs];
+}
+
} // namespace Platform
// From browser_main_win.h, stubs until we figure out the right thing...