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

Side by Side Diff: chrome_frame/chrome_frame_automation.cc

Issue 3061036: Handle automation server crashes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 4 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
« no previous file with comments | « chrome_frame/chrome_frame_automation.h ('k') | chrome_frame/chrome_frame_npapi_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #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/trace_event.h" 10 #include "base/trace_event.h"
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 InvokeCallback<GetEnabledExtensionsContext>(msg, context); 119 InvokeCallback<GetEnabledExtensionsContext>(msg, context);
120 break; 120 break;
121 default: 121 default:
122 NOTREACHED(); 122 NOTREACHED();
123 } 123 }
124 return true; 124 return true;
125 } 125 }
126 }; 126 };
127 127
128 ChromeFrameAutomationProxyImpl::ChromeFrameAutomationProxyImpl( 128 ChromeFrameAutomationProxyImpl::ChromeFrameAutomationProxyImpl(
129 int launch_timeout) 129 AutomationProxyCacheEntry* entry, int launch_timeout)
130 : AutomationProxy(launch_timeout) { 130 : AutomationProxy(launch_timeout), proxy_entry_(entry) {
131 TRACE_EVENT_BEGIN("chromeframe.automationproxy", this, ""); 131 TRACE_EVENT_BEGIN("chromeframe.automationproxy", this, "");
132 132
133 sync_ = new CFMsgDispatcher(); 133 sync_ = new CFMsgDispatcher();
134 message_filter_ = new TabProxyNotificationMessageFilter(tracker_.get()); 134 message_filter_ = new TabProxyNotificationMessageFilter(tracker_.get());
135
135 // Order of filters is not important. 136 // Order of filters is not important.
136 channel_->AddFilter(message_filter_.get()); 137 channel_->AddFilter(message_filter_.get());
137 channel_->AddFilter(sync_.get()); 138 channel_->AddFilter(sync_.get());
138 } 139 }
139 140
140 ChromeFrameAutomationProxyImpl::~ChromeFrameAutomationProxyImpl() { 141 ChromeFrameAutomationProxyImpl::~ChromeFrameAutomationProxyImpl() {
141 TRACE_EVENT_END("chromeframe.automationproxy", this, ""); 142 TRACE_EVENT_END("chromeframe.automationproxy", this, "");
142 } 143 }
143 144
144 void ChromeFrameAutomationProxyImpl::SendAsAsync( 145 void ChromeFrameAutomationProxyImpl::SendAsAsync(
145 IPC::SyncMessage* msg, 146 IPC::SyncMessage* msg,
146 SyncMessageReplyDispatcher::SyncMessageCallContext* context, void* key) { 147 SyncMessageReplyDispatcher::SyncMessageCallContext* context, void* key) {
147 sync_->Push(msg, context, key); 148 sync_->Push(msg, context, key);
148 channel_->ChannelProxy::Send(msg); 149 channel_->ChannelProxy::Send(msg);
149 } 150 }
150 151
151 void ChromeFrameAutomationProxyImpl::CancelAsync(void* key) { 152 void ChromeFrameAutomationProxyImpl::CancelAsync(void* key) {
152 sync_->Cancel(key); 153 sync_->Cancel(key);
153 } 154 }
154 155
156 void ChromeFrameAutomationProxyImpl::OnChannelError() {
157 DLOG(ERROR) << "Automation server died";
158 if (proxy_entry_) {
159 proxy_entry_->OnChannelError();
160 } else {
161 NOTREACHED();
162 }
163 }
164
155 scoped_refptr<TabProxy> ChromeFrameAutomationProxyImpl::CreateTabProxy( 165 scoped_refptr<TabProxy> ChromeFrameAutomationProxyImpl::CreateTabProxy(
156 int handle) { 166 int handle) {
157 DCHECK(tracker_->GetResource(handle) == NULL); 167 DCHECK(tracker_->GetResource(handle) == NULL);
158 TabProxy* tab_proxy = new TabProxy(this, tracker_.get(), handle); 168 TabProxy* tab_proxy = new TabProxy(this, tracker_.get(), handle);
159 if (tab_proxy != NULL) 169 if (tab_proxy != NULL)
160 message_filter_->AddTabProxy(handle); 170 message_filter_->AddTabProxy(handle);
161 return tab_proxy; 171 return tab_proxy;
162 } 172 }
163 173
164 void ChromeFrameAutomationProxyImpl::ReleaseTabProxy(AutomationHandle handle) { 174 void ChromeFrameAutomationProxyImpl::ReleaseTabProxy(AutomationHandle handle) {
(...skipping 16 matching lines...) Expand all
181 launch_milliseconds << " ms."; 191 launch_milliseconds << " ms.";
182 } 192 }
183 } 193 }
184 194
185 base::Time launch_time_begin_; 195 base::Time launch_time_begin_;
186 #else 196 #else
187 void Dump() {} 197 void Dump() {}
188 #endif 198 #endif
189 }; 199 };
190 200
191 ProxyFactory::ProxyCacheEntry::ProxyCacheEntry(const std::wstring& profile) 201 DISABLE_RUNNABLE_METHOD_REFCOUNT(AutomationProxyCacheEntry);
192 : proxy(NULL), profile_name(profile), ref_count(1), 202
193 launch_result(AutomationLaunchResult(-1)) { 203 AutomationProxyCacheEntry::AutomationProxyCacheEntry(
194 thread.reset(new base::Thread(WideToASCII(profile_name).c_str())); 204 ChromeFrameLaunchParams* params, LaunchDelegate* delegate)
195 thread->Start(); 205 : profile_name(params->profile_name()),
206 launch_result_(AUTOMATION_LAUNCH_RESULT_INVALID),
207 snapshots_(NULL), uma_send_interval_(1) {
208 DCHECK(delegate);
209 thread_.reset(new base::Thread(WideToASCII(profile_name).c_str()));
210 thread_->Start();
211 thread_->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this,
212 &AutomationProxyCacheEntry::CreateProxy, params, delegate));
196 } 213 }
197 214
198 DISABLE_RUNNABLE_METHOD_REFCOUNT(ProxyFactory); 215 AutomationProxyCacheEntry::~AutomationProxyCacheEntry() {
199 216 DLOG(INFO) << __FUNCTION__ << profile_name;
200 ProxyFactory::ProxyFactory()
201 : uma_send_interval_(0) {
202 uma_send_interval_ = GetConfigInt(kDefaultSendUMADataInterval,
203 kUmaSendIntervalValue);
204 } 217 }
205 218
206 ProxyFactory::~ProxyFactory() { 219 void AutomationProxyCacheEntry::StartSendUmaInterval(
207 for (size_t i = 0; i < proxies_.container().size(); ++i) { 220 ChromeFrameHistogramSnapshots* snapshots, int send_interval) {
208 DWORD result = WaitForSingleObject(proxies_[i]->thread->thread_handle(), 0); 221 DCHECK(snapshots);
209 if (WAIT_OBJECT_0 != result) 222 DCHECK(!snapshots_);
210 // TODO(stoyan): Don't leak proxies on exit. 223 snapshots_ = snapshots;
211 DLOG(ERROR) << "Proxies leaked on exit."; 224 uma_send_interval_ = send_interval;
212 } 225 thread_->message_loop()->PostDelayedTask(FROM_HERE,
226 NewRunnableMethod(this, &AutomationProxyCacheEntry::SendUMAData),
227 send_interval);
213 } 228 }
214 229
215 void ProxyFactory::GetAutomationServer( 230 void AutomationProxyCacheEntry::CreateProxy(ChromeFrameLaunchParams* params,
216 LaunchDelegate* delegate, const ChromeFrameLaunchParams& params, 231 LaunchDelegate* delegate) {
217 void** automation_server_id) { 232 DCHECK(IsSameThread(PlatformThread::CurrentId()));
218 TRACE_EVENT_BEGIN("chromeframe.createproxy", this, ""); 233 DCHECK(delegate);
219 234 DCHECK(params);
220 ProxyCacheEntry* entry = NULL; 235 DCHECK(proxy_.get() == NULL);
221 // Find already existing launcher thread for given profile
222 AutoLock lock(lock_);
223 for (size_t i = 0; i < proxies_.container().size(); ++i) {
224 if (!lstrcmpiW(proxies_[i]->profile_name.c_str(),
225 params.profile_name.c_str())) {
226 entry = proxies_[i];
227 DCHECK(entry->thread.get() != NULL);
228 break;
229 }
230 }
231
232 if (entry == NULL) {
233 entry = new ProxyCacheEntry(params.profile_name);
234 proxies_.container().push_back(entry);
235 } else {
236 entry->ref_count++;
237 }
238
239 DCHECK(delegate != NULL);
240 DCHECK(automation_server_id != NULL);
241
242 *automation_server_id = entry;
243 // Note we always queue request to the launch thread, even if we already
244 // have established proxy object. A simple lock around entry->proxy = proxy
245 // would allow calling LaunchDelegate directly from here if
246 // entry->proxy != NULL. Drawback is that callback may be invoked either in
247 // main thread or in background thread, which may confuse the client.
248 entry->thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this,
249 &ProxyFactory::CreateProxy, entry, params, delegate));
250
251 // IE uses the chrome frame provided UMA data uploading scheme. NPAPI
252 // continues to use Chrome to upload UMA data.
253 if (!CrashMetricsReporter::GetInstance()->active()) {
254 entry->thread->message_loop()->PostDelayedTask(FROM_HERE,
255 NewRunnableMethod(this, &ProxyFactory::SendUMAData, entry),
256 uma_send_interval_);
257 }
258 }
259
260 void ProxyFactory::CreateProxy(ProxyFactory::ProxyCacheEntry* entry,
261 const ChromeFrameLaunchParams& params,
262 LaunchDelegate* delegate) {
263 DCHECK(entry->thread->thread_id() == PlatformThread::CurrentId());
264 if (entry->proxy) {
265 delegate->LaunchComplete(entry->proxy, entry->launch_result);
266 return;
267 }
268 236
269 // We *must* create automationproxy in a thread that has message loop, 237 // We *must* create automationproxy in a thread that has message loop,
270 // since SyncChannel::Context construction registers event to be watched 238 // since SyncChannel::Context construction registers event to be watched
271 // through ObjectWatcher which subscribes for the current thread message loop 239 // through ObjectWatcher which subscribes for the current thread message loop
272 // destruction notification. 240 // destruction notification.
273 241
274 // At same time we must destroy/stop the thread from another thread. 242 // At same time we must destroy/stop the thread from another thread.
275 ChromeFrameAutomationProxyImpl* proxy = 243 ChromeFrameAutomationProxyImpl* proxy =
276 new ChromeFrameAutomationProxyImpl( 244 new ChromeFrameAutomationProxyImpl(this, params->launch_timeout());
277 params.automation_server_launch_timeout);
278 245
279 // Launch browser 246 // Launch browser
280 scoped_ptr<CommandLine> command_line( 247 scoped_ptr<CommandLine> command_line(
281 chrome_launcher::CreateLaunchCommandLine()); 248 chrome_launcher::CreateLaunchCommandLine());
282 command_line->AppendSwitchASCII(switches::kAutomationClientChannelID, 249 command_line->AppendSwitchASCII(switches::kAutomationClientChannelID,
283 proxy->channel_id()); 250 proxy->channel_id());
284 251
285 // Run Chrome in Chrome Frame mode. In practice, this modifies the paths 252 // Run Chrome in Chrome Frame mode. In practice, this modifies the paths
286 // and registry keys that Chrome looks in via the BrowserDistribution 253 // and registry keys that Chrome looks in via the BrowserDistribution
287 // mechanism. 254 // mechanism.
288 command_line->AppendSwitch(switches::kChromeFrame); 255 command_line->AppendSwitch(switches::kChromeFrame);
289 256
290 // Chrome Frame never wants Chrome to start up with a First Run UI. 257 // Chrome Frame never wants Chrome to start up with a First Run UI.
291 command_line->AppendSwitch(switches::kNoFirstRun); 258 command_line->AppendSwitch(switches::kNoFirstRun);
292 259
293 command_line->AppendSwitch(switches::kDisablePopupBlocking); 260 command_line->AppendSwitch(switches::kDisablePopupBlocking);
294 261
295 // Disable the "Whoa! Chrome has crashed." dialog, because that isn't very 262 // Disable the "Whoa! Chrome has crashed." dialog, because that isn't very
296 // useful for Chrome Frame users. 263 // useful for Chrome Frame users.
297 #ifndef NDEBUG 264 #ifndef NDEBUG
298 command_line->AppendSwitch(switches::kNoErrorDialogs); 265 command_line->AppendSwitch(switches::kNoErrorDialogs);
299 #endif 266 #endif
300 267
301 // In headless mode runs like reliability test runs we want full crash dumps 268 // In headless mode runs like reliability test runs we want full crash dumps
302 // from chrome. 269 // from chrome.
303 if (IsHeadlessMode()) 270 if (IsHeadlessMode())
304 command_line->AppendSwitch(switches::kFullMemoryCrashReport); 271 command_line->AppendSwitch(switches::kFullMemoryCrashReport);
305 272
306 DLOG(INFO) << "Profile path: " << params.profile_path.value(); 273 DLOG(INFO) << "Profile path: " << params->profile_path().value();
307 command_line->AppendSwitchPath(switches::kUserDataDir, params.profile_path); 274 command_line->AppendSwitchPath(switches::kUserDataDir,
275 params->profile_path());
308 276
309 std::wstring command_line_string(command_line->command_line_string()); 277 std::wstring command_line_string(command_line->command_line_string());
310 // If there are any extra arguments, append them to the command line. 278 // If there are any extra arguments, append them to the command line.
311 if (!params.extra_chrome_arguments.empty()) { 279 if (!params->extra_arguments().empty()) {
312 command_line_string += L' ' + params.extra_chrome_arguments; 280 command_line_string += L' ' + params->extra_arguments();
313 } 281 }
314 282
315 automation_server_launch_start_time_ = base::TimeTicks::Now(); 283 automation_server_launch_start_time_ = base::TimeTicks::Now();
316 284
317 if (!base::LaunchApp(command_line_string, false, false, NULL)) { 285 if (!base::LaunchApp(command_line_string, false, false, NULL)) {
318 // We have no code for launch failure. 286 // We have no code for launch failure.
319 entry->launch_result = AutomationLaunchResult(-1); 287 launch_result_ = AUTOMATION_LAUNCH_RESULT_INVALID;
320 } else { 288 } else {
321 // Launch timeout may happen if the new instance tries to communicate 289 // Launch timeout may happen if the new instance tries to communicate
322 // with an existing Chrome instance that is hung and displays msgbox 290 // with an existing Chrome instance that is hung and displays msgbox
323 // asking to kill the previous one. This could be easily observed if the 291 // asking to kill the previous one. This could be easily observed if the
324 // already running Chrome instance is running as high-integrity process 292 // already running Chrome instance is running as high-integrity process
325 // (started with "Run as Administrator" or launched by another high 293 // (started with "Run as Administrator" or launched by another high
326 // integrity process) hence our medium-integrity process 294 // integrity process) hence our medium-integrity process
327 // cannot SendMessage to it with request to activate itself. 295 // cannot SendMessage to it with request to activate itself.
328 296
329 // TODO(stoyan) AutomationProxy eats Hello message, hence installing 297 // TODO(stoyan) AutomationProxy eats Hello message, hence installing
330 // message filter is pointless, we can leverage ObjectWatcher and use 298 // message filter is pointless, we can leverage ObjectWatcher and use
331 // system thread pool to notify us when proxy->AppLaunch event is signaled. 299 // system thread pool to notify us when proxy->AppLaunch event is signaled.
332 LaunchTimeStats launch_stats; 300 LaunchTimeStats launch_stats;
333 // Wait for the automation server launch result, then stash away the 301 // Wait for the automation server launch result, then stash away the
334 // version string it reported. 302 // version string it reported.
335 entry->launch_result = proxy->WaitForAppLaunch(); 303 launch_result_ = proxy->WaitForAppLaunch();
336 launch_stats.Dump(); 304 launch_stats.Dump();
337 305
338 base::TimeDelta delta = 306 base::TimeDelta delta =
339 base::TimeTicks::Now() - automation_server_launch_start_time_; 307 base::TimeTicks::Now() - automation_server_launch_start_time_;
340 308
341 if (entry->launch_result == AUTOMATION_SUCCESS) { 309 if (launch_result_ == AUTOMATION_SUCCESS) {
342 THREAD_SAFE_UMA_HISTOGRAM_TIMES( 310 THREAD_SAFE_UMA_HISTOGRAM_TIMES(
343 "ChromeFrame.AutomationServerLaunchSuccessTime", delta); 311 "ChromeFrame.AutomationServerLaunchSuccessTime", delta);
344 } else { 312 } else {
345 THREAD_SAFE_UMA_HISTOGRAM_TIMES( 313 THREAD_SAFE_UMA_HISTOGRAM_TIMES(
346 "ChromeFrame.AutomationServerLaunchFailedTime", delta); 314 "ChromeFrame.AutomationServerLaunchFailedTime", delta);
347 } 315 }
348 316
349 THREAD_SAFE_UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.LaunchResult", 317 THREAD_SAFE_UMA_HISTOGRAM_CUSTOM_COUNTS("ChromeFrame.LaunchResult",
350 entry->launch_result, 318 launch_result_,
351 AUTOMATION_SUCCESS, 319 AUTOMATION_SUCCESS,
352 AUTOMATION_CREATE_TAB_FAILED, 320 AUTOMATION_CREATE_TAB_FAILED,
353 AUTOMATION_CREATE_TAB_FAILED + 1); 321 AUTOMATION_CREATE_TAB_FAILED + 1);
354 } 322 }
355 323
356 TRACE_EVENT_END("chromeframe.createproxy", this, ""); 324 TRACE_EVENT_END("chromeframe.createproxy", this, "");
357 325
358 // Finally set the proxy. 326 // Finally set the proxy.
359 entry->proxy = proxy; 327 proxy_.reset(proxy);
360 delegate->LaunchComplete(proxy, entry->launch_result); 328 launch_delegates_.push_back(delegate);
361 } 329
362 330 delegate->LaunchComplete(proxy_.get(), launch_result_);
363 bool ProxyFactory::ReleaseAutomationServer(void* server_id) { 331 }
332
333 void AutomationProxyCacheEntry::RemoveDelegate(LaunchDelegate* delegate,
334 base::WaitableEvent* done,
335 bool* was_last_delegate) {
336 DCHECK(IsSameThread(PlatformThread::CurrentId()));
337 DCHECK(delegate);
338 DCHECK(done);
339 DCHECK(was_last_delegate);
340
341 *was_last_delegate = false;
342
343 LaunchDelegates::iterator it = std::find(launch_delegates_.begin(),
344 launch_delegates_.end(), delegate);
345 if (it == launch_delegates_.end()) {
346 NOTREACHED();
347 } else {
348 if (launch_delegates_.size() == 1) {
349 *was_last_delegate = true;
350
351 if (snapshots_)
352 SendUMAData();
353
354 // Take down the proxy since we no longer have any clients.
355 proxy_.reset(NULL);
356
357 // Process pending notifications.
358 thread_->message_loop()->RunAllPending();
359 }
360 // Be careful to remove from the list after running pending
361 // tasks. Otherwise the delegate being removed might miss out
362 // on pending notifications such as LaunchComplete.
363 launch_delegates_.erase(it);
364 }
365
366 done->Signal();
367 }
368
369 void AutomationProxyCacheEntry::AddDelegate(LaunchDelegate* delegate) {
370 DCHECK(IsSameThread(PlatformThread::CurrentId()));
371 DCHECK(std::find(launch_delegates_.begin(),
372 launch_delegates_.end(),
373 delegate) == launch_delegates_.end())
374 << "Same delegate being added twice";
375 DCHECK(launch_result_ != AUTOMATION_LAUNCH_RESULT_INVALID);
376
377 launch_delegates_.push_back(delegate);
378 delegate->LaunchComplete(proxy_.get(), launch_result_);
379 }
380
381 void AutomationProxyCacheEntry::OnChannelError() {
382 DCHECK(IsSameThread(PlatformThread::CurrentId()));
383 launch_result_ = AUTOMATION_SERVER_CRASHED;
384 LaunchDelegates::const_iterator it = launch_delegates_.begin();
385 for (; it != launch_delegates_.end(); ++it) {
386 (*it)->AutomationServerDied();
387 }
388 }
389
390 void AutomationProxyCacheEntry::SendUMAData() {
391 DCHECK(IsSameThread(PlatformThread::CurrentId()));
392 DCHECK(snapshots_);
393 // IE uses the chrome frame provided UMA data uploading scheme. NPAPI
394 // continues to use Chrome to upload UMA data.
395 if (CrashMetricsReporter::GetInstance()->active()) {
396 return;
397 }
398
399 if (!proxy_.get()) {
400 NOTREACHED() << __FUNCTION__ << " Invalid proxy entry";
401 } else {
402 ChromeFrameHistogramSnapshots::HistogramPickledList histograms =
403 snapshots_->GatherAllHistograms();
404
405 if (!histograms.empty()) {
406 proxy_->Send(new AutomationMsg_RecordHistograms(0, histograms));
407 }
408
409 MessageLoop::current()->PostDelayedTask(FROM_HERE,
410 NewRunnableMethod(this, &AutomationProxyCacheEntry::SendUMAData),
411 uma_send_interval_);
412 }
413 }
414
415
416 DISABLE_RUNNABLE_METHOD_REFCOUNT(ProxyFactory);
417
418 ProxyFactory::ProxyFactory()
419 : uma_send_interval_(0) {
420 uma_send_interval_ = GetConfigInt(kDefaultSendUMADataInterval,
421 kUmaSendIntervalValue);
422 }
423
424 ProxyFactory::~ProxyFactory() {
425 for (size_t i = 0; i < proxies_.container().size(); ++i) {
426 DWORD result = proxies_[i]->WaitForThread(0);
427 if (WAIT_OBJECT_0 != result)
428 // TODO(stoyan): Don't leak proxies on exit.
429 DLOG(ERROR) << "Proxies leaked on exit.";
430 }
431 }
432
433 void ProxyFactory::GetAutomationServer(
434 LaunchDelegate* delegate, ChromeFrameLaunchParams* params,
435 void** automation_server_id) {
436 TRACE_EVENT_BEGIN("chromeframe.createproxy", this, "");
437
438 scoped_refptr<AutomationProxyCacheEntry> entry;
439 // Find already existing launcher thread for given profile
440 AutoLock lock(lock_);
441 for (size_t i = 0; i < proxies_.container().size(); ++i) {
442 if (proxies_[i]->IsSameProfile(params->profile_name())) {
443 entry = proxies_[i];
444 break;
445 }
446 }
447
448 if (entry == NULL) {
449 DLOG(INFO) << __FUNCTION__ << " creating new proxy entry";
450 entry = new AutomationProxyCacheEntry(params, delegate);
451 proxies_.container().push_back(entry);
452
453 // IE uses the chrome frame provided UMA data uploading scheme. NPAPI
454 // continues to use Chrome to upload UMA data.
455 if (!CrashMetricsReporter::GetInstance()->active()) {
456 entry->StartSendUmaInterval(&chrome_frame_histograms_,
457 uma_send_interval_);
458 }
459 } else if (delegate) {
460 // Notify the new delegate of the launch status from the worker thread
461 // and add it to the list of delegates.
462 entry->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(entry.get(),
463 &AutomationProxyCacheEntry::AddDelegate, delegate));
464 }
465
466 DCHECK(automation_server_id != NULL);
467 DCHECK(!entry->IsSameThread(PlatformThread::CurrentId()));
468
469 *automation_server_id = entry;
470 }
471
472 bool ProxyFactory::ReleaseAutomationServer(void* server_id,
473 LaunchDelegate* delegate) {
364 if (!server_id) { 474 if (!server_id) {
365 NOTREACHED(); 475 NOTREACHED();
366 return false; 476 return false;
367 } 477 }
368 478
369 ProxyCacheEntry* entry = reinterpret_cast<ProxyCacheEntry*>(server_id); 479 AutomationProxyCacheEntry* entry =
480 reinterpret_cast<AutomationProxyCacheEntry*>(server_id);
370 481
371 #ifndef NDEBUG 482 #ifndef NDEBUG
372 lock_.Acquire(); 483 lock_.Acquire();
373 Vector::ContainerType::iterator it = std::find(proxies_.container().begin(), 484 Vector::ContainerType::iterator it = std::find(proxies_.container().begin(),
374 proxies_.container().end(), 485 proxies_.container().end(),
375 entry); 486 entry);
376 DCHECK(it != proxies_.container().end()); 487 DCHECK(it != proxies_.container().end());
377 DCHECK(entry->thread->thread_id() != PlatformThread::CurrentId()); 488 DCHECK(!entry->IsSameThread(PlatformThread::CurrentId()));
378 DCHECK_GT(entry->ref_count, 0);
379 489
380 lock_.Release(); 490 lock_.Release();
381 #endif 491 #endif
382 492
383 base::WaitableEvent done(true, false); 493 // AddRef the entry object as we might need to take it out of the proxy
384 entry->thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, 494 // stack and then uninitialize the entry.
385 &ProxyFactory::ReleaseProxy, entry, &done)); 495 entry->AddRef();
386 done.Wait(); 496
387 497 bool last_delegate = false;
388 // Stop the thread and destroy the entry if there is no more clients. 498 if (delegate) {
389 if (entry->ref_count == 0) { 499 base::WaitableEvent done(true, false);
390 DCHECK(entry->proxy == NULL); 500 entry->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(entry,
391 entry->thread.reset(); 501 &AutomationProxyCacheEntry::RemoveDelegate, delegate, &done,
392 delete entry; 502 &last_delegate));
393 } 503 done.Wait();
394 504 }
395 return true; 505
396 } 506 if (last_delegate) {
397 507 lock_.Acquire();
398 void ProxyFactory::ReleaseProxy(ProxyCacheEntry* entry,
399 base::WaitableEvent* done) {
400 DCHECK(entry->thread->thread_id() == PlatformThread::CurrentId());
401
402 lock_.Acquire();
403 if (!--entry->ref_count) {
404 Vector::ContainerType::iterator it = std::find(proxies_.container().begin(), 508 Vector::ContainerType::iterator it = std::find(proxies_.container().begin(),
405 proxies_.container().end(), 509 proxies_.container().end(),
406 entry); 510 entry);
407 proxies_->erase(it); 511 proxies_.container().erase(it);
408 } 512 lock_.Release();
409 lock_.Release(); 513 }
410 514
411 // Send pending UMA data if any. 515 entry->Release();
412 if (!entry->ref_count) { 516
413 SendUMAData(entry); 517 return true;
414 delete entry->proxy;
415 entry->proxy = NULL;
416 }
417
418 done->Signal();
419 } 518 }
420 519
421 Singleton<ProxyFactory> g_proxy_factory; 520 Singleton<ProxyFactory> g_proxy_factory;
422 521
423 void ProxyFactory::SendUMAData(ProxyCacheEntry* proxy_entry) {
424 // IE uses the chrome frame provided UMA data uploading scheme. NPAPI
425 // continues to use Chrome to upload UMA data.
426 if (CrashMetricsReporter::GetInstance()->active()) {
427 return;
428 }
429
430 if (!proxy_entry) {
431 NOTREACHED() << __FUNCTION__ << " Invalid proxy entry";
432 return;
433 }
434
435 DCHECK(proxy_entry->thread->thread_id() == PlatformThread::CurrentId());
436
437 if (proxy_entry->proxy) {
438 ChromeFrameHistogramSnapshots::HistogramPickledList histograms =
439 chrome_frame_histograms_.GatherAllHistograms();
440
441 if (!histograms.empty()) {
442 proxy_entry->proxy->Send(
443 new AutomationMsg_RecordHistograms(0, histograms));
444 }
445 } else {
446 DLOG(INFO) << __FUNCTION__ << " No proxy available to service the request";
447 return;
448 }
449
450 MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
451 this, &ProxyFactory::SendUMAData, proxy_entry), uma_send_interval_);
452 }
453
454 template <> struct RunnableMethodTraits<ChromeFrameAutomationClient> { 522 template <> struct RunnableMethodTraits<ChromeFrameAutomationClient> {
455 static void RetainCallee(ChromeFrameAutomationClient* obj) {} 523 static void RetainCallee(ChromeFrameAutomationClient* obj) {}
456 static void ReleaseCallee(ChromeFrameAutomationClient* obj) {} 524 static void ReleaseCallee(ChromeFrameAutomationClient* obj) {}
457 }; 525 };
458 526
459 ChromeFrameAutomationClient::ChromeFrameAutomationClient() 527 ChromeFrameAutomationClient::ChromeFrameAutomationClient()
460 : chrome_frame_delegate_(NULL), 528 : chrome_frame_delegate_(NULL),
461 chrome_window_(NULL), 529 chrome_window_(NULL),
462 tab_window_(NULL), 530 tab_window_(NULL),
463 parent_window_(NULL), 531 parent_window_(NULL),
(...skipping 11 matching lines...) Expand all
475 navigate_after_initialization_(false) { 543 navigate_after_initialization_(false) {
476 } 544 }
477 545
478 ChromeFrameAutomationClient::~ChromeFrameAutomationClient() { 546 ChromeFrameAutomationClient::~ChromeFrameAutomationClient() {
479 // Uninitialize must be called prior to the destructor 547 // Uninitialize must be called prior to the destructor
480 DCHECK(automation_server_ == NULL); 548 DCHECK(automation_server_ == NULL);
481 } 549 }
482 550
483 bool ChromeFrameAutomationClient::Initialize( 551 bool ChromeFrameAutomationClient::Initialize(
484 ChromeFrameDelegate* chrome_frame_delegate, 552 ChromeFrameDelegate* chrome_frame_delegate,
485 const ChromeFrameLaunchParams& chrome_launch_params) { 553 ChromeFrameLaunchParams* chrome_launch_params) {
486 DCHECK(!IsWindow()); 554 DCHECK(!IsWindow());
487 chrome_frame_delegate_ = chrome_frame_delegate; 555 chrome_frame_delegate_ = chrome_frame_delegate;
488 556
557 #ifndef NDEBUG
558 if (chrome_launch_params_ && chrome_launch_params_ != chrome_launch_params) {
559 DCHECK_EQ(chrome_launch_params_->url(), chrome_launch_params->url());
560 DCHECK_EQ(chrome_launch_params_->referrer(),
561 chrome_launch_params->referrer());
562 }
563 #endif
564
489 chrome_launch_params_ = chrome_launch_params; 565 chrome_launch_params_ = chrome_launch_params;
490 566
491 ui_thread_id_ = PlatformThread::CurrentId(); 567 ui_thread_id_ = PlatformThread::CurrentId();
492 #ifndef NDEBUG 568 #ifndef NDEBUG
493 // In debug mode give more time to work with a debugger. 569 // In debug mode give more time to work with a debugger.
494 if (IsDebuggerPresent()) { 570 if (IsDebuggerPresent()) {
495 // Don't use INFINITE (which is -1) or even MAXINT since we will convert 571 // Don't use INFINITE (which is -1) or even MAXINT since we will convert
496 // from milliseconds to microseconds when stored in a base::TimeDelta, 572 // from milliseconds to microseconds when stored in a base::TimeDelta,
497 // thus * 1000. An hour should be enough. 573 // thus * 1000. An hour should be enough.
498 chrome_launch_params_.automation_server_launch_timeout = 60 * 60 * 1000; 574 chrome_launch_params_->set_launch_timeout(60 * 60 * 1000);
499 } else { 575 } else {
500 DCHECK_LT(chrome_launch_params_.automation_server_launch_timeout, 576 DCHECK_LT(chrome_launch_params_->launch_timeout(),
501 MAXINT / 2000); 577 MAXINT / 2000);
502 chrome_launch_params_.automation_server_launch_timeout *= 2; 578 chrome_launch_params_->set_launch_timeout(
579 chrome_launch_params_->launch_timeout() * 2);
503 } 580 }
504 #endif // NDEBUG 581 #endif // NDEBUG
505 582
506 // Create a window on the UI thread for marshaling messages back and forth 583 // Create a window on the UI thread for marshaling messages back and forth
507 // from the IPC thread. This window cannot be a message only window as the 584 // from the IPC thread. This window cannot be a message only window as the
508 // external chrome tab window is created as a child of this window. This 585 // external chrome tab window is created as a child of this window. This
509 // window is eventually reparented to the ActiveX/NPAPI plugin window. 586 // window is eventually reparented to the ActiveX/NPAPI plugin window.
510 if (!Create(GetDesktopWindow(), NULL, NULL, 587 if (!Create(GetDesktopWindow(), NULL, NULL,
511 WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 588 WS_CHILDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
512 WS_EX_TOOLWINDOW)) { 589 WS_EX_TOOLWINDOW)) {
513 NOTREACHED(); 590 NOTREACHED();
514 return false; 591 return false;
515 } 592 }
516 593
517 // Keep object in memory, while the window is alive. 594 // Keep object in memory, while the window is alive.
518 // Corresponsing Release is in OnFinalMessage(); 595 // Corresponding Release is in OnFinalMessage();
519 AddRef(); 596 AddRef();
520 597
521 // Mark our state as initializing. We'll reach initialized once 598 // Mark our state as initializing. We'll reach initialized once
522 // InitializeComplete is called successfully. 599 // InitializeComplete is called successfully.
523 init_state_ = INITIALIZING; 600 init_state_ = INITIALIZING;
524 601
525 if (chrome_launch_params_.url.is_valid()) 602 if (chrome_launch_params_->url().is_valid())
526 navigate_after_initialization_ = false; 603 navigate_after_initialization_ = false;
527 604
528 proxy_factory_->GetAutomationServer( 605 proxy_factory_->GetAutomationServer(static_cast<LaunchDelegate*>(this),
529 static_cast<ProxyFactory::LaunchDelegate*>(this),
530 chrome_launch_params_, &automation_server_id_); 606 chrome_launch_params_, &automation_server_id_);
531 607
532 return true; 608 return true;
533 } 609 }
534 610
535 void ChromeFrameAutomationClient::Uninitialize() { 611 void ChromeFrameAutomationClient::Uninitialize() {
536 if (init_state_ == UNINITIALIZED) { 612 if (init_state_ == UNINITIALIZED) {
537 DLOG(WARNING) << __FUNCTION__ << ": Automation client not initialized"; 613 DLOG(WARNING) << __FUNCTION__ << ": Automation client not initialized";
538 return; 614 return;
539 } 615 }
(...skipping 24 matching lines...) Expand all
564 640
565 // Wait for the background thread to exit. 641 // Wait for the background thread to exit.
566 ReleaseAutomationServer(); 642 ReleaseAutomationServer();
567 643
568 // We must destroy the window, since if there are pending tasks 644 // We must destroy the window, since if there are pending tasks
569 // window procedure may be invoked after DLL is unloaded. 645 // window procedure may be invoked after DLL is unloaded.
570 // Unfortunately pending tasks are leaked. 646 // Unfortunately pending tasks are leaked.
571 if (::IsWindow(m_hWnd)) 647 if (::IsWindow(m_hWnd))
572 DestroyWindow(); 648 DestroyWindow();
573 649
650 DCHECK(navigate_after_initialization_ == false);
651 handle_top_level_requests_ = false;
652 ui_thread_id_ = 0;
574 chrome_frame_delegate_ = NULL; 653 chrome_frame_delegate_ = NULL;
575 init_state_ = UNINITIALIZED; 654 init_state_ = UNINITIALIZED;
576 } 655 }
577 656
578 bool ChromeFrameAutomationClient::InitiateNavigation( 657 bool ChromeFrameAutomationClient::InitiateNavigation(const std::string& url,
579 const std::string& url, const std::string& referrer, bool is_privileged) { 658 const std::string& referrer, bool is_privileged) {
580 if (url.empty()) 659 if (url.empty())
581 return false; 660 return false;
582 661
583 GURL parsed_url(url); 662 GURL parsed_url(url);
584 // Catch invalid URLs early. 663 // Catch invalid URLs early.
585 if (!parsed_url.is_valid() || 664 if (!parsed_url.is_valid() ||
586 !IsValidUrlScheme(UTF8ToWide(url), is_privileged)) { 665 !IsValidUrlScheme(UTF8ToWide(url), is_privileged)) {
587 DLOG(ERROR) << "Invalid URL passed to InitiateNavigation: " << url 666 DLOG(ERROR) << "Invalid URL passed to InitiateNavigation: " << url
588 << " is_privileged=" << is_privileged; 667 << " is_privileged=" << is_privileged;
589 return false; 668 return false;
590 } 669 }
591 670
592 if (parsed_url != chrome_launch_params_.url) { 671 if (!chrome_launch_params_ || parsed_url != chrome_launch_params_->url()) {
593 // Important: Since we will be using the referrer_ variable from a 672 // Important: Since we will be using the referrer_ variable from a
594 // different thread, we need to force a new std::string buffer instance for 673 // different thread, we need to force a new std::string buffer instance for
595 // the referrer_ GURL variable. Otherwise we can run into strangeness when 674 // the referrer_ GURL variable. Otherwise we can run into strangeness when
596 // the GURL is accessed and it could result in a bad URL that can cause the 675 // the GURL is accessed and it could result in a bad URL that can cause the
597 // referrer to be dropped or something worse. 676 // referrer to be dropped or something worse.
598 chrome_launch_params_.referrer = GURL(referrer.c_str()); 677 GURL referrer_gurl(referrer.c_str());
599 chrome_launch_params_.url = parsed_url; 678 if (!chrome_launch_params_) {
679 FilePath profile_path;
680 chrome_launch_params_ = new ChromeFrameLaunchParams(parsed_url,
681 referrer_gurl, profile_path, L"", L"", false, false);
682 } else {
683 chrome_launch_params_->set_referrer(referrer_gurl);
684 chrome_launch_params_->set_url(parsed_url);
685 }
600 686
601 navigate_after_initialization_ = false; 687 navigate_after_initialization_ = false;
602 688
603 if (is_initialized()) { 689 if (is_initialized()) {
604 BeginNavigate(chrome_launch_params_.url, chrome_launch_params_.referrer); 690 BeginNavigate();
605 } else { 691 } else {
606 navigate_after_initialization_ = true; 692 navigate_after_initialization_ = true;
607 } 693 }
608 } 694 }
609 695
610 return true; 696 return true;
611 } 697 }
612 698
613 bool ChromeFrameAutomationClient::NavigateToIndex(int index) { 699 bool ChromeFrameAutomationClient::NavigateToIndex(int index) {
614 // Could be NULL if we failed to launch Chrome in LaunchAutomationServer() 700 // Could be NULL if we failed to launch Chrome in LaunchAutomationServer()
(...skipping 22 matching lines...) Expand all
637 } 723 }
638 724
639 bool ChromeFrameAutomationClient::SetProxySettings( 725 bool ChromeFrameAutomationClient::SetProxySettings(
640 const std::string& json_encoded_proxy_settings) { 726 const std::string& json_encoded_proxy_settings) {
641 if (!is_initialized()) 727 if (!is_initialized())
642 return false; 728 return false;
643 automation_server_->SendProxyConfig(json_encoded_proxy_settings); 729 automation_server_->SendProxyConfig(json_encoded_proxy_settings);
644 return true; 730 return true;
645 } 731 }
646 732
647 void ChromeFrameAutomationClient::BeginNavigate(const GURL& url, 733 void ChromeFrameAutomationClient::BeginNavigate() {
648 const GURL& referrer) {
649 // Could be NULL if we failed to launch Chrome in LaunchAutomationServer() 734 // Could be NULL if we failed to launch Chrome in LaunchAutomationServer()
650 if (!automation_server_ || !tab_.get()) { 735 if (!automation_server_ || !tab_.get()) {
651 DLOG(WARNING) << "BeginNavigate - can't navigate."; 736 DLOG(WARNING) << "BeginNavigate - can't navigate.";
652 ReportNavigationError(AUTOMATION_MSG_NAVIGATION_ERROR, 737 ReportNavigationError(AUTOMATION_MSG_NAVIGATION_ERROR,
653 chrome_launch_params_.url.spec()); 738 chrome_launch_params_->url().spec());
654 return; 739 return;
655 } 740 }
656 741
657 DCHECK(::IsWindow(chrome_window_)); 742 DCHECK(::IsWindow(chrome_window_));
658 743
659 if (!tab_->is_valid()) { 744 if (!tab_->is_valid()) {
660 DLOG(WARNING) << "BeginNavigate - tab isn't valid."; 745 DLOG(WARNING) << "BeginNavigate - tab isn't valid.";
661 return; 746 return;
662 } 747 }
663 748
664 IPC::SyncMessage* msg = 749 IPC::SyncMessage* msg =
665 new AutomationMsg_NavigateInExternalTab(0, tab_->handle(), url, 750 new AutomationMsg_NavigateInExternalTab(0, tab_->handle(),
666 referrer, NULL); 751 chrome_launch_params_->url(), chrome_launch_params_->referrer(),
752 NULL);
667 automation_server_->SendAsAsync(msg, new BeginNavigateContext(this), this); 753 automation_server_->SendAsAsync(msg, new BeginNavigateContext(this), this);
668 754
669 RECT client_rect = {0}; 755 RECT client_rect = {0};
670 chrome_frame_delegate_->GetBounds(&client_rect); 756 chrome_frame_delegate_->GetBounds(&client_rect);
671 Resize(client_rect.right - client_rect.left, 757 Resize(client_rect.right - client_rect.left,
672 client_rect.bottom - client_rect.top, 758 client_rect.bottom - client_rect.top,
673 SWP_NOACTIVATE | SWP_NOZORDER); 759 SWP_NOACTIVATE | SWP_NOZORDER);
674 } 760 }
675 761
676 void ChromeFrameAutomationClient::BeginNavigateCompleted( 762 void ChromeFrameAutomationClient::BeginNavigateCompleted(
677 AutomationMsg_NavigationResponseValues result) { 763 AutomationMsg_NavigationResponseValues result) {
678 if (result == AUTOMATION_MSG_NAVIGATION_ERROR) 764 if (result == AUTOMATION_MSG_NAVIGATION_ERROR)
679 ReportNavigationError(AUTOMATION_MSG_NAVIGATION_ERROR, 765 ReportNavigationError(AUTOMATION_MSG_NAVIGATION_ERROR,
680 chrome_launch_params_.url.spec()); 766 chrome_launch_params_->url().spec());
681 } 767 }
682 768
683 void ChromeFrameAutomationClient::FindInPage(const std::wstring& search_string, 769 void ChromeFrameAutomationClient::FindInPage(const std::wstring& search_string,
684 FindInPageDirection forward, 770 FindInPageDirection forward,
685 FindInPageCase match_case, 771 FindInPageCase match_case,
686 bool find_next) { 772 bool find_next) {
687 DCHECK(tab_.get()); 773 DCHECK(tab_.get());
688 774
689 // What follows is quite similar to TabProxy::FindInPage() but uses 775 // What follows is quite similar to TabProxy::FindInPage() but uses
690 // the SyncMessageReplyDispatcher to avoid concerns about blocking 776 // the SyncMessageReplyDispatcher to avoid concerns about blocking
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 876
791 // The context will delete itself after it is called. 877 // The context will delete itself after it is called.
792 automation_server_->SendAsAsync(msg, ctx, this); 878 automation_server_->SendAsAsync(msg, ctx, this);
793 } 879 }
794 880
795 void ChromeFrameAutomationClient::CreateExternalTab() { 881 void ChromeFrameAutomationClient::CreateExternalTab() {
796 AutomationLaunchResult launch_result = AUTOMATION_SUCCESS; 882 AutomationLaunchResult launch_result = AUTOMATION_SUCCESS;
797 DCHECK(IsWindow()); 883 DCHECK(IsWindow());
798 DCHECK(automation_server_ != NULL); 884 DCHECK(automation_server_ != NULL);
799 885
800 if (chrome_launch_params_.url.is_valid()) { 886 if (chrome_launch_params_->url().is_valid()) {
801 navigate_after_initialization_ = false; 887 navigate_after_initialization_ = false;
802 } 888 }
803 889
804 const IPC::ExternalTabSettings settings = { 890 const IPC::ExternalTabSettings settings = {
805 m_hWnd, 891 m_hWnd,
806 gfx::Rect(), 892 gfx::Rect(),
807 WS_CHILD, 893 WS_CHILD,
808 chrome_launch_params_.incognito_mode, 894 chrome_launch_params_->incognito(),
809 !use_chrome_network_, 895 !use_chrome_network_,
810 handle_top_level_requests_, 896 handle_top_level_requests_,
811 chrome_launch_params_.url, 897 chrome_launch_params_->url(),
812 chrome_launch_params_.referrer, 898 chrome_launch_params_->referrer(),
813 !chrome_launch_params_.is_widget_mode // Infobars disabled in widget mode. 899 !chrome_launch_params_->widget_mode() // Infobars disabled in widget mode.
814 }; 900 };
815 901
816 THREAD_SAFE_UMA_HISTOGRAM_CUSTOM_COUNTS( 902 THREAD_SAFE_UMA_HISTOGRAM_CUSTOM_COUNTS(
817 "ChromeFrame.HostNetworking", !use_chrome_network_, 0, 1, 2); 903 "ChromeFrame.HostNetworking", !use_chrome_network_, 0, 1, 2);
818 904
819 THREAD_SAFE_UMA_HISTOGRAM_CUSTOM_COUNTS( 905 THREAD_SAFE_UMA_HISTOGRAM_CUSTOM_COUNTS(
820 "ChromeFrame.HandleTopLevelRequests", handle_top_level_requests_, 0, 1, 906 "ChromeFrame.HandleTopLevelRequests", handle_top_level_requests_, 0, 1,
821 2); 907 2);
822 908
823 IPC::SyncMessage* message = 909 IPC::SyncMessage* message =
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 DLOG(INFO) << __FUNCTION__ << ": sending CreateExternalTabComplete"; 983 DLOG(INFO) << __FUNCTION__ << ": sending CreateExternalTabComplete";
898 } 984 }
899 } 985 }
900 } else { 986 } else {
901 // Launch failed. Note, we cannot delete proxy here. 987 // Launch failed. Note, we cannot delete proxy here.
902 PostTask(FROM_HERE, NewRunnableMethod(this, 988 PostTask(FROM_HERE, NewRunnableMethod(this,
903 &ChromeFrameAutomationClient::InitializeComplete, result)); 989 &ChromeFrameAutomationClient::InitializeComplete, result));
904 } 990 }
905 } 991 }
906 992
993 void ChromeFrameAutomationClient::AutomationServerDied() {
994 // Make sure we notify our delegate.
995 PostTask(FROM_HERE, NewRunnableMethod(this,
996 &ChromeFrameAutomationClient::InitializeComplete,
997 AUTOMATION_SERVER_CRASHED));
998 // Then uninitialize.
999 PostTask(FROM_HERE, NewRunnableMethod(this,
1000 &ChromeFrameAutomationClient::Uninitialize));
1001 }
1002
907 void ChromeFrameAutomationClient::InitializeComplete( 1003 void ChromeFrameAutomationClient::InitializeComplete(
908 AutomationLaunchResult result) { 1004 AutomationLaunchResult result) {
909 DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_); 1005 DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_);
910 std::string version = automation_server_->server_version(); 1006 std::string version = automation_server_->server_version();
911 1007
912 if (result != AUTOMATION_SUCCESS) { 1008 if (result != AUTOMATION_SUCCESS) {
913 DLOG(WARNING) << "InitializeComplete: failure " << result; 1009 DLOG(WARNING) << "InitializeComplete: failure " << result;
914 ReleaseAutomationServer(); 1010 ReleaseAutomationServer();
915 } else { 1011 } else {
916 init_state_ = INITIALIZED; 1012 init_state_ = INITIALIZED;
917 1013
918 // If the host already have a window, ask Chrome to re-parent. 1014 // If the host already have a window, ask Chrome to re-parent.
919 if (parent_window_) 1015 if (parent_window_)
920 SetParentWindow(parent_window_); 1016 SetParentWindow(parent_window_);
921 1017
922 // If host specified destination URL - navigate. Apparently we do not use 1018 // If host specified destination URL - navigate. Apparently we do not use
923 // accelerator table. 1019 // accelerator table.
924 if (navigate_after_initialization_) { 1020 if (navigate_after_initialization_) {
925 BeginNavigate(chrome_launch_params_.url, 1021 navigate_after_initialization_ = false;
926 chrome_launch_params_.referrer); 1022 BeginNavigate();
927 } 1023 }
928 } 1024 }
929 1025
930 if (chrome_frame_delegate_) { 1026 if (chrome_frame_delegate_) {
931 if (result == AUTOMATION_SUCCESS) { 1027 if (result == AUTOMATION_SUCCESS) {
932 chrome_frame_delegate_->OnAutomationServerReady(); 1028 chrome_frame_delegate_->OnAutomationServerReady();
933 } else { 1029 } else {
934 chrome_frame_delegate_->OnAutomationServerLaunchFailed(result, version); 1030 chrome_frame_delegate_->OnAutomationServerLaunchFailed(result, version);
935 } 1031 }
936 } 1032 }
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 // Refactor the ChromeFrameAutomationProxy code to not depend on 1215 // Refactor the ChromeFrameAutomationProxy code to not depend on
1120 // AutomationProxy and simplify the whole mess. 1216 // AutomationProxy and simplify the whole mess.
1121 void* server_id = automation_server_id_; 1217 void* server_id = automation_server_id_;
1122 automation_server_id_ = NULL; 1218 automation_server_id_ = NULL;
1123 1219
1124 if (automation_server_) { 1220 if (automation_server_) {
1125 // Make sure to clean up any pending sync messages before we go away. 1221 // Make sure to clean up any pending sync messages before we go away.
1126 automation_server_->CancelAsync(this); 1222 automation_server_->CancelAsync(this);
1127 } 1223 }
1128 1224
1129 proxy_factory_->ReleaseAutomationServer(server_id); 1225 proxy_factory_->ReleaseAutomationServer(server_id, this);
1130 automation_server_ = NULL; 1226 automation_server_ = NULL;
1131 1227
1132 // automation_server_ must not have been set to non NULL. 1228 // automation_server_ must not have been set to non NULL.
1133 // (if this regresses, start by looking at LaunchComplete()). 1229 // (if this regresses, start by looking at LaunchComplete()).
1134 DCHECK(automation_server_ == NULL); 1230 DCHECK(automation_server_ == NULL);
1135 } else { 1231 } else {
1136 DCHECK(automation_server_ == NULL); 1232 DCHECK(automation_server_ == NULL);
1137 } 1233 }
1138 } 1234 }
1139 1235
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 const URLRequestStatus& status) { 1385 const URLRequestStatus& status) {
1290 automation_server_->Send(new AutomationMsg_RequestEnd(0, tab_->handle(), 1386 automation_server_->Send(new AutomationMsg_RequestEnd(0, tab_->handle(),
1291 request_id, status)); 1387 request_id, status));
1292 } 1388 }
1293 1389
1294 void ChromeFrameAutomationClient::OnCookiesRetrieved(bool success, 1390 void ChromeFrameAutomationClient::OnCookiesRetrieved(bool success,
1295 const GURL& url, const std::string& cookie_string, int cookie_id) { 1391 const GURL& url, const std::string& cookie_string, int cookie_id) {
1296 automation_server_->Send(new AutomationMsg_GetCookiesHostResponse(0, 1392 automation_server_->Send(new AutomationMsg_GetCookiesHostResponse(0,
1297 tab_->handle(), success, url, cookie_string, cookie_id)); 1393 tab_->handle(), success, url, cookie_string, cookie_id));
1298 } 1394 }
OLDNEW
« no previous file with comments | « chrome_frame/chrome_frame_automation.h ('k') | chrome_frame/chrome_frame_npapi_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698