OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // IE browser helper object implementation. | 5 // IE browser helper object implementation. |
6 #include "ceee/ie/plugin/bho/browser_helper_object.h" | 6 #include "ceee/ie/plugin/bho/browser_helper_object.h" |
7 | 7 |
8 #include <atlsafe.h> | 8 #include <atlsafe.h> |
9 #include <shlguid.h> | 9 #include <shlguid.h> |
10 | 10 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 lower_bound_ready_state_(READYSTATE_UNINITIALIZED), | 100 lower_bound_ready_state_(READYSTATE_UNINITIALIZED), |
101 ie7_or_later_(false), | 101 ie7_or_later_(false), |
102 thread_id_(::GetCurrentThreadId()), | 102 thread_id_(::GetCurrentThreadId()), |
103 full_tab_chrome_frame_(false) { | 103 full_tab_chrome_frame_(false) { |
104 TRACE_EVENT_BEGIN("ceee.bho", this, ""); | 104 TRACE_EVENT_BEGIN("ceee.bho", this, ""); |
105 // Only the first call to this function really does anything. | 105 // Only the first call to this function really does anything. |
106 CookieAccountant::GetInstance()->PatchWininetFunctions(); | 106 CookieAccountant::GetInstance()->PatchWininetFunctions(); |
107 } | 107 } |
108 | 108 |
109 BrowserHelperObject::~BrowserHelperObject() { | 109 BrowserHelperObject::~BrowserHelperObject() { |
110 if (broker_rpc_ != NULL) { | 110 if (broker_rpc_ != NULL) |
111 broker_rpc_->Disconnect(); | 111 broker_rpc_->Disconnect(); |
112 } | |
113 | 112 |
114 TRACE_EVENT_END("ceee.bho", this, ""); | 113 TRACE_EVENT_END("ceee.bho", this, ""); |
115 } | 114 } |
116 | 115 |
117 HRESULT BrowserHelperObject::FinalConstruct() { | 116 HRESULT BrowserHelperObject::FinalConstruct() { |
118 return S_OK; | 117 return S_OK; |
119 } | 118 } |
120 | 119 |
121 void BrowserHelperObject::FinalRelease() { | 120 void BrowserHelperObject::FinalRelease() { |
122 web_browser_.Release(); | 121 web_browser_.Release(); |
123 } | 122 } |
124 | 123 |
125 STDMETHODIMP BrowserHelperObject::SetSite(IUnknown* site) { | 124 STDMETHODIMP BrowserHelperObject::SetSite(IUnknown* site) { |
126 typedef IObjectWithSiteImpl<BrowserHelperObject> SuperSite; | 125 typedef IObjectWithSiteImpl<BrowserHelperObject> SuperSite; |
127 | 126 |
128 // From experience, we know the site may be set multiple times. | 127 // From experience, we know the site may be set multiple times. |
129 // Let's ignore second and subsequent set or unset. | 128 // Let's ignore second and subsequent set or unset. |
130 if (NULL != site && NULL != m_spUnkSite.p || | 129 if (site != NULL&& m_spUnkSite.p != NULL || |
131 NULL == site && NULL == m_spUnkSite.p) { | 130 site == NULL && m_spUnkSite.p == NULL ) { |
132 LOG(WARNING) << "Duplicate call to SetSite, previous site " | 131 LOG(WARNING) << "Duplicate call to SetSite, previous site " |
133 << m_spUnkSite.p << " new site " << site; | 132 << m_spUnkSite.p << " new site " << site; |
134 return S_OK; | 133 return S_OK; |
135 } | 134 } |
136 | 135 |
137 if (NULL == site) { | 136 if (NULL == site) { |
138 mu::ScopedTimer metrics_timer("ceee/BHO.TearDown", broker_rpc_.get()); | 137 if (broker_rpc_ != NULL) |
MAD
2010/11/24 23:03:56
You'll need to sync and merge again, this should b
Jói
2010/11/25 23:13:41
Done.
| |
138 mu::ScopedTimer metrics_timer("ceee/BHO.TearDown", broker_rpc_.get()); | |
139 | 139 |
140 // We're being torn down. | 140 // We're being torn down. |
141 TearDown(); | 141 TearDown(); |
142 | 142 |
143 FireOnRemovedEvent(); | 143 FireOnRemovedEvent(); |
144 // This call should be the last thing we send to the broker. | 144 // This call should be the last thing we send to the broker. |
145 FireOnUnmappedEvent(); | 145 FireOnUnmappedEvent(); |
146 } | 146 } |
147 | 147 |
148 HRESULT hr = SuperSite::SetSite(site); | 148 HRESULT hr = SuperSite::SetSite(site); |
149 if (FAILED(hr)) | 149 if (FAILED(hr)) |
150 return hr; | 150 return hr; |
151 | 151 |
152 if (NULL != site) { | 152 if (NULL != site) { |
153 if (broker_rpc_ == NULL) { | |
154 // Unfortunately, we need to connect before taking performance. Including | |
155 // this call in our Timing would be useful. Unit tests make it | |
156 // complicated. | |
157 // TODO(hansl@chromium.org): Change initialization to be able to time | |
158 // this call too. | |
159 hr = ConnectRpcBrokerClient(); | |
160 if (FAILED(hr) || !broker_rpc_->is_connected()) { | |
161 NOTREACHED() << "Couldn't connect to the RPC server."; | |
162 TearDown(); | |
163 SuperSite::SetSite(NULL); | |
164 } | |
165 } | |
166 | |
167 mu::ScopedTimer metrics_timer("ceee/BHO.Initialize", broker_rpc_.get()); | |
168 // We're being initialized. | 153 // We're being initialized. |
169 hr = Initialize(site); | 154 hr = Initialize(site); |
170 | 155 |
171 // Release the site, and tear down our own state in case of failure. | 156 // Release the site, and tear down our own state in case of failure. |
172 if (FAILED(hr)) { | 157 if (FAILED(hr)) { |
173 TearDown(); | 158 TearDown(); |
174 SuperSite::SetSite(NULL); | 159 SuperSite::SetSite(NULL); |
175 } | 160 } |
176 } | 161 } |
177 | 162 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 new WebProgressNotifier()); | 245 new WebProgressNotifier()); |
261 HRESULT hr = web_progress_notifier->Initialize(this, tab_window_, | 246 HRESULT hr = web_progress_notifier->Initialize(this, tab_window_, |
262 web_browser_); | 247 web_browser_); |
263 | 248 |
264 return SUCCEEDED(hr) ? web_progress_notifier.release() : NULL; | 249 return SUCCEEDED(hr) ? web_progress_notifier.release() : NULL; |
265 } | 250 } |
266 | 251 |
267 HRESULT BrowserHelperObject::Initialize(IUnknown* site) { | 252 HRESULT BrowserHelperObject::Initialize(IUnknown* site) { |
268 TRACE_EVENT_INSTANT("ceee.bho.initialize", this, ""); | 253 TRACE_EVENT_INSTANT("ceee.bho.initialize", this, ""); |
269 | 254 |
255 // We need to make sure the Broker is CoCreated BEFORE we try RPC to it. | |
256 HRESULT hr = GetBrokerRegistrar(&broker_registrar_); | |
257 DCHECK(SUCCEEDED(hr) && broker_registrar_) << "CoCreating Broker. " << | |
258 com::LogHr(hr); | |
259 if (FAILED(hr) || !broker_registrar_) | |
260 return com::AlwaysError(hr); | |
261 | |
262 // Unfortunately, we need to connect before taking performance. Including | |
263 // this call in our Timing would be useful. Unit tests make it | |
264 // complicated. | |
265 // TODO(hansl@chromium.org): Change initialization to be able to time | |
266 // this call too. | |
267 DCHECK(broker_rpc_ == NULL); | |
268 hr = ConnectRpcBrokerClient(); | |
269 if (FAILED(hr) || !broker_rpc_->is_connected()) { | |
270 NOTREACHED() << "Couldn't connect to the RPC server."; | |
271 return com::AlwaysError(hr); | |
272 } | |
273 mu::ScopedTimer metrics_timer("ceee/BHO.Initialize", broker_rpc_.get()); | |
274 | |
270 ie7_or_later_ = ie_util::GetIeVersion() > ie_util::IEVERSION_IE6; | 275 ie7_or_later_ = ie_util::GetIeVersion() > ie_util::IEVERSION_IE6; |
271 | 276 |
272 HRESULT hr = InitializeChromeFrameHost(); | 277 hr = InitializeChromeFrameHost(); |
273 DCHECK(SUCCEEDED(hr)) << "InitializeChromeFrameHost failed " << | 278 DCHECK(SUCCEEDED(hr)) << "InitializeChromeFrameHost failed " << |
274 com::LogHr(hr); | 279 com::LogHr(hr); |
275 if (FAILED(hr)) { | 280 if (FAILED(hr)) { |
276 return hr; | 281 return hr; |
277 } | 282 } |
278 | 283 |
279 // Initialize the extension port manager. | 284 // Initialize the extension port manager. |
280 extension_port_manager_.Initialize(chrome_frame_host_); | 285 extension_port_manager_.Initialize(chrome_frame_host_); |
281 | 286 |
282 // Register the proxy/stubs for the executor. | 287 // Register the proxy/stubs for the executor. |
283 // Note the proxy registration function will have logged what occurred. | 288 // Note the proxy registration function will have logged what occurred. |
284 hr = RegisterProxies(); | 289 hr = RegisterProxies(); |
285 if (FAILED(hr)) | 290 if (FAILED(hr)) |
286 return hr; | 291 return hr; |
287 | 292 |
288 // Preemptively feed the broker with an executor in our thread. | 293 // Preemptively feed the broker with an executor in our thread. |
289 hr = GetBrokerRegistrar(&broker_registrar_); | 294 DCHECK(executor_ == NULL); |
290 LOG_IF(ERROR, FAILED(hr)) << "Failed to create broker, hr=" << | 295 hr = CreateExecutor(&executor_); |
296 LOG_IF(ERROR, FAILED(hr)) << "Failed to create Executor, hr=" << | |
291 com::LogHr(hr); | 297 com::LogHr(hr); |
292 DCHECK(SUCCEEDED(hr)) << "CoCreating Broker. " << com::LogHr(hr); | 298 DCHECK(SUCCEEDED(hr)) << "CoCreating Executor. " << com::LogHr(hr); |
293 if (SUCCEEDED(hr)) { | 299 if (SUCCEEDED(hr)) { |
294 DCHECK(executor_ == NULL); | 300 // TODO(mad@chromium.org): Implement the proper manual/secure |
295 hr = CreateExecutor(&executor_); | 301 // registration. |
296 LOG_IF(ERROR, FAILED(hr)) << "Failed to create Executor, hr=" << | 302 hr = broker_registrar_->RegisterTabExecutor(::GetCurrentThreadId(), |
297 com::LogHr(hr); | 303 executor_); |
298 DCHECK(SUCCEEDED(hr)) << "CoCreating Executor. " << com::LogHr(hr); | 304 DCHECK(SUCCEEDED(hr)) << "Registering Executor. " << com::LogHr(hr); |
299 if (SUCCEEDED(hr)) { | |
300 // TODO(mad@chromium.org): Implement the proper manual/secure | |
301 // registration. | |
302 hr = broker_registrar_->RegisterTabExecutor(::GetCurrentThreadId(), | |
303 executor_); | |
304 DCHECK(SUCCEEDED(hr)) << "Registering Executor. " << com::LogHr(hr); | |
305 } | |
306 } | 305 } |
306 if (FAILED(hr)) | |
307 return hr; | |
307 | 308 |
308 // We need the service provider for both the sink connections and | 309 // We need the service provider for both the sink connections and |
309 // to get a handle to the tab window. | 310 // to get a handle to the tab window. |
310 CComQIPtr<IServiceProvider> service_provider(site); | 311 CComQIPtr<IServiceProvider> service_provider(site); |
311 DCHECK(service_provider); | 312 DCHECK(service_provider); |
312 if (service_provider == NULL) { | 313 if (service_provider == NULL) { |
313 return E_FAIL; | 314 return E_FAIL; |
314 } | 315 } |
315 | 316 |
316 hr = ConnectSinks(service_provider); | 317 hr = ConnectSinks(service_provider); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 chrome_frame_host_->SetEventSink(NULL); | 414 chrome_frame_host_->SetEventSink(NULL); |
414 | 415 |
415 LOG(ERROR) << "Failed to start chrome frame " << com::LogHr(hr); | 416 LOG(ERROR) << "Failed to start chrome frame " << com::LogHr(hr); |
416 return hr; | 417 return hr; |
417 } | 418 } |
418 | 419 |
419 return hr; | 420 return hr; |
420 } | 421 } |
421 | 422 |
422 HRESULT BrowserHelperObject::OnCfReadyStateChanged(LONG state) { | 423 HRESULT BrowserHelperObject::OnCfReadyStateChanged(LONG state) { |
423 // If EnsureTabId() returns false, the session_id isn't available. | 424 if (state == READYSTATE_COMPLETE) { |
424 // This means that the ExternalTab hasn't been created yet, which is certainly | 425 // If EnsureTabId() returns false, the session_id isn't available. |
425 // a bug. Calling this here will also ensure we call all the deferred calls if | 426 // This means that the ExternalTab hasn't been created yet, which is certain ly |
426 // they haven't been called yet. | 427 // a bug. Calling this here will also ensure we call all the deferred calls if |
427 bool id_available = EnsureTabId(); | 428 // they haven't been called yet. |
428 if (!id_available) { | 429 bool id_available = EnsureTabId(); |
429 NOTREACHED(); | 430 if (!id_available) { |
430 return E_UNEXPECTED; | 431 NOTREACHED(); |
431 } | 432 return E_UNEXPECTED; |
433 } | |
432 | 434 |
433 if (state == READYSTATE_COMPLETE) { | |
434 extension_path_ = ceee_module_util::GetExtensionPath(); | 435 extension_path_ = ceee_module_util::GetExtensionPath(); |
435 | 436 |
436 if (ceee_module_util::IsCrxOrEmpty(extension_path_) && | 437 if (ceee_module_util::IsCrxOrEmpty(extension_path_) && |
437 ceee_module_util::NeedToInstallExtension()) { | 438 ceee_module_util::NeedToInstallExtension()) { |
438 LOG(INFO) << "Installing extension: \"" << extension_path_ << "\""; | 439 LOG(INFO) << "Installing extension: \"" << extension_path_ << "\""; |
439 chrome_frame_host_->InstallExtension(CComBSTR(extension_path_.c_str())); | 440 chrome_frame_host_->InstallExtension(CComBSTR(extension_path_.c_str())); |
440 } else { | 441 } else { |
441 // In the case where we don't have a CRX (or we don't need to install it), | 442 // In the case where we don't have a CRX (or we don't need to install it), |
442 // we must ask for the currently enabled extension before we can decide | 443 // we must ask for the currently enabled extension before we can decide |
443 // what we need to do. | 444 // what we need to do. |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
774 deferred_tab_id_call_.push_back(NewRunnableMethod( | 775 deferred_tab_id_call_.push_back(NewRunnableMethod( |
775 this, &BrowserHelperObject::OnBeforeNavigate2Impl, | 776 this, &BrowserHelperObject::OnBeforeNavigate2Impl, |
776 ScopedDispatchPtr(webbrowser_disp), url_bstr)); | 777 ScopedDispatchPtr(webbrowser_disp), url_bstr)); |
777 } else { | 778 } else { |
778 OnBeforeNavigate2Impl(ScopedDispatchPtr(webbrowser_disp), url_bstr); | 779 OnBeforeNavigate2Impl(ScopedDispatchPtr(webbrowser_disp), url_bstr); |
779 } | 780 } |
780 } | 781 } |
781 | 782 |
782 void BrowserHelperObject::OnBeforeNavigate2Impl( | 783 void BrowserHelperObject::OnBeforeNavigate2Impl( |
783 const ScopedDispatchPtr& webbrowser_disp, const CComBSTR& url) { | 784 const ScopedDispatchPtr& webbrowser_disp, const CComBSTR& url) { |
784 mu::ScopedTimer metrics_timer("ceee/BHO.BeforeNavigate", broker_rpc_.get()); | 785 if (broker_rpc_ != NULL) |
786 mu::ScopedTimer metrics_timer("ceee/BHO.BeforeNavigate", broker_rpc_.get()); | |
785 | 787 |
786 base::win::ScopedComPtr<IWebBrowser2> webbrowser; | 788 base::win::ScopedComPtr<IWebBrowser2> webbrowser; |
787 HRESULT hr = webbrowser.QueryFrom(webbrowser_disp); | 789 HRESULT hr = webbrowser.QueryFrom(webbrowser_disp); |
788 if (FAILED(hr)) { | 790 if (FAILED(hr)) { |
789 LOG(ERROR) << "OnBeforeNavigate2 failed to QI " << com::LogHr(hr); | 791 LOG(ERROR) << "OnBeforeNavigate2 failed to QI " << com::LogHr(hr); |
790 return; | 792 return; |
791 } | 793 } |
792 | 794 |
793 for (std::vector<Sink*>::iterator iter = sinks_.begin(); | 795 for (std::vector<Sink*>::iterator iter = sinks_.begin(); |
794 iter != sinks_.end(); ++iter) { | 796 iter != sinks_.end(); ++iter) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
839 deferred_tab_id_call_.push_back(NewRunnableMethod( | 841 deferred_tab_id_call_.push_back(NewRunnableMethod( |
840 this, &BrowserHelperObject::OnDocumentCompleteImpl, | 842 this, &BrowserHelperObject::OnDocumentCompleteImpl, |
841 webbrowser, url_bstr)); | 843 webbrowser, url_bstr)); |
842 } else { | 844 } else { |
843 OnDocumentCompleteImpl(webbrowser, url_bstr); | 845 OnDocumentCompleteImpl(webbrowser, url_bstr); |
844 } | 846 } |
845 } | 847 } |
846 | 848 |
847 void BrowserHelperObject::OnDocumentCompleteImpl( | 849 void BrowserHelperObject::OnDocumentCompleteImpl( |
848 const ScopedWebBrowser2Ptr& webbrowser, const CComBSTR& url) { | 850 const ScopedWebBrowser2Ptr& webbrowser, const CComBSTR& url) { |
849 mu::ScopedTimer metrics_timer("ceee/BHO.DocumentComplete", broker_rpc_.get()); | 851 if (broker_rpc_ != NULL) { |
852 mu::ScopedTimer metrics_timer("ceee/BHO.DocumentComplete", | |
853 broker_rpc_.get()); | |
854 } | |
850 for (std::vector<Sink*>::iterator iter = sinks_.begin(); | 855 for (std::vector<Sink*>::iterator iter = sinks_.begin(); |
851 iter != sinks_.end(); ++iter) { | 856 iter != sinks_.end(); ++iter) { |
852 (*iter)->OnDocumentComplete(webbrowser, url); | 857 (*iter)->OnDocumentComplete(webbrowser, url); |
853 } | 858 } |
854 } | 859 } |
855 | 860 |
856 STDMETHODIMP_(void) BrowserHelperObject::OnNavigateComplete2( | 861 STDMETHODIMP_(void) BrowserHelperObject::OnNavigateComplete2( |
857 IDispatch* webbrowser_disp, VARIANT* url) { | 862 IDispatch* webbrowser_disp, VARIANT* url) { |
858 if (webbrowser_disp == NULL || url == NULL) { | 863 if (webbrowser_disp == NULL || url == NULL) { |
859 LOG(ERROR) << "OnNavigateComplete2 got invalid parameter(s)"; | 864 LOG(ERROR) << "OnNavigateComplete2 got invalid parameter(s)"; |
(...skipping 18 matching lines...) Expand all Loading... | |
878 deferred_tab_id_call_.push_back(NewRunnableMethod( | 883 deferred_tab_id_call_.push_back(NewRunnableMethod( |
879 this, &BrowserHelperObject::OnNavigateComplete2Impl, | 884 this, &BrowserHelperObject::OnNavigateComplete2Impl, |
880 webbrowser, url_bstr)); | 885 webbrowser, url_bstr)); |
881 } else { | 886 } else { |
882 BrowserHelperObject::OnNavigateComplete2Impl(webbrowser, url_bstr); | 887 BrowserHelperObject::OnNavigateComplete2Impl(webbrowser, url_bstr); |
883 } | 888 } |
884 } | 889 } |
885 | 890 |
886 void BrowserHelperObject::OnNavigateComplete2Impl( | 891 void BrowserHelperObject::OnNavigateComplete2Impl( |
887 const ScopedWebBrowser2Ptr& webbrowser, const CComBSTR& url) { | 892 const ScopedWebBrowser2Ptr& webbrowser, const CComBSTR& url) { |
888 mu::ScopedTimer metrics_timer("ceee/BHO.NavigateComplete", broker_rpc_.get()); | 893 if (broker_rpc_ != NULL) { |
894 mu::ScopedTimer metrics_timer("ceee/BHO.NavigateComplete", | |
895 broker_rpc_.get()); | |
896 } | |
889 | 897 |
890 HandleNavigateComplete(webbrowser, url); | 898 HandleNavigateComplete(webbrowser, url); |
891 | 899 |
892 for (std::vector<Sink*>::iterator iter = sinks_.begin(); | 900 for (std::vector<Sink*>::iterator iter = sinks_.begin(); |
893 iter != sinks_.end(); ++iter) { | 901 iter != sinks_.end(); ++iter) { |
894 (*iter)->OnNavigateComplete(webbrowser, url); | 902 (*iter)->OnNavigateComplete(webbrowser, url); |
895 } | 903 } |
896 } | 904 } |
897 | 905 |
898 STDMETHODIMP_(void) BrowserHelperObject::OnNavigateError( | 906 STDMETHODIMP_(void) BrowserHelperObject::OnNavigateError( |
(...skipping 30 matching lines...) Expand all Loading... | |
929 this, &BrowserHelperObject::OnNavigateErrorImpl, | 937 this, &BrowserHelperObject::OnNavigateErrorImpl, |
930 webbrowser, url_bstr, status)); | 938 webbrowser, url_bstr, status)); |
931 } else { | 939 } else { |
932 OnNavigateErrorImpl(webbrowser, url_bstr, status); | 940 OnNavigateErrorImpl(webbrowser, url_bstr, status); |
933 } | 941 } |
934 } | 942 } |
935 | 943 |
936 void BrowserHelperObject::OnNavigateErrorImpl( | 944 void BrowserHelperObject::OnNavigateErrorImpl( |
937 const ScopedWebBrowser2Ptr& webbrowser, const CComBSTR& url, | 945 const ScopedWebBrowser2Ptr& webbrowser, const CComBSTR& url, |
938 LONG status_code) { | 946 LONG status_code) { |
939 mu::ScopedTimer metrics_timer("ceee/BHO.NavigateError", broker_rpc_.get()); | 947 if (broker_rpc_ != NULL) |
948 mu::ScopedTimer metrics_timer("ceee/BHO.NavigateError", broker_rpc_.get()); | |
940 | 949 |
941 for (std::vector<Sink*>::iterator iter = sinks_.begin(); | 950 for (std::vector<Sink*>::iterator iter = sinks_.begin(); |
942 iter != sinks_.end(); ++iter) { | 951 iter != sinks_.end(); ++iter) { |
943 (*iter)->OnNavigateError(webbrowser, url, status_code); | 952 (*iter)->OnNavigateError(webbrowser, url, status_code); |
944 } | 953 } |
945 } | 954 } |
946 | 955 |
947 STDMETHODIMP_(void) BrowserHelperObject::OnNewWindow2( | 956 STDMETHODIMP_(void) BrowserHelperObject::OnNewWindow2( |
948 IDispatch** /*webbrowser_disp*/, VARIANT_BOOL* /*cancel*/) { | 957 IDispatch** /*webbrowser_disp*/, VARIANT_BOOL* /*cancel*/) { |
949 // When a new window/tab is created, IE7 or later version of IE will also | 958 // When a new window/tab is created, IE7 or later version of IE will also |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1458 DCHECK(thread_id_ == ::GetCurrentThreadId()); | 1467 DCHECK(thread_id_ == ::GetCurrentThreadId()); |
1459 | 1468 |
1460 if (sink == NULL) | 1469 if (sink == NULL) |
1461 return; | 1470 return; |
1462 | 1471 |
1463 std::vector<Sink*>::iterator iter = std::find(sinks_.begin(), sinks_.end(), | 1472 std::vector<Sink*>::iterator iter = std::find(sinks_.begin(), sinks_.end(), |
1464 sink); | 1473 sink); |
1465 if (iter != sinks_.end()) | 1474 if (iter != sinks_.end()) |
1466 sinks_.erase(iter); | 1475 sinks_.erase(iter); |
1467 } | 1476 } |
OLD | NEW |