Index: chrome/browser/component_updater/component_updater_resource_throttle.cc |
diff --git a/chrome/browser/component_updater/component_updater_resource_throttle.cc b/chrome/browser/component_updater/component_updater_resource_throttle.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2a38cf9c60fba1e3461caac9f0577c3192b85104 |
--- /dev/null |
+++ b/chrome/browser/component_updater/component_updater_resource_throttle.cc |
@@ -0,0 +1,108 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/component_updater/component_updater_resource_throttle.h" |
+ |
+#include "base/location.h" |
+#include "base/memory/weak_ptr.h" |
+#include "chrome/browser/component_updater/component_updater_service.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/resource_controller.h" |
+#include "content/public/browser/resource_throttle.h" |
+ |
+using content::BrowserThread; |
+ |
+namespace component_updater { |
+ |
+namespace { |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+// In charge of blocking url requests until the |crx_id| component has been |
+// updated. This class is touched solely from the IO thread. The UI thread |
+// can post tasks to it via weak pointers. By default the request is blocked |
+// unless the CrxUpdateService calls Unblock(). |
+// The lifetime is controlled by Chrome's resource loader so the component |
+// updater cannot touch objects from this class except via weak pointers. |
+class CUResourceThrottle : public content::ResourceThrottle, |
+ public base::SupportsWeakPtr<CUResourceThrottle> { |
+ public: |
+ CUResourceThrottle(); |
+ virtual ~CUResourceThrottle(); |
+ |
+ // Overriden from ResourceThrottle. |
+ virtual void WillStartRequest(bool* defer) OVERRIDE; |
+ virtual void WillRedirectRequest(const GURL& new_url, bool* defer) OVERRIDE; |
+ virtual const char* GetNameForLogging() const OVERRIDE; |
+ |
+ // Component updater calls this function via PostTask to unblock the request. |
+ void Unblock(); |
+ |
+ typedef std::vector<base::WeakPtr<CUResourceThrottle> > WeakPtrVector; |
+ |
+ private: |
+ enum State { NEW, BLOCKED, UNBLOCKED }; |
+ |
+ State state_; |
+}; |
+ |
+CUResourceThrottle::CUResourceThrottle() : state_(NEW) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+} |
+ |
+CUResourceThrottle::~CUResourceThrottle() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+} |
+ |
+void CUResourceThrottle::WillStartRequest(bool* defer) { |
+ if (state_ != UNBLOCKED) { |
+ state_ = BLOCKED; |
+ *defer = true; |
+ } else { |
+ *defer = false; |
+ } |
+} |
+ |
+void CUResourceThrottle::WillRedirectRequest(const GURL& new_url, bool* defer) { |
+ WillStartRequest(defer); |
+} |
+ |
+const char* CUResourceThrottle::GetNameForLogging() const { |
+ return "ComponentUpdateResourceThrottle"; |
+} |
+ |
+void CUResourceThrottle::Unblock() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ if (state_ == BLOCKED) |
+ controller()->Resume(); |
+ state_ = UNBLOCKED; |
+} |
+ |
+void UnblockThrottleOnUIThread(base::WeakPtr<CUResourceThrottle> rt) { |
+ BrowserThread::PostTask(BrowserThread::IO, |
+ FROM_HERE, |
+ base::Bind(&CUResourceThrottle::Unblock, rt)); |
+} |
+ |
+} // namespace |
+ |
+content::ResourceThrottle* GetOnDemandResourceThrottle( |
+ ComponentUpdateService* cus, |
+ const std::string& crx_id) { |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
+ // We give the raw pointer to the caller, who will delete it at will |
+ // and we keep for ourselves a weak pointer to it so we can post tasks |
+ // from the UI thread without having to track lifetime directly. |
+ CUResourceThrottle* rt = new CUResourceThrottle; |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&ComponentUpdateService::MaybeThrottle, |
+ base::Unretained(cus), |
+ crx_id, |
+ base::Bind(&UnblockThrottleOnUIThread, rt->AsWeakPtr()))); |
+ return rt; |
+} |
+ |
+} // namespace component_updater |