Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / app_controller_mac.mm
index 6435203..3a433d7 100644 (file)
@@ -12,6 +12,7 @@
 #include "base/mac/mac_util.h"
 #include "base/mac/sdk_forward_declarations.h"
 #include "base/message_loop/message_loop.h"
+#include "base/metrics/histogram.h"
 #include "base/prefs/pref_service.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/sys_string_conversions.h"
@@ -30,6 +31,7 @@
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/first_run/first_run.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/mac/handoff_utility.h"
 #include "chrome/browser/mac/mac_startup_profiler.h"
 #include "chrome/browser/profiles/profile_info_cache_observer.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -213,7 +215,6 @@ bool IsProfileSignedOut(Profile* profile) {
 - (void)updateConfirmToQuitPrefMenuItem:(NSMenuItem*)item;
 - (void)updateDisplayMessageCenterPrefMenuItem:(NSMenuItem*)item;
 - (void)registerServicesMenuTypesTo:(NSApplication*)app;
-- (void)openUrls:(const std::vector<GURL>&)urls;
 - (void)getUrl:(NSAppleEventDescriptor*)event
      withReply:(NSAppleEventDescriptor*)reply;
 - (void)windowLayeringDidChange:(NSNotification*)inNotification;
@@ -223,6 +224,20 @@ bool IsProfileSignedOut(Profile* profile) {
 - (BOOL)shouldQuitWithInProgressDownloads;
 - (void)executeApplication:(id)sender;
 - (void)profileWasRemoved:(const base::FilePath&)profilePath;
+
+// Opens a tab for each GURL in |urls|.
+- (void)openUrls:(const std::vector<GURL>&)urls;
+
+// This class cannot open urls until startup has finished. The urls that cannot
+// be opened are cached in |startupUrls_|. This method must be called exactly
+// once after startup has completed. It opens the urls in |startupUrls_|, and
+// clears |startupUrls_|.
+- (void)openStartupUrls;
+
+// Opens a tab for each GURL in |urls|. If there is exactly one tab open before
+// this method is called, and that tab is the NTP, then this method closes the
+// NTP after all the |urls| have been opened.
+- (void)openUrlsReplacingNTP:(const std::vector<GURL>&)urls;
 @end
 
 class AppControllerProfileObserver : public ProfileInfoCacheObserver {
@@ -236,7 +251,7 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
     profile_manager_->GetProfileInfoCache().AddObserver(this);
   }
 
-  virtual ~AppControllerProfileObserver() {
+  ~AppControllerProfileObserver() override {
     DCHECK(profile_manager_);
     profile_manager_->GetProfileInfoCache().RemoveObserver(this);
   }
@@ -244,29 +259,21 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
  private:
   // ProfileInfoCacheObserver implementation:
 
-  virtual void OnProfileAdded(const base::FilePath& profile_path) OVERRIDE {
-  }
+  void OnProfileAdded(const base::FilePath& profile_path) override {}
 
-  virtual void OnProfileWasRemoved(
-      const base::FilePath& profile_path,
-      const base::string16& profile_name) OVERRIDE {
+  void OnProfileWasRemoved(const base::FilePath& profile_path,
+                           const base::string16& profile_name) override {
     // When a profile is deleted we need to notify the AppController,
     // so it can correctly update its pointer to the last used profile.
     [app_controller_ profileWasRemoved:profile_path];
   }
 
-  virtual void OnProfileWillBeRemoved(
-      const base::FilePath& profile_path) OVERRIDE {
-  }
+  void OnProfileWillBeRemoved(const base::FilePath& profile_path) override {}
 
-  virtual void OnProfileNameChanged(
-      const base::FilePath& profile_path,
-      const base::string16& old_profile_name) OVERRIDE {
-  }
+  void OnProfileNameChanged(const base::FilePath& profile_path,
+                            const base::string16& old_profile_name) override {}
 
-  virtual void OnProfileAvatarChanged(
-      const base::FilePath& profile_path) OVERRIDE {
-  }
+  void OnProfileAvatarChanged(const base::FilePath& profile_path) override {}
 
   ProfileManager* profile_manager_;
 
@@ -668,6 +675,15 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
 }
 
 - (void)openStartupUrls {
+  DCHECK(startupComplete_);
+  [self openUrlsReplacingNTP:startupUrls_];
+  startupUrls_.clear();
+}
+
+- (void)openUrlsReplacingNTP:(const std::vector<GURL>&)urls {
+  if (urls.empty())
+    return;
+
   // On Mac, the URLs are passed in via Cocoa, not command line. The Chrome
   // NSApplication is created in MainMessageLoop, and then the shortcut urls
   // are passed in via Apple events. At this point, the first browser is
@@ -675,8 +691,12 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
   // before PreMainMessageLoop to capture shortcut URL events, it may cause
   // more problems because it relies on things created in PreMainMessageLoop
   // and may break existing message loop design.
-  if (startupUrls_.empty())
+
+  // If the browser hasn't started yet, just queue up the URLs.
+  if (!startupComplete_) {
+    startupUrls_.insert(startupUrls_.end(), urls.begin(), urls.end());
     return;
+  }
 
   // If there's only 1 tab and the tab is NTP, close this NTP tab and open all
   // startup urls in new tabs, because the omnibox will stay focused if we
@@ -690,10 +710,7 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
     startupContent = browser->tab_strip_model()->GetActiveWebContents();
   }
 
-  if (startupUrls_.size()) {
-    [self openUrls:startupUrls_];
-    startupUrls_.clear();
-  }
+  [self openUrls:urls];
 
   if (startupIndex != TabStripModel::kNoTab &&
       startupContent->GetVisibleURL() == GURL(chrome::kChromeUINewTabURL)) {
@@ -1007,7 +1024,7 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
   // for a locked profile, we have to show the User Manager instead as the
   // locked profile needs authentication.
   if (IsProfileSignedOut(lastProfile)) {
-    UserManager::Show(lastProfile->GetPath(),
+    UserManager::Show(base::FilePath(),
                       profiles::USER_MANAGER_NO_TUTORIAL,
                       profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
     return;
@@ -1102,8 +1119,7 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
       }
       break;
     case IDC_TASK_MANAGER:
-      content::RecordAction(UserMetricsAction("TaskManager"));
-      TaskManagerMac::Show();
+      chrome::OpenTaskManager(NULL);
       break;
     case IDC_OPTIONS:
       [self showPreferences:sender];
@@ -1211,7 +1227,7 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
   // so we have to show the User Manager as well.
   Profile* lastProfile = [self lastProfile];
   if (lastProfile->IsGuestSession() || IsProfileSignedOut(lastProfile)) {
-    UserManager::Show(lastProfile->GetPath(),
+    UserManager::Show(base::FilePath(),
                       profiles::USER_MANAGER_NO_TUTORIAL,
                       profiles::USER_MANAGER_SELECT_PROFILE_NO_ACTION);
   } else {
@@ -1319,13 +1335,20 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
   return profile;
 }
 
+// Returns true if a browser window may be opened for the last active profile.
+- (bool)canOpenNewBrowser {
+  Profile* profile = [self safeLastProfileForNewWindows];
+
+  const PrefService* prefs = g_browser_process->local_state();
+  return !profile->IsGuestSession() ||
+         prefs->GetBoolean(prefs::kBrowserGuestModeEnabled);
+}
+
 // Various methods to open URLs that we get in a native fashion. We use
 // StartupBrowserCreator here because on the other platforms, URLs to open come
 // through the ProcessSingleton, and it calls StartupBrowserCreator. It's best
 // to bottleneck the openings through that for uniform handling.
-
 - (void)openUrls:(const std::vector<GURL>&)urls {
-  // If the browser hasn't started yet, just queue up the URLs.
   if (!startupComplete_) {
     startupUrls_.insert(startupUrls_.end(), urls.begin(), urls.end());
     return;
@@ -1355,7 +1378,7 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
   std::vector<GURL> gurlVector;
   gurlVector.push_back(gurl);
 
-  [self openUrls:gurlVector];
+  [self openUrlsReplacingNTP:gurlVector];
 }
 
 - (void)application:(NSApplication*)sender
@@ -1367,7 +1390,7 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
     gurlVector.push_back(gurl);
   }
   if (!gurlVector.empty())
-    [self openUrls:gurlVector];
+    [self openUrlsReplacingNTP:gurlVector];
   else
     NOTREACHED() << "Nothing to open!";
 
@@ -1380,18 +1403,28 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
   if (Browser* browser = ActivateBrowser([self lastProfile])) {
     // Show options tab in the active browser window.
     chrome::ShowSettings(browser);
-  } else {
+  } else if ([self canOpenNewBrowser]) {
     // No browser window, so create one for the options tab.
     chrome::OpenOptionsWindow([self safeLastProfileForNewWindows]);
+  } else {
+    // No way to create a browser, default to the User Manager.
+    UserManager::Show(base::FilePath(),
+                      profiles::USER_MANAGER_NO_TUTORIAL,
+                      profiles::USER_MANAGER_SELECT_PROFILE_CHROME_SETTINGS);
   }
 }
 
 - (IBAction)orderFrontStandardAboutPanel:(id)sender {
   if (Browser* browser = ActivateBrowser([self lastProfile])) {
     chrome::ShowAboutChrome(browser);
-  } else {
-    // No browser window, so create one for the about tab.
+  } else if ([self canOpenNewBrowser]) {
+    // No browser window, so create one for the options tab.
     chrome::OpenAboutWindow([self safeLastProfileForNewWindows]);
+  } else {
+    // No way to create a browser, default to the User Manager.
+    UserManager::Show(base::FilePath(),
+                      profiles::USER_MANAGER_NO_TUTORIAL,
+                      profiles::USER_MANAGER_SELECT_PROFILE_ABOUT_CHROME);
   }
 }
 
@@ -1559,6 +1592,12 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
     return NO;
   }
 
+  NSString* originString = base::mac::ObjCCast<NSString>(
+      [userActivity.userInfo objectForKey:handoff::kOriginKey]);
+  handoff::Origin origin = handoff::OriginFromString(originString);
+  UMA_HISTOGRAM_ENUMERATION(
+      "OSX.Handoff.Origin", origin, handoff::ORIGIN_COUNT);
+
   NSURL* url = userActivity.webPageURL;
   if (!url)
     return NO;
@@ -1567,7 +1606,7 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
   std::vector<GURL> gurlVector;
   gurlVector.push_back(gurl);
 
-  [self openUrls:gurlVector];
+  [self openUrlsReplacingNTP:gurlVector];
   return YES;
 }