1 // Copyright (c) 2013 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/merge_session_throttle.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 #include "base/memory/singleton.h" 10 #include "base/metrics/histogram.h" 11 #include "base/strings/string_util.h" 12 #include "chrome/browser/chromeos/login/login_utils.h" 13 #include "chrome/browser/google/google_util.h" 14 #include "chrome/browser/net/chrome_url_request_context.h" 15 #include "chrome/common/url_constants.h" 16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/render_view_host.h" 18 #include "content/public/browser/resource_controller.h" 19 #include "content/public/browser/web_contents.h" 20 #include "net/base/net_errors.h" 21 #include "net/base/net_util.h" 22 #include "net/base/network_change_notifier.h" 23 #include "net/url_request/url_request.h" 24 #include "net/url_request/url_request_context.h" 25 26 using content::BrowserThread; 27 using content::RenderViewHost; 28 using content::WebContents; 29 30 namespace { 31 32 void ShowDeleayedLoadingPage( 33 int render_process_id, 34 int render_view_id, 35 const GURL& url, 36 const chromeos::MergeSessionLoadPage::CompletionCallback& callback) { 37 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 38 39 // Check again on UI thread and proceed if it's connected. 40 if (chromeos::UserManager::Get()->GetMergeSessionState() != 41 chromeos::UserManager::MERGE_STATUS_IN_PROCESS) { 42 BrowserThread::PostTask( 43 BrowserThread::IO, FROM_HERE, callback); 44 } else { 45 RenderViewHost* render_view_host = 46 RenderViewHost::FromID(render_process_id, render_view_id); 47 WebContents* web_contents = render_view_host ? 48 WebContents::FromRenderViewHost(render_view_host) : NULL; 49 // There is a chance that the tab closed after we decided to show 50 // the offline page on the IO thread and before we actually show the 51 // offline page here on the UI thread. 52 if (web_contents) 53 (new chromeos::MergeSessionLoadPage(web_contents, url, callback))->Show(); 54 } 55 } 56 57 } // namespace 58 59 MergeSessionThrottle::MergeSessionThrottle(int render_process_id, 60 int render_view_id, 61 net::URLRequest* request) 62 : render_process_id_(render_process_id), 63 render_view_id_(render_view_id), 64 request_(request) { 65 } 66 67 MergeSessionThrottle::~MergeSessionThrottle() { 68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 69 } 70 71 void MergeSessionThrottle::WillStartRequest(bool* defer) { 72 if (!ShouldShowMergeSessionPage(request_->url())) 73 return; 74 75 DVLOG(1) << "WillStartRequest: url=" << request_->url(); 76 BrowserThread::PostTask( 77 BrowserThread::UI, 78 FROM_HERE, 79 base::Bind( 80 &ShowDeleayedLoadingPage, 81 render_process_id_, 82 render_view_id_, 83 request_->url(), 84 base::Bind( 85 &MergeSessionThrottle::OnBlockingPageComplete, 86 AsWeakPtr()))); 87 *defer = true; 88 } 89 90 void MergeSessionThrottle::OnBlockingPageComplete() { 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 92 controller()->Resume(); 93 } 94 95 bool MergeSessionThrottle::ShouldShowMergeSessionPage(const GURL& url) const { 96 // If we are loading google properties while merge session is in progress, 97 // we will show delayed loading page instead. 98 return !net::NetworkChangeNotifier::IsOffline() && 99 chromeos::UserManager::Get()->GetMergeSessionState() == 100 chromeos::UserManager::MERGE_STATUS_IN_PROCESS && 101 google_util::IsGoogleHostname(url.host(), 102 google_util::ALLOW_SUBDOMAIN); 103 } 104