OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/media/web_contents_capture_util.h" | 5 #include "content/browser/renderer_host/media/web_contents_capture_util.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/message_loop_proxy.h" |
8 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
9 #include "base/string_piece.h" | 10 #include "base/string_piece.h" |
10 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "content/public/browser/browser_thread.h" |
| 13 #include "content/public/browser/render_process_host.h" |
| 14 #include "content/public/browser/render_view_host.h" |
| 15 #include "content/public/browser/web_contents.h" |
| 16 |
| 17 namespace content { |
11 | 18 |
12 namespace { | 19 namespace { |
13 | 20 |
14 const char kVirtualDeviceScheme[] = "virtual-media-stream://"; | 21 const char kVirtualDeviceScheme[] = "virtual-media-stream://"; |
15 | 22 |
16 } // namespace | 23 } // namespace |
17 | 24 |
18 namespace content { | 25 // static |
19 | |
20 std::string WebContentsCaptureUtil::AppendWebContentsDeviceScheme( | 26 std::string WebContentsCaptureUtil::AppendWebContentsDeviceScheme( |
21 const std::string& device_id) { | 27 const std::string& device_id) { |
22 return kVirtualDeviceScheme + device_id; | 28 return kVirtualDeviceScheme + device_id; |
23 } | 29 } |
24 | 30 |
| 31 // static |
25 std::string WebContentsCaptureUtil::StripWebContentsDeviceScheme( | 32 std::string WebContentsCaptureUtil::StripWebContentsDeviceScheme( |
26 const std::string& device_id) { | 33 const std::string& device_id) { |
27 return (IsWebContentsDeviceId(device_id) ? | 34 return (IsWebContentsDeviceId(device_id) ? |
28 device_id.substr(arraysize(kVirtualDeviceScheme) - 1) : | 35 device_id.substr(arraysize(kVirtualDeviceScheme) - 1) : |
29 device_id); | 36 device_id); |
30 } | 37 } |
31 | 38 |
| 39 // static |
32 bool WebContentsCaptureUtil::IsWebContentsDeviceId( | 40 bool WebContentsCaptureUtil::IsWebContentsDeviceId( |
33 const std::string& device_id) { | 41 const std::string& device_id) { |
34 return StartsWithASCII(device_id, kVirtualDeviceScheme, true); | 42 return StartsWithASCII(device_id, kVirtualDeviceScheme, true); |
35 } | 43 } |
36 | 44 |
| 45 // static |
37 bool WebContentsCaptureUtil::ExtractTabCaptureTarget( | 46 bool WebContentsCaptureUtil::ExtractTabCaptureTarget( |
38 const std::string& device_id_param, | 47 const std::string& device_id_param, |
39 int* render_process_id, | 48 int* render_process_id, |
40 int* render_view_id) { | 49 int* render_view_id) { |
41 if (!IsWebContentsDeviceId(device_id_param)) | 50 if (!IsWebContentsDeviceId(device_id_param)) |
42 return false; | 51 return false; |
43 | 52 |
44 const std::string device_id = device_id_param.substr( | 53 const std::string device_id = device_id_param.substr( |
45 arraysize(kVirtualDeviceScheme) - 1); | 54 arraysize(kVirtualDeviceScheme) - 1); |
46 | 55 |
47 const size_t sep_pos = device_id.find(':'); | 56 const size_t sep_pos = device_id.find(':'); |
48 if (sep_pos == std::string::npos) | 57 if (sep_pos == std::string::npos) |
49 return false; | 58 return false; |
50 | 59 |
51 const base::StringPiece component1(device_id.data(), sep_pos); | 60 const base::StringPiece component1(device_id.data(), sep_pos); |
52 const base::StringPiece component2(device_id.data() + sep_pos + 1, | 61 const base::StringPiece component2(device_id.data() + sep_pos + 1, |
53 device_id.length() - sep_pos - 1); | 62 device_id.length() - sep_pos - 1); |
54 | 63 |
55 return (base::StringToInt(component1, render_process_id) && | 64 return (base::StringToInt(component1, render_process_id) && |
56 base::StringToInt(component2, render_view_id)); | 65 base::StringToInt(component2, render_view_id)); |
57 } | 66 } |
58 | 67 |
| 68 WebContentsTracker::WebContentsTracker() {} |
| 69 |
| 70 WebContentsTracker::~WebContentsTracker() { |
| 71 DCHECK(!web_contents()) << "BUG: Still observering!"; |
| 72 } |
| 73 |
| 74 void WebContentsTracker::Start(int render_process_id, int render_view_id, |
| 75 const ChangeCallback& callback) { |
| 76 DCHECK(!message_loop_ || message_loop_->BelongsToCurrentThread()); |
| 77 |
| 78 message_loop_ = base::MessageLoopProxy::current(); |
| 79 DCHECK(message_loop_); |
| 80 callback_ = callback; |
| 81 |
| 82 BrowserThread::PostTask( |
| 83 BrowserThread::UI, FROM_HERE, |
| 84 base::Bind(&WebContentsTracker::LookUpAndObserveWebContents, this, |
| 85 render_process_id, render_view_id)); |
| 86 } |
| 87 |
| 88 void WebContentsTracker::Stop() { |
| 89 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 90 |
| 91 callback_.Reset(); |
| 92 |
| 93 BrowserThread::PostTask( |
| 94 BrowserThread::UI, FROM_HERE, |
| 95 base::Bind(&WebContentsTracker::Observe, this, |
| 96 static_cast<WebContents*>(NULL))); |
| 97 } |
| 98 |
| 99 void WebContentsTracker::OnWebContentsChangeEvent() { |
| 100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 101 |
| 102 WebContents* const wc = web_contents(); |
| 103 RenderViewHost* const rvh = wc ? wc->GetRenderViewHost() : NULL; |
| 104 RenderProcessHost* const rph = rvh ? rvh->GetProcess() : NULL; |
| 105 |
| 106 const int render_process_id = rph ? rph->GetID() : MSG_ROUTING_NONE; |
| 107 const int render_view_id = rvh ? rvh->GetRoutingID() : MSG_ROUTING_NONE; |
| 108 |
| 109 message_loop_->PostTask(FROM_HERE, |
| 110 base::Bind(&WebContentsTracker::MaybeDoCallback, this, |
| 111 render_process_id, render_view_id)); |
| 112 } |
| 113 |
| 114 void WebContentsTracker::MaybeDoCallback(int render_process_id, |
| 115 int render_view_id) { |
| 116 DCHECK(message_loop_->BelongsToCurrentThread()); |
| 117 |
| 118 if (!callback_.is_null()) |
| 119 callback_.Run(render_process_id, render_view_id); |
| 120 } |
| 121 |
| 122 void WebContentsTracker::LookUpAndObserveWebContents(int render_process_id, |
| 123 int render_view_id) { |
| 124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 125 |
| 126 RenderViewHost* const rvh = |
| 127 RenderViewHost::FromID(render_process_id, render_view_id); |
| 128 DVLOG_IF(1, !rvh) << "RenderViewHost::FromID(" |
| 129 << render_process_id << ", " << render_view_id |
| 130 << ") returned NULL."; |
| 131 Observe(rvh ? WebContents::FromRenderViewHost(rvh) : NULL); |
| 132 DVLOG_IF(1, !web_contents()) |
| 133 << "WebContents::FromRenderViewHost(" << rvh << ") returned NULL."; |
| 134 |
| 135 OnWebContentsChangeEvent(); |
| 136 } |
| 137 |
| 138 void WebContentsTracker::RenderViewReady() { |
| 139 OnWebContentsChangeEvent(); |
| 140 } |
| 141 |
| 142 void WebContentsTracker::AboutToNavigateRenderView(RenderViewHost* rvh) { |
| 143 OnWebContentsChangeEvent(); |
| 144 } |
| 145 |
| 146 void WebContentsTracker::DidNavigateMainFrame( |
| 147 const LoadCommittedDetails& details, const FrameNavigateParams& params) { |
| 148 OnWebContentsChangeEvent(); |
| 149 } |
| 150 |
| 151 void WebContentsTracker::WebContentsDestroyed(WebContents* web_contents) { |
| 152 OnWebContentsChangeEvent(); |
| 153 } |
| 154 |
59 } // namespace content | 155 } // namespace content |
OLD | NEW |