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 26using content::BrowserThread; 27using content::RenderViewHost; 28using content::WebContents; 29 30namespace { 31 32void 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 59MergeSessionThrottle::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 67MergeSessionThrottle::~MergeSessionThrottle() { 68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 69} 70 71void 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 90void MergeSessionThrottle::OnBlockingPageComplete() { 91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 92 controller()->Resume(); 93} 94 95bool 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