1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/chromeos/login/signin/merge_session_navigation_throttle.h"
6 
7 #include "base/time/time.h"
8 #include "chrome/browser/chromeos/login/signin/merge_session_throttling_utils.h"
9 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/navigation_handle.h"
12 #include "content/public/browser/web_contents.h"
13 
14 namespace {
15 
16 // Maximum wait time for merge session process.
17 constexpr base::TimeDelta kTotalWaitTime = base::TimeDelta::FromSeconds(10);
18 
GetOAuth2LoginManager(content::WebContents * web_contents)19 chromeos::OAuth2LoginManager* GetOAuth2LoginManager(
20     content::WebContents* web_contents) {
21   content::BrowserContext* browser_context = web_contents->GetBrowserContext();
22   if (!browser_context)
23     return nullptr;
24 
25   Profile* profile = Profile::FromBrowserContext(browser_context);
26   if (!profile)
27     return nullptr;
28 
29   return chromeos::OAuth2LoginManagerFactory::GetInstance()->GetForProfile(
30       profile);
31 }
32 }  // namespace
33 
34 // static
35 std::unique_ptr<content::NavigationThrottle>
Create(content::NavigationHandle * handle)36 MergeSessionNavigationThrottle::Create(content::NavigationHandle* handle) {
37   return std::unique_ptr<content::NavigationThrottle>(
38       new MergeSessionNavigationThrottle(handle));
39 }
40 
MergeSessionNavigationThrottle(content::NavigationHandle * handle)41 MergeSessionNavigationThrottle::MergeSessionNavigationThrottle(
42     content::NavigationHandle* handle)
43     : NavigationThrottle(handle), login_manager_observer_(this) {
44   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
45 }
46 
~MergeSessionNavigationThrottle()47 MergeSessionNavigationThrottle::~MergeSessionNavigationThrottle() {
48   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
49 }
50 
51 content::NavigationThrottle::ThrottleCheckResult
WillStartRequest()52 MergeSessionNavigationThrottle::WillStartRequest() {
53   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
54   if (!merge_session_throttling_utils::ShouldDelayUrl(
55           navigation_handle()->GetURL()) ||
56       !merge_session_throttling_utils::ShouldDelayRequestForWebContents(
57           navigation_handle()->GetWebContents())) {
58     return content::NavigationThrottle::PROCEED;
59   }
60 
61   if (BeforeDefer())
62     return content::NavigationThrottle::DEFER;
63 
64   return content::NavigationThrottle::PROCEED;
65 }
66 
67 content::NavigationThrottle::ThrottleCheckResult
WillRedirectRequest()68 MergeSessionNavigationThrottle::WillRedirectRequest() {
69   return WillStartRequest();
70 }
71 
GetNameForLogging()72 const char* MergeSessionNavigationThrottle::GetNameForLogging() {
73   return "MergeSessionNavigationThrottle";
74 }
75 
OnSessionRestoreStateChanged(Profile * user_profile,chromeos::OAuth2LoginManager::SessionRestoreState state)76 void MergeSessionNavigationThrottle::OnSessionRestoreStateChanged(
77     Profile* user_profile,
78     chromeos::OAuth2LoginManager::SessionRestoreState state) {
79   chromeos::OAuth2LoginManager* manager =
80       GetOAuth2LoginManager(navigation_handle()->GetWebContents());
81   if (!manager->ShouldBlockTabLoading()) {
82     Proceed();
83   }
84 }
85 
BeforeDefer()86 bool MergeSessionNavigationThrottle::BeforeDefer() {
87   chromeos::OAuth2LoginManager* manager =
88       GetOAuth2LoginManager(navigation_handle()->GetWebContents());
89   if (manager && manager->ShouldBlockTabLoading()) {
90     login_manager_observer_.Add(manager);
91     proceed_timer_.Start(FROM_HERE, kTotalWaitTime, this,
92                          &MergeSessionNavigationThrottle::Proceed);
93     return true;
94   }
95   return false;
96 }
97 
Proceed()98 void MergeSessionNavigationThrottle::Proceed() {
99   proceed_timer_.Stop();
100   chromeos::OAuth2LoginManager* manager =
101       GetOAuth2LoginManager(navigation_handle()->GetWebContents());
102   if (manager) {
103     login_manager_observer_.Remove(manager);
104   }
105   Resume();
106 }
107