16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file. 46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/component_updater/component_updater_resource_throttle.h" 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/location.h" 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "base/memory/weak_ptr.h" 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/component_updater/component_updater_service.h" 106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/resource_controller.h" 126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/resource_throttle.h" 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)using content::BrowserThread; 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace component_updater { 176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)namespace { 196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// In charge of blocking url requests until the |crx_id| component has been 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// updated. This class is touched solely from the IO thread. The UI thread 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// can post tasks to it via weak pointers. By default the request is blocked 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// unless the CrxUpdateService calls Unblock(). 256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// The lifetime is controlled by Chrome's resource loader so the component 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// updater cannot touch objects from this class except via weak pointers. 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class CUResourceThrottle : public content::ResourceThrottle, 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) public base::SupportsWeakPtr<CUResourceThrottle> { 296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) public: 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CUResourceThrottle(); 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual ~CUResourceThrottle(); 326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Overriden from ResourceThrottle. 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void WillStartRequest(bool* defer) OVERRIDE; 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE; 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual const char* GetNameForLogging() const OVERRIDE; 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Component updater calls this function via PostTask to unblock the request. 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void Unblock(); 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) typedef std::vector<base::WeakPtr<CUResourceThrottle> > WeakPtrVector; 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) private: 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) enum State { NEW, BLOCKED, UNBLOCKED }; 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) State state_; 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}; 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)CUResourceThrottle::CUResourceThrottle() : state_(NEW) { 506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)CUResourceThrottle::~CUResourceThrottle() { 546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void CUResourceThrottle::WillStartRequest(bool* defer) { 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (state_ != UNBLOCKED) { 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) state_ = BLOCKED; 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *defer = true; 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else { 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *defer = false; 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void CUResourceThrottle::WillRedirectRequest(const GURL& new_url, bool* defer) { 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) WillStartRequest(defer); 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char* CUResourceThrottle::GetNameForLogging() const { 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return "ComponentUpdateResourceThrottle"; 726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void CUResourceThrottle::Unblock() { 756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (state_ == BLOCKED) 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) controller()->Resume(); 786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) state_ = UNBLOCKED; 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void UnblockThrottleOnUIThread(base::WeakPtr<CUResourceThrottle> rt) { 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::IO, 836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FROM_HERE, 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&CUResourceThrottle::Unblock, rt)); 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} // namespace 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)content::ResourceThrottle* GetOnDemandResourceThrottle( 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ComponentUpdateService* cus, 916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const std::string& crx_id) { 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK_CURRENTLY_ON(BrowserThread::IO); 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // We give the raw pointer to the caller, who will delete it at will 956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // and we keep for ourselves a weak pointer to it so we can post tasks 966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // from the UI thread without having to track lifetime directly. 976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) CUResourceThrottle* rt = new CUResourceThrottle; 986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BrowserThread::PostTask( 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BrowserThread::UI, 1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FROM_HERE, 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&ComponentUpdateService::MaybeThrottle, 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Unretained(cus), 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) crx_id, 1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Bind(&UnblockThrottleOnUIThread, rt->AsWeakPtr()))); 1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return rt; 1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} // namespace component_updater 109