Index: chrome/browser/app_controller_mac.mm |
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm |
index 2e2dfe57e200c64a0cff295ef819aeefefa3b63b..604f21792fd79db9b9128f3b1c756f5e24e71f8c 100644 |
--- a/chrome/browser/app_controller_mac.mm |
+++ b/chrome/browser/app_controller_mac.mm |
@@ -63,6 +63,7 @@ |
#import "chrome/browser/ui/cocoa/confirm_quit.h" |
#import "chrome/browser/ui/cocoa/confirm_quit_panel_controller.h" |
#import "chrome/browser/ui/cocoa/encoding_menu_controller_delegate_mac.h" |
+#include "chrome/browser/ui/cocoa/handoff_active_url_observer_bridge.h" |
#import "chrome/browser/ui/cocoa/history_menu_bridge.h" |
#include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h" |
#import "chrome/browser/ui/cocoa/profiles/profile_menu_controller.h" |
@@ -83,6 +84,7 @@ |
#include "chrome/common/url_constants.h" |
#include "chrome/grit/chromium_strings.h" |
#include "chrome/grit/generated_resources.h" |
+#include "components/handoff/handoff_manager.h" |
#include "components/handoff/handoff_utility.h" |
#include "components/signin/core/browser/signin_manager.h" |
#include "components/signin/core/common/profile_management_switches.h" |
@@ -209,9 +211,10 @@ bool IsProfileSignedOut(Profile* profile) { |
return cache.ProfileIsSigninRequiredAtIndex(profile_index); |
} |
-} // anonymous namespace |
+} // namespace |
+ |
+@interface AppController () <HandoffActiveURLObserverBridgeDelegate> |
-@interface AppController (Private) |
- (void)initMenuState; |
- (void)initProfileMenu; |
- (void)updateConfirmToQuitPrefMenuItem:(NSMenuItem*)item; |
@@ -240,6 +243,25 @@ bool IsProfileSignedOut(Profile* profile) { |
// 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; |
+ |
+// Whether instances of this class should use the Handoff feature. |
+- (BOOL)shouldUseHandoff; |
+ |
+// This method passes |handoffURL| to |handoffManager_|. |
+- (void)passURLToHandoffManager:(const GURL&)handoffURL; |
+ |
+// Lazily creates the Handoff Manager. Updates the state of the Handoff |
+// Manager. This method is idempotent. This should be called: |
+// - During initialization. |
+// - When the current tab navigates to a new URL. |
+// - When the active browser changes. |
+// - When the active browser's active tab switches. |
+// |webContents| should be the new, active WebContents. |
+- (void)updateHandoffManager:(content::WebContents*)webContents; |
+ |
+// Given |webContents|, extracts a GURL to be used for Handoff. This may return |
+// the empty GURL. |
+- (GURL)handoffURLFromWebContents:(content::WebContents*)webContents; |
@end |
class AppControllerProfileObserver : public ProfileInfoCacheObserver { |
@@ -776,6 +798,12 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver { |
startupComplete_ = YES; |
+ Browser* browser = |
+ FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_NATIVE); |
+ content::WebContents* activeWebContents = nullptr; |
+ if (browser) |
+ activeWebContents = browser->tab_strip_model()->GetActiveWebContents(); |
+ [self updateHandoffManager:activeWebContents]; |
[self openStartupUrls]; |
PrefService* localState = g_browser_process->local_state(); |
@@ -786,6 +814,9 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver { |
base::Bind(&chrome::BrowserCommandController::UpdateOpenFileState, |
menuState_.get())); |
} |
+ |
+ handoff_active_url_observer_bridge_.reset( |
+ new HandoffActiveURLObserverBridge(self)); |
} |
// This is called after profiles have been loaded and preferences registered. |
@@ -1638,6 +1669,53 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver { |
error:(NSError*)error { |
} |
+#pragma mark - Handoff Manager |
+ |
+- (BOOL)shouldUseHandoff { |
+ return base::mac::IsOSYosemiteOrLater(); |
+} |
+ |
+- (void)passURLToHandoffManager:(const GURL&)handoffURL { |
+ [handoffManager_ updateActiveURL:handoffURL]; |
+} |
+ |
+- (void)updateHandoffManager:(content::WebContents*)webContents { |
+ if (![self shouldUseHandoff]) |
+ return; |
+ |
+ if (!handoffManager_) |
+ handoffManager_.reset([[HandoffManager alloc] init]); |
+ |
+ GURL handoffURL = [self handoffURLFromWebContents:webContents]; |
+ [self passURLToHandoffManager:handoffURL]; |
+} |
+ |
+- (GURL)handoffURLFromWebContents:(content::WebContents*)webContents { |
+ if (!webContents) |
+ return GURL(); |
+ |
+ Profile* profile = |
+ Profile::FromBrowserContext(webContents->GetBrowserContext()); |
+ if (!profile) |
+ return GURL(); |
+ |
+ // Handoff is not allowed from an incognito profile. To err on the safe side, |
+ // also disallow Handoff from a guest profile. |
+ if (profile->GetProfileType() != Profile::REGULAR_PROFILE) |
+ return GURL(); |
+ |
+ if (!webContents) |
+ return GURL(); |
+ |
+ return webContents->GetVisibleURL(); |
+} |
+ |
+#pragma mark - HandoffActiveURLObserverBridgeDelegate |
+ |
+- (void)handoffActiveURLChanged:(content::WebContents*)webContents { |
+ [self updateHandoffManager:webContents]; |
+} |
+ |
@end // @implementation AppController |
//--------------------------------------------------------------------------- |