1 // Copyright 2014 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.
5 #include "chrome/browser/component_updater/component_updater_resource_throttle.h"
7 #include "base/location.h"
8 #include "base/memory/weak_ptr.h"
9 #include "components/component_updater/component_updater_service.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/resource_controller.h"
12 #include "content/public/browser/resource_throttle.h"
14 using content::BrowserThread
;
16 namespace component_updater
{
20 ///////////////////////////////////////////////////////////////////////////////
21 // In charge of blocking url requests until the |crx_id| component has been
22 // updated. This class is touched solely from the IO thread. The UI thread
23 // can post tasks to it via weak pointers. By default the request is blocked
24 // unless the CrxUpdateService calls Unblock().
25 // The lifetime is controlled by Chrome's resource loader so the component
26 // updater cannot touch objects from this class except via weak pointers.
27 class CUResourceThrottle
: public content::ResourceThrottle
,
28 public base::SupportsWeakPtr
<CUResourceThrottle
> {
31 ~CUResourceThrottle() override
;
33 // Overriden from ResourceThrottle.
34 void WillStartRequest(bool* defer
) override
;
35 void WillRedirectRequest(const net::RedirectInfo
& redirect_info
,
36 bool* defer
) override
;
37 const char* GetNameForLogging() const override
;
39 // Component updater calls this function via PostTask to unblock the request.
42 typedef std::vector
<base::WeakPtr
<CUResourceThrottle
> > WeakPtrVector
;
45 enum State
{ NEW
, BLOCKED
, UNBLOCKED
};
50 CUResourceThrottle::CUResourceThrottle() : state_(NEW
) {
51 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
54 CUResourceThrottle::~CUResourceThrottle() {
55 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
58 void CUResourceThrottle::WillStartRequest(bool* defer
) {
59 if (state_
!= UNBLOCKED
) {
67 void CUResourceThrottle::WillRedirectRequest(
68 const net::RedirectInfo
& redirect_info
, bool* defer
) {
69 WillStartRequest(defer
);
72 const char* CUResourceThrottle::GetNameForLogging() const {
73 return "ComponentUpdateResourceThrottle";
76 void CUResourceThrottle::Unblock() {
77 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
78 if (state_
== BLOCKED
)
79 controller()->Resume();
83 void UnblockThrottleOnUIThread(base::WeakPtr
<CUResourceThrottle
> rt
) {
84 BrowserThread::PostTask(BrowserThread::IO
,
86 base::Bind(&CUResourceThrottle::Unblock
, rt
));
91 content::ResourceThrottle
* GetOnDemandResourceThrottle(
92 ComponentUpdateService
* cus
,
93 const std::string
& crx_id
) {
94 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
96 // We give the raw pointer to the caller, who will delete it at will
97 // and we keep for ourselves a weak pointer to it so we can post tasks
98 // from the UI thread without having to track lifetime directly.
99 CUResourceThrottle
* rt
= new CUResourceThrottle
;
100 BrowserThread::PostTask(
103 base::Bind(&ComponentUpdateService::MaybeThrottle
,
104 base::Unretained(cus
),
106 base::Bind(&UnblockThrottleOnUIThread
, rt
->AsWeakPtr())));
110 } // namespace component_updater