Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: chrome_frame/chrome_frame_automation.cc

Issue 7276037: Remove NPAPI support from Chrome Frame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome_frame/chrome_frame_automation.h" 5 #include "chrome_frame/chrome_frame_automation.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 20 matching lines...) Expand all
31 #include "chrome_frame/simple_resource_loader.h" 31 #include "chrome_frame/simple_resource_loader.h"
32 #include "chrome_frame/utils.h" 32 #include "chrome_frame/utils.h"
33 #include "ui/base/ui_base_switches.h" 33 #include "ui/base/ui_base_switches.h"
34 34
35 #ifdef NDEBUG 35 #ifdef NDEBUG
36 int64 kAutomationServerReasonableLaunchDelay = 1000; // in milliseconds 36 int64 kAutomationServerReasonableLaunchDelay = 1000; // in milliseconds
37 #else 37 #else
38 int64 kAutomationServerReasonableLaunchDelay = 1000 * 10; 38 int64 kAutomationServerReasonableLaunchDelay = 1000 * 10;
39 #endif 39 #endif
40 40
41 int kDefaultSendUMADataInterval = 20000; // in milliseconds.
42
43 static const wchar_t kUmaSendIntervalValue[] = L"UmaSendInterval";
44
45 class ChromeFrameAutomationProxyImpl::TabProxyNotificationMessageFilter 41 class ChromeFrameAutomationProxyImpl::TabProxyNotificationMessageFilter
46 : public IPC::ChannelProxy::MessageFilter { 42 : public IPC::ChannelProxy::MessageFilter {
47 public: 43 public:
48 explicit TabProxyNotificationMessageFilter(AutomationHandleTracker* tracker) 44 explicit TabProxyNotificationMessageFilter(AutomationHandleTracker* tracker)
49 : tracker_(tracker) { 45 : tracker_(tracker) {
50 } 46 }
51 47
52 void AddTabProxy(AutomationHandle tab_proxy) { 48 void AddTabProxy(AutomationHandle tab_proxy) {
53 base::AutoLock lock(lock_); 49 base::AutoLock lock(lock_);
54 tabs_list_.push_back(tab_proxy); 50 tabs_list_.push_back(tab_proxy);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 #else 194 #else
199 void Dump() {} 195 void Dump() {}
200 #endif 196 #endif
201 }; 197 };
202 198
203 DISABLE_RUNNABLE_METHOD_REFCOUNT(AutomationProxyCacheEntry); 199 DISABLE_RUNNABLE_METHOD_REFCOUNT(AutomationProxyCacheEntry);
204 200
205 AutomationProxyCacheEntry::AutomationProxyCacheEntry( 201 AutomationProxyCacheEntry::AutomationProxyCacheEntry(
206 ChromeFrameLaunchParams* params, LaunchDelegate* delegate) 202 ChromeFrameLaunchParams* params, LaunchDelegate* delegate)
207 : profile_name(params->profile_name()), 203 : profile_name(params->profile_name()),
208 launch_result_(AUTOMATION_LAUNCH_RESULT_INVALID), 204 launch_result_(AUTOMATION_LAUNCH_RESULT_INVALID) {
209 snapshots_(NULL), uma_send_interval_(1) {
210 DCHECK(delegate); 205 DCHECK(delegate);
211 thread_.reset(new base::Thread(WideToASCII(profile_name).c_str())); 206 thread_.reset(new base::Thread(WideToASCII(profile_name).c_str()));
212 thread_->Start(); 207 thread_->Start();
213 // Use scoped_refptr so that the params will get released when the task 208 // Use scoped_refptr so that the params will get released when the task
214 // has been run. 209 // has been run.
215 scoped_refptr<ChromeFrameLaunchParams> ref_params(params); 210 scoped_refptr<ChromeFrameLaunchParams> ref_params(params);
216 thread_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, 211 thread_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this,
217 &AutomationProxyCacheEntry::CreateProxy, ref_params, delegate)); 212 &AutomationProxyCacheEntry::CreateProxy, ref_params, delegate));
218 } 213 }
219 214
220 AutomationProxyCacheEntry::~AutomationProxyCacheEntry() { 215 AutomationProxyCacheEntry::~AutomationProxyCacheEntry() {
221 DVLOG(1) << __FUNCTION__ << profile_name; 216 DVLOG(1) << __FUNCTION__ << profile_name;
222 // Attempt to fix chrome_frame_tests crash seen at times on the IE6/IE7 217 // Attempt to fix chrome_frame_tests crash seen at times on the IE6/IE7
223 // builders. It appears that there are cases when we can enter here when the 218 // builders. It appears that there are cases when we can enter here when the
224 // AtExitManager is tearing down the global ProxyCache which causes a crash 219 // AtExitManager is tearing down the global ProxyCache which causes a crash
225 // while tearing down the AutomationProxy object due to a NULL MessageLoop 220 // while tearing down the AutomationProxy object due to a NULL MessageLoop
226 // The AutomationProxy class uses the SyncChannel which assumes the existence 221 // The AutomationProxy class uses the SyncChannel which assumes the existence
227 // of a MessageLoop instance. 222 // of a MessageLoop instance.
228 // We leak the AutomationProxy pointer here to avoid a crash. 223 // We leak the AutomationProxy pointer here to avoid a crash.
229 if (MessageLoop::current() == NULL) { 224 if (MessageLoop::current() == NULL) {
230 proxy_.release(); 225 proxy_.release();
231 } 226 }
232 } 227 }
233 228
234 void AutomationProxyCacheEntry::StartSendUmaInterval(
235 ChromeFrameHistogramSnapshots* snapshots, int send_interval) {
236 DCHECK(snapshots);
237 DCHECK(!snapshots_);
238 snapshots_ = snapshots;
239 uma_send_interval_ = send_interval;
240 thread_->message_loop()->PostDelayedTask(FROM_HERE,
241 NewRunnableMethod(this, &AutomationProxyCacheEntry::SendUMAData),
242 send_interval);
243 }
244
245 void AutomationProxyCacheEntry::CreateProxy(ChromeFrameLaunchParams* params, 229 void AutomationProxyCacheEntry::CreateProxy(ChromeFrameLaunchParams* params,
246 LaunchDelegate* delegate) { 230 LaunchDelegate* delegate) {
247 DCHECK(IsSameThread(base::PlatformThread::CurrentId())); 231 DCHECK(IsSameThread(base::PlatformThread::CurrentId()));
248 DCHECK(delegate); 232 DCHECK(delegate);
249 DCHECK(params); 233 DCHECK(params);
250 DCHECK(proxy_.get() == NULL); 234 DCHECK(proxy_.get() == NULL);
251 235
252 // We *must* create automationproxy in a thread that has message loop, 236 // We *must* create automationproxy in a thread that has message loop,
253 // since SyncChannel::Context construction registers event to be watched 237 // since SyncChannel::Context construction registers event to be watched
254 // through ObjectWatcher which subscribes for the current thread message loop 238 // through ObjectWatcher which subscribes for the current thread message loop
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 *was_last_delegate = false; 358 *was_last_delegate = false;
375 359
376 LaunchDelegates::iterator it = std::find(launch_delegates_.begin(), 360 LaunchDelegates::iterator it = std::find(launch_delegates_.begin(),
377 launch_delegates_.end(), delegate); 361 launch_delegates_.end(), delegate);
378 if (it == launch_delegates_.end()) { 362 if (it == launch_delegates_.end()) {
379 NOTREACHED(); 363 NOTREACHED();
380 } else { 364 } else {
381 if (launch_delegates_.size() == 1) { 365 if (launch_delegates_.size() == 1) {
382 *was_last_delegate = true; 366 *was_last_delegate = true;
383 367
384 if (snapshots_)
385 SendUMAData();
386
387 // Process pending notifications. 368 // Process pending notifications.
388 thread_->message_loop()->RunAllPending(); 369 thread_->message_loop()->RunAllPending();
389 370
390 // Take down the proxy since we no longer have any clients. 371 // Take down the proxy since we no longer have any clients.
391 // Make sure we only do this once all pending messages have been cleared. 372 // Make sure we only do this once all pending messages have been cleared.
392 proxy_.reset(NULL); 373 proxy_.reset(NULL);
393 } 374 }
394 // Be careful to remove from the list after running pending 375 // Be careful to remove from the list after running pending
395 // tasks. Otherwise the delegate being removed might miss out 376 // tasks. Otherwise the delegate being removed might miss out
396 // on pending notifications such as LaunchComplete. 377 // on pending notifications such as LaunchComplete.
(...skipping 17 matching lines...) Expand all
414 395
415 void AutomationProxyCacheEntry::OnChannelError() { 396 void AutomationProxyCacheEntry::OnChannelError() {
416 DCHECK(IsSameThread(base::PlatformThread::CurrentId())); 397 DCHECK(IsSameThread(base::PlatformThread::CurrentId()));
417 launch_result_ = AUTOMATION_SERVER_CRASHED; 398 launch_result_ = AUTOMATION_SERVER_CRASHED;
418 LaunchDelegates::const_iterator it = launch_delegates_.begin(); 399 LaunchDelegates::const_iterator it = launch_delegates_.begin();
419 for (; it != launch_delegates_.end(); ++it) { 400 for (; it != launch_delegates_.end(); ++it) {
420 (*it)->AutomationServerDied(); 401 (*it)->AutomationServerDied();
421 } 402 }
422 } 403 }
423 404
424 void AutomationProxyCacheEntry::SendUMAData() {
425 DCHECK(IsSameThread(base::PlatformThread::CurrentId()));
426 DCHECK(snapshots_);
427 // IE uses the chrome frame provided UMA data uploading scheme. NPAPI
428 // continues to use Chrome to upload UMA data.
429 if (CrashMetricsReporter::GetInstance()->active()) {
430 return;
431 }
432
433 if (!proxy_.get()) {
434 DLOG(WARNING) << __FUNCTION__ << " NULL proxy, can't send UMA data";
435 } else {
436 ChromeFrameHistogramSnapshots::HistogramPickledList histograms =
437 snapshots_->GatherAllHistograms();
438
439 if (!histograms.empty()) {
440 proxy_->Send(new AutomationMsg_RecordHistograms(histograms));
441 }
442
443 MessageLoop::current()->PostDelayedTask(FROM_HERE,
444 NewRunnableMethod(this, &AutomationProxyCacheEntry::SendUMAData),
445 uma_send_interval_);
446 }
447 }
448
449
450 DISABLE_RUNNABLE_METHOD_REFCOUNT(ProxyFactory); 405 DISABLE_RUNNABLE_METHOD_REFCOUNT(ProxyFactory);
451 406
452 ProxyFactory::ProxyFactory() 407 ProxyFactory::ProxyFactory() {
453 : uma_send_interval_(0) {
454 uma_send_interval_ = GetConfigInt(kDefaultSendUMADataInterval,
455 kUmaSendIntervalValue);
456 } 408 }
457 409
458 ProxyFactory::~ProxyFactory() { 410 ProxyFactory::~ProxyFactory() {
459 for (size_t i = 0; i < proxies_.container().size(); ++i) { 411 for (size_t i = 0; i < proxies_.container().size(); ++i) {
460 DWORD result = proxies_[i]->WaitForThread(0); 412 DWORD result = proxies_[i]->WaitForThread(0);
461 if (WAIT_OBJECT_0 != result) 413 if (WAIT_OBJECT_0 != result)
462 // TODO(stoyan): Don't leak proxies on exit. 414 // TODO(stoyan): Don't leak proxies on exit.
463 DLOG(ERROR) << "Proxies leaked on exit."; 415 DLOG(ERROR) << "Proxies leaked on exit.";
464 } 416 }
465 } 417 }
(...skipping 10 matching lines...) Expand all
476 if (proxies_[i]->IsSameProfile(params->profile_name())) { 428 if (proxies_[i]->IsSameProfile(params->profile_name())) {
477 entry = proxies_[i]; 429 entry = proxies_[i];
478 break; 430 break;
479 } 431 }
480 } 432 }
481 433
482 if (entry == NULL) { 434 if (entry == NULL) {
483 DVLOG(1) << __FUNCTION__ << " creating new proxy entry"; 435 DVLOG(1) << __FUNCTION__ << " creating new proxy entry";
484 entry = new AutomationProxyCacheEntry(params, delegate); 436 entry = new AutomationProxyCacheEntry(params, delegate);
485 proxies_.container().push_back(entry); 437 proxies_.container().push_back(entry);
486
487 // IE uses the chrome frame provided UMA data uploading scheme. NPAPI
488 // continues to use Chrome to upload UMA data.
489 if (!CrashMetricsReporter::GetInstance()->active()) {
490 entry->StartSendUmaInterval(&chrome_frame_histograms_,
491 uma_send_interval_);
492 }
493 } else if (delegate) { 438 } else if (delegate) {
494 // Notify the new delegate of the launch status from the worker thread 439 // Notify the new delegate of the launch status from the worker thread
495 // and add it to the list of delegates. 440 // and add it to the list of delegates.
496 entry->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(entry.get(), 441 entry->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(entry.get(),
497 &AutomationProxyCacheEntry::AddDelegate, delegate)); 442 &AutomationProxyCacheEntry::AddDelegate, delegate));
498 } 443 }
499 444
500 DCHECK(automation_server_id != NULL); 445 DCHECK(automation_server_id != NULL);
501 DCHECK(!entry->IsSameThread(base::PlatformThread::CurrentId())); 446 DCHECK(!entry->IsSameThread(base::PlatformThread::CurrentId()));
502 447
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 DCHECK_LT(chrome_launch_params_->launch_timeout(), 559 DCHECK_LT(chrome_launch_params_->launch_timeout(),
615 MAXINT / 2000); 560 MAXINT / 2000);
616 chrome_launch_params_->set_launch_timeout( 561 chrome_launch_params_->set_launch_timeout(
617 chrome_launch_params_->launch_timeout() * 2); 562 chrome_launch_params_->launch_timeout() * 2);
618 } 563 }
619 #endif // NDEBUG 564 #endif // NDEBUG
620 565
621 // Create a window on the UI thread for marshaling messages back and forth 566 // Create a window on the UI thread for marshaling messages back and forth
622 // from the IPC thread. This window cannot be a message only window as the 567 // from the IPC thread. This window cannot be a message only window as the
623 // external chrome tab window is created as a child of this window. This 568 // external chrome tab window is created as a child of this window. This
624 // window is eventually reparented to the ActiveX/NPAPI plugin window. 569 // window is eventually reparented to the ActiveX plugin window.
625 if (!Create(GetDesktopWindow(), NULL, NULL, 570 if (!Create(GetDesktopWindow(), NULL, NULL,
626 WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 571 WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
627 WS_EX_TOOLWINDOW)) { 572 WS_EX_TOOLWINDOW)) {
628 NOTREACHED(); 573 NOTREACHED();
629 return false; 574 return false;
630 } 575 }
631 576
632 // Keep object in memory, while the window is alive. 577 // Keep object in memory, while the window is alive.
633 // Corresponding Release is in OnFinalMessage(); 578 // Corresponding Release is in OnFinalMessage();
634 AddRef(); 579 AddRef();
(...skipping 15 matching lines...) Expand all
650 595
651 void ChromeFrameAutomationClient::Uninitialize() { 596 void ChromeFrameAutomationClient::Uninitialize() {
652 if (init_state_ == UNINITIALIZED) { 597 if (init_state_ == UNINITIALIZED) {
653 DLOG(WARNING) << __FUNCTION__ << ": Automation client not initialized"; 598 DLOG(WARNING) << __FUNCTION__ << ": Automation client not initialized";
654 return; 599 return;
655 } 600 }
656 601
657 init_state_ = UNINITIALIZING; 602 init_state_ = UNINITIALIZING;
658 603
659 // Called from client's FinalRelease() / destructor 604 // Called from client's FinalRelease() / destructor
660 // ChromeFrameAutomationClient may wait for the initialization (launch)
661 // to complete while Uninitialize is called.
662 // We either have to:
663 // 1) Make ReleaseAutomationServer blocking call (wait until thread exits)
664 // 2) Behave like a COM object i.e. increase module lock count.
665 // Otherwise the DLL may get unloaded while we have running threads.
666 // Unfortunately in NPAPI case we cannot increase module lock count, hence
667 // we stick with blocking/waiting
668 if (url_fetcher_) { 605 if (url_fetcher_) {
669 // Clean up any outstanding requests 606 // Clean up any outstanding requests
670 url_fetcher_->StopAllRequests(); 607 url_fetcher_->StopAllRequests();
671 url_fetcher_ = NULL; 608 url_fetcher_ = NULL;
672 } 609 }
673 610
674 if (tab_) { 611 if (tab_) {
675 tab_->RemoveObserver(this); 612 tab_->RemoveObserver(this);
676 if (automation_server_) 613 if (automation_server_)
677 automation_server_->ReleaseTabProxy(tab_->handle()); 614 automation_server_->ReleaseTabProxy(tab_->handle());
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 } 987 }
1051 break; 988 break;
1052 } 989 }
1053 990
1054 PostTask(FROM_HERE, NewRunnableMethod(this, 991 PostTask(FROM_HERE, NewRunnableMethod(this,
1055 &ChromeFrameAutomationClient::ProcessUrlRequestMessage, tab, msg, true)); 992 &ChromeFrameAutomationClient::ProcessUrlRequestMessage, tab, msg, true));
1056 return true; 993 return true;
1057 } 994 }
1058 995
1059 // These are invoked in channel's background thread. 996 // These are invoked in channel's background thread.
1060 // Cannot call any method of the activex/npapi here since they are STA 997 // Cannot call any method of the activex here since it is a STA kind of being.
1061 // kind of beings.
1062 // By default we marshal the IPC message to the main/GUI thread and from there 998 // By default we marshal the IPC message to the main/GUI thread and from there
1063 // we safely invoke chrome_frame_delegate_->OnMessageReceived(msg). 999 // we safely invoke chrome_frame_delegate_->OnMessageReceived(msg).
1064 bool ChromeFrameAutomationClient::OnMessageReceived(TabProxy* tab, 1000 bool ChromeFrameAutomationClient::OnMessageReceived(TabProxy* tab,
1065 const IPC::Message& msg) { 1001 const IPC::Message& msg) {
1066 DCHECK(tab == tab_.get()); 1002 DCHECK(tab == tab_.get());
1067 // Quickly process network related messages. 1003 // Quickly process network related messages.
1068 if (url_fetcher_ && ProcessUrlRequestMessage(tab, msg, false)) 1004 if (url_fetcher_ && ProcessUrlRequestMessage(tab, msg, false))
1069 return true; 1005 return true;
1070 1006
1071 // Early check to avoid needless marshaling 1007 // Early check to avoid needless marshaling
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 const net::URLRequestStatus& status) { 1287 const net::URLRequestStatus& status) {
1352 automation_server_->Send(new AutomationMsg_RequestEnd( 1288 automation_server_->Send(new AutomationMsg_RequestEnd(
1353 tab_->handle(), request_id, status)); 1289 tab_->handle(), request_id, status));
1354 } 1290 }
1355 1291
1356 void ChromeFrameAutomationClient::OnCookiesRetrieved(bool success, 1292 void ChromeFrameAutomationClient::OnCookiesRetrieved(bool success,
1357 const GURL& url, const std::string& cookie_string, int cookie_id) { 1293 const GURL& url, const std::string& cookie_string, int cookie_id) {
1358 automation_server_->Send(new AutomationMsg_GetCookiesHostResponse( 1294 automation_server_->Send(new AutomationMsg_GetCookiesHostResponse(
1359 tab_->handle(), success, url, cookie_string, cookie_id)); 1295 tab_->handle(), success, url, cookie_string, cookie_id));
1360 } 1296 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698