Index: content/browser/renderer_host/media/web_contents_capture_util.cc |
diff --git a/content/browser/renderer_host/media/web_contents_capture_util.cc b/content/browser/renderer_host/media/web_contents_capture_util.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..40732d376abf13426a27d56f7229eeeef9eab55a |
--- /dev/null |
+++ b/content/browser/renderer_host/media/web_contents_capture_util.cc |
@@ -0,0 +1,115 @@ |
+// Copyright (c) 2012 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 "content/browser/renderer_host/media/web_contents_capture_util.h" |
+ |
+#include "base/basictypes.h" |
+#include "base/string_number_conversions.h" |
+#include "base/string_piece.h" |
+#include "base/string_util.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "content/public/browser/render_process_host.h" |
+#include "content/public/browser/render_view_host.h" |
+#include "content/public/browser/web_contents.h" |
+ |
+namespace { |
+ |
+const char kVirtualDeviceScheme[] = "virtual://"; |
+ |
+} // namespace |
+ |
+namespace content { |
+ |
+// static |
+bool WebContentsCaptureUtil::ExtractTabCaptureTarget( |
+ const std::string& device_id_param, |
+ int* render_process_id, |
+ int* render_view_id) { |
+ const std::string device_id = device_id_param.substr( |
+ arraysize(kVirtualDeviceScheme) - 1, device_id_param.length()); |
+ |
+ const size_t sep_pos = device_id.find(':'); |
+ if (sep_pos == std::string::npos) |
+ return false; |
+ |
+ const base::StringPiece component1(device_id.data(), sep_pos); |
+ const base::StringPiece component2(device_id.data() + sep_pos + 1, |
+ device_id.length() - sep_pos - 1); |
+ |
+ return (base::StringToInt(component1, render_process_id) && |
+ base::StringToInt(component2, render_view_id)); |
+} |
+ |
+WebContentsCaptureUtil::RenderViewTracker::RenderViewTracker() {} |
+ |
+WebContentsCaptureUtil::RenderViewTracker::~RenderViewTracker() { |
+ DCHECK(!web_contents()) << "BUG: Still observering!"; |
+} |
+ |
+void WebContentsCaptureUtil::RenderViewTracker::Start( |
+ int render_process_id, int render_view_id, |
+ const ChangeCallback& callback) { |
+ { |
Alpha Left Google
2012/11/26 22:59:59
I still think this can be done without a lock:
St
miu
2012/11/28 05:05:01
Actually, that's not guaranteed. The reason is be
|
+ base::AutoLock guard(lock_); |
+ callback_ = callback; |
+ } |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&RenderViewTracker::LookUpAndObserveWebContents, this, |
Alpha Left Google
2012/11/26 22:59:59
Use BindToLoop here such that LookUpAndObserveWebC
|
+ render_process_id, render_view_id)); |
+} |
+ |
+void WebContentsCaptureUtil::RenderViewTracker::Stop() { |
+ { |
+ base::AutoLock guard(lock_); |
+ callback_.Reset(); |
+ } |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&RenderViewTracker::Observe, this, |
+ static_cast<WebContents*>(NULL))); |
+} |
+ |
+void WebContentsCaptureUtil::RenderViewTracker::OnWebContentsChangeEvent() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ WebContents* const wc = web_contents(); |
+ RenderViewHost* const rvh = wc ? wc->GetRenderViewHost() : NULL; |
+ RenderProcessHost* const rph = rvh ? rvh->GetProcess() : NULL; |
+ |
+ const int render_process_id = rph ? rph->GetID() : MSG_ROUTING_NONE; |
+ const int render_view_id = rvh ? rvh->GetRoutingID() : MSG_ROUTING_NONE; |
+ |
+ base::AutoLock guard(lock_); |
+ if (!callback_.is_null()) { |
+ callback_.Run(render_process_id, render_view_id); |
Alpha Left Google
2012/11/26 22:59:59
If you access |callback| only on IO thread you don
|
+ } |
+} |
+ |
+void WebContentsCaptureUtil::RenderViewTracker::LookUpAndObserveWebContents( |
+ int render_process_id, int render_view_id) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ RenderViewHost* const rvh = |
+ RenderViewHost::FromID(render_process_id, render_view_id); |
+ DVLOG_IF(1, !rvh) << "RenderViewHost::FromID(" |
+ << render_process_id << ", " << render_view_id |
+ << ") returned NULL."; |
+ Observe(rvh ? WebContents::FromRenderViewHost(rvh) : NULL); |
+ DVLOG_IF(1, !web_contents()) |
+ << "WebContents::FromRenderViewHost(" << rvh << ") returned NULL."; |
+ |
+ OnWebContentsChangeEvent(); |
+} |
+ |
+void WebContentsCaptureUtil::RenderViewTracker::RenderViewReady() { |
+ OnWebContentsChangeEvent(); |
+} |
+ |
+void WebContentsCaptureUtil::RenderViewTracker::WebContentsDestroyed( |
+ WebContents* web_contents) { |
+ OnWebContentsChangeEvent(); |
+} |
+ |
+} // namespace content |