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

Side by Side Diff: content/browser/android/java/gin_java_bridge_dispatcher_host.cc

Issue 498633003: Cache pending JS bridge sync IPC replies, and send in case of RenderFrame deletion. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments and a test Created 6 years, 3 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/android/java/gin_java_bridge_dispatcher_host.h" 5 #include "content/browser/android/java/gin_java_bridge_dispatcher_host.h"
6 6
7 #include "base/android/java_handler_thread.h" 7 #include "base/android/java_handler_thread.h"
8 #include "base/android/jni_android.h" 8 #include "base/android/jni_android.h"
9 #include "base/android/scoped_java_ref.h" 9 #include "base/android/scoped_java_ref.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 WebContents* web_contents, 49 WebContents* web_contents,
50 jobject retained_object_set) 50 jobject retained_object_set)
51 : WebContentsObserver(web_contents), 51 : WebContentsObserver(web_contents),
52 retained_object_set_(base::android::AttachCurrentThread(), 52 retained_object_set_(base::android::AttachCurrentThread(),
53 retained_object_set), 53 retained_object_set),
54 allow_object_contents_inspection_(true) { 54 allow_object_contents_inspection_(true) {
55 DCHECK(retained_object_set); 55 DCHECK(retained_object_set);
56 } 56 }
57 57
58 GinJavaBridgeDispatcherHost::~GinJavaBridgeDispatcherHost() { 58 GinJavaBridgeDispatcherHost::~GinJavaBridgeDispatcherHost() {
59 DCHECK(pending_replies_.empty());
59 } 60 }
60 61
61 void GinJavaBridgeDispatcherHost::RenderFrameCreated( 62 void GinJavaBridgeDispatcherHost::RenderFrameCreated(
62 RenderFrameHost* render_frame_host) { 63 RenderFrameHost* render_frame_host) {
63 for (NamedObjectMap::const_iterator iter = named_objects_.begin(); 64 for (NamedObjectMap::const_iterator iter = named_objects_.begin();
64 iter != named_objects_.end(); 65 iter != named_objects_.end();
65 ++iter) { 66 ++iter) {
66 render_frame_host->Send(new GinJavaBridgeMsg_AddNamedObject( 67 render_frame_host->Send(new GinJavaBridgeMsg_AddNamedObject(
67 render_frame_host->GetRoutingID(), iter->first, iter->second)); 68 render_frame_host->GetRoutingID(), iter->first, iter->second));
68 } 69 }
69 } 70 }
70 71
71 void GinJavaBridgeDispatcherHost::RenderFrameDeleted( 72 void GinJavaBridgeDispatcherHost::RenderFrameDeleted(
72 RenderFrameHost* render_frame_host) { 73 RenderFrameHost* render_frame_host) {
74 DCHECK_CURRENTLY_ON(BrowserThread::UI);
75 PendingReplyMap::const_iterator it =
76 pending_replies_.find(render_frame_host);
77 if (it != pending_replies_.end()) {
78 IPC::Message* reply_msg = it->second;
79 base::ListValue result;
80 result.Append(base::Value::CreateNullValue());
81 IPC::WriteParam(reply_msg, result);
82 IPC::WriteParam(reply_msg, kGinJavaBridgeRenderFrameDeleted);
83 render_frame_host->Send(reply_msg);
84 pending_replies_.erase(render_frame_host);
85 }
73 RemoveHolder(render_frame_host, 86 RemoveHolder(render_frame_host,
74 GinJavaBoundObject::ObjectMap::iterator(&objects_), 87 GinJavaBoundObject::ObjectMap::iterator(&objects_),
75 objects_.size()); 88 objects_.size());
76 } 89 }
77 90
78 GinJavaBoundObject::ObjectID GinJavaBridgeDispatcherHost::AddObject( 91 GinJavaBoundObject::ObjectID GinJavaBridgeDispatcherHost::AddObject(
79 const base::android::JavaRef<jobject>& object, 92 const base::android::JavaRef<jobject>& object,
80 const base::android::JavaRef<jclass>& safe_annotation_clazz, 93 const base::android::JavaRef<jclass>& safe_annotation_clazz,
81 bool is_named, 94 bool is_named,
82 RenderFrameHost* holder) { 95 RenderFrameHost* holder) {
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 new IsValidRenderFrameHostHelper(render_frame_host); 362 new IsValidRenderFrameHostHelper(render_frame_host);
350 web_contents()->ForEachFrame( 363 web_contents()->ForEachFrame(
351 base::Bind(&IsValidRenderFrameHostHelper::OnFrame, helper)); 364 base::Bind(&IsValidRenderFrameHostHelper::OnFrame, helper));
352 return helper->rfh_found(); 365 return helper->rfh_found();
353 } 366 }
354 367
355 void GinJavaBridgeDispatcherHost::SendReply( 368 void GinJavaBridgeDispatcherHost::SendReply(
356 RenderFrameHost* render_frame_host, 369 RenderFrameHost* render_frame_host,
357 IPC::Message* reply_msg) { 370 IPC::Message* reply_msg) {
358 DCHECK_CURRENTLY_ON(BrowserThread::UI); 371 DCHECK_CURRENTLY_ON(BrowserThread::UI);
359 if (IsValidRenderFrameHost(render_frame_host)) { 372
360 render_frame_host->Send(reply_msg); 373 if (!IsValidRenderFrameHost(render_frame_host)) {
361 } else { 374 // In this case, we must've already sent the reply when the redner frame
362 delete reply_msg; 375 // was destroyed.
376 DCHECK(pending_replies_.find(render_frame_host) == pending_replies_.end());
boliu 2014/08/27 17:47:34 delete reply_msg here I think?
benm (inactive) 2014/08/27 17:53:34 I don't think so, as in this case we should have s
boliu 2014/08/27 17:55:56 Hmm? I mean |reply_msg| argument to this function,
benm (inactive) 2014/08/27 17:57:50 They are one and the same I believe. the param her
boliu 2014/08/27 18:23:48 Oh god. That's just freaking confusing. That means
benm (inactive) 2014/08/27 18:30:02 Mmm, yes that's true. We can always get it from th
377 return;
363 } 378 }
379
380 DCHECK(pending_replies_.find(render_frame_host) != pending_replies_.end());
381 render_frame_host->Send(reply_msg);
382 pending_replies_.erase(render_frame_host);
364 } 383 }
365 384
366 void GinJavaBridgeDispatcherHost::OnGetMethods( 385 void GinJavaBridgeDispatcherHost::OnGetMethods(
367 RenderFrameHost* render_frame_host, 386 RenderFrameHost* render_frame_host,
368 GinJavaBoundObject::ObjectID object_id, 387 GinJavaBoundObject::ObjectID object_id,
369 IPC::Message* reply_msg) { 388 IPC::Message* reply_msg) {
370 DCHECK_CURRENTLY_ON(BrowserThread::UI); 389 DCHECK_CURRENTLY_ON(BrowserThread::UI);
371 DCHECK(render_frame_host); 390 DCHECK(render_frame_host);
372 if (!allow_object_contents_inspection_) { 391 if (!allow_object_contents_inspection_) {
373 IPC::WriteParam(reply_msg, std::set<std::string>()); 392 IPC::WriteParam(reply_msg, std::set<std::string>());
374 render_frame_host->Send(reply_msg); 393 render_frame_host->Send(reply_msg);
375 return; 394 return;
376 } 395 }
377 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id)); 396 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
378 if (!object) { 397 if (!object) {
379 LOG(ERROR) << "WebView: Unknown object: " << object_id; 398 LOG(ERROR) << "WebView: Unknown object: " << object_id;
380 IPC::WriteParam(reply_msg, std::set<std::string>()); 399 IPC::WriteParam(reply_msg, std::set<std::string>());
381 render_frame_host->Send(reply_msg); 400 render_frame_host->Send(reply_msg);
382 return; 401 return;
383 } 402 }
403 DCHECK(pending_replies_.find(render_frame_host) == pending_replies_.end());
404 pending_replies_[render_frame_host] = reply_msg;
384 base::PostTaskAndReplyWithResult( 405 base::PostTaskAndReplyWithResult(
385 g_background_thread.Get().message_loop()->message_loop_proxy(), 406 g_background_thread.Get().message_loop()->message_loop_proxy(),
386 FROM_HERE, 407 FROM_HERE,
387 base::Bind(&GinJavaBoundObject::GetMethodNames, object), 408 base::Bind(&GinJavaBoundObject::GetMethodNames, object),
388 base::Bind(&GinJavaBridgeDispatcherHost::SendMethods, 409 base::Bind(&GinJavaBridgeDispatcherHost::SendMethods,
389 AsWeakPtr(), 410 AsWeakPtr(),
390 render_frame_host, 411 render_frame_host,
391 reply_msg)); 412 reply_msg));
392 } 413 }
393 414
(...skipping 12 matching lines...) Expand all
406 IPC::Message* reply_msg) { 427 IPC::Message* reply_msg) {
407 DCHECK_CURRENTLY_ON(BrowserThread::UI); 428 DCHECK_CURRENTLY_ON(BrowserThread::UI);
408 DCHECK(render_frame_host); 429 DCHECK(render_frame_host);
409 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id)); 430 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
410 if (!object) { 431 if (!object) {
411 LOG(ERROR) << "WebView: Unknown object: " << object_id; 432 LOG(ERROR) << "WebView: Unknown object: " << object_id;
412 IPC::WriteParam(reply_msg, false); 433 IPC::WriteParam(reply_msg, false);
413 render_frame_host->Send(reply_msg); 434 render_frame_host->Send(reply_msg);
414 return; 435 return;
415 } 436 }
437 DCHECK(pending_replies_.find(render_frame_host) == pending_replies_.end());
438 pending_replies_[render_frame_host] = reply_msg;
416 base::PostTaskAndReplyWithResult( 439 base::PostTaskAndReplyWithResult(
417 g_background_thread.Get().message_loop()->message_loop_proxy(), 440 g_background_thread.Get().message_loop()->message_loop_proxy(),
418 FROM_HERE, 441 FROM_HERE,
419 base::Bind(&GinJavaBoundObject::HasMethod, object, method_name), 442 base::Bind(&GinJavaBoundObject::HasMethod, object, method_name),
420 base::Bind(&GinJavaBridgeDispatcherHost::SendHasMethodReply, 443 base::Bind(&GinJavaBridgeDispatcherHost::SendHasMethodReply,
421 AsWeakPtr(), 444 AsWeakPtr(),
422 render_frame_host, 445 render_frame_host,
423 reply_msg)); 446 reply_msg));
424 } 447 }
425 448
(...skipping 16 matching lines...) Expand all
442 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id)); 465 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
443 if (!object) { 466 if (!object) {
444 LOG(ERROR) << "WebView: Unknown object: " << object_id; 467 LOG(ERROR) << "WebView: Unknown object: " << object_id;
445 base::ListValue result; 468 base::ListValue result;
446 result.Append(base::Value::CreateNullValue()); 469 result.Append(base::Value::CreateNullValue());
447 IPC::WriteParam(reply_msg, result); 470 IPC::WriteParam(reply_msg, result);
448 IPC::WriteParam(reply_msg, kGinJavaBridgeUnknownObjectId); 471 IPC::WriteParam(reply_msg, kGinJavaBridgeUnknownObjectId);
449 render_frame_host->Send(reply_msg); 472 render_frame_host->Send(reply_msg);
450 return; 473 return;
451 } 474 }
475 DCHECK(pending_replies_.find(render_frame_host) == pending_replies_.end());
476 pending_replies_[render_frame_host] = reply_msg;
452 scoped_refptr<GinJavaMethodInvocationHelper> result = 477 scoped_refptr<GinJavaMethodInvocationHelper> result =
453 new GinJavaMethodInvocationHelper( 478 new GinJavaMethodInvocationHelper(
454 make_scoped_ptr(new GinJavaBoundObjectDelegate(object)) 479 make_scoped_ptr(new GinJavaBoundObjectDelegate(object))
455 .PassAs<GinJavaMethodInvocationHelper::ObjectDelegate>(), 480 .PassAs<GinJavaMethodInvocationHelper::ObjectDelegate>(),
456 method_name, 481 method_name,
457 arguments); 482 arguments);
458 result->Init(this); 483 result->Init(this);
459 g_background_thread.Get() 484 g_background_thread.Get()
460 .message_loop() 485 .message_loop()
461 ->message_loop_proxy() 486 ->message_loop_proxy()
(...skipping 19 matching lines...) Expand all
481 } else { 506 } else {
482 ProcessMethodInvocationObjectResult(render_frame_host, reply_msg, result); 507 ProcessMethodInvocationObjectResult(render_frame_host, reply_msg, result);
483 } 508 }
484 } 509 }
485 510
486 void GinJavaBridgeDispatcherHost::ProcessMethodInvocationObjectResult( 511 void GinJavaBridgeDispatcherHost::ProcessMethodInvocationObjectResult(
487 RenderFrameHost* render_frame_host, 512 RenderFrameHost* render_frame_host,
488 IPC::Message* reply_msg, 513 IPC::Message* reply_msg,
489 scoped_refptr<GinJavaMethodInvocationHelper> result) { 514 scoped_refptr<GinJavaMethodInvocationHelper> result) {
490 DCHECK_CURRENTLY_ON(BrowserThread::UI); 515 DCHECK_CURRENTLY_ON(BrowserThread::UI);
516
491 if (!IsValidRenderFrameHost(render_frame_host)) { 517 if (!IsValidRenderFrameHost(render_frame_host)) {
492 delete reply_msg; 518 // In this case, we must've already sent the reply when the render frame
519 // was destroyed.
520 DCHECK(pending_replies_.find(render_frame_host) == pending_replies_.end());
boliu 2014/08/27 17:47:34 delete reply_msg?
benm (inactive) 2014/08/27 17:53:34 same reply as above.
493 return; 521 return;
494 } 522 }
523
495 base::ListValue wrapped_result; 524 base::ListValue wrapped_result;
496 if (!result->GetObjectResult().is_null()) { 525 if (!result->GetObjectResult().is_null()) {
497 GinJavaBoundObject::ObjectID returned_object_id; 526 GinJavaBoundObject::ObjectID returned_object_id;
498 if (FindObjectId(result->GetObjectResult(), &returned_object_id)) { 527 if (FindObjectId(result->GetObjectResult(), &returned_object_id)) {
499 (*objects_.Lookup(returned_object_id))->AddHolder(render_frame_host); 528 (*objects_.Lookup(returned_object_id))->AddHolder(render_frame_host);
500 } else { 529 } else {
501 returned_object_id = AddObject(result->GetObjectResult(), 530 returned_object_id = AddObject(result->GetObjectResult(),
502 result->GetSafeAnnotationClass(), 531 result->GetSafeAnnotationClass(),
503 false, 532 false,
504 render_frame_host); 533 render_frame_host);
505 } 534 }
506 wrapped_result.Append( 535 wrapped_result.Append(
507 GinJavaBridgeValue::CreateObjectIDValue(returned_object_id).release()); 536 GinJavaBridgeValue::CreateObjectIDValue(
537 returned_object_id).release());
508 } else { 538 } else {
509 wrapped_result.Append(base::Value::CreateNullValue()); 539 wrapped_result.Append(base::Value::CreateNullValue());
510 } 540 }
511 IPC::WriteParam(reply_msg, wrapped_result); 541 IPC::WriteParam(reply_msg, wrapped_result);
512 IPC::WriteParam(reply_msg, result->GetInvocationError()); 542 IPC::WriteParam(reply_msg, result->GetInvocationError());
513 render_frame_host->Send(reply_msg); 543 SendReply(render_frame_host, reply_msg);
514 } 544 }
515 545
516 void GinJavaBridgeDispatcherHost::OnObjectWrapperDeleted( 546 void GinJavaBridgeDispatcherHost::OnObjectWrapperDeleted(
517 RenderFrameHost* render_frame_host, 547 RenderFrameHost* render_frame_host,
518 GinJavaBoundObject::ObjectID object_id) { 548 GinJavaBoundObject::ObjectID object_id) {
519 DCHECK_CURRENTLY_ON(BrowserThread::UI); 549 DCHECK_CURRENTLY_ON(BrowserThread::UI);
520 DCHECK(render_frame_host); 550 DCHECK(render_frame_host);
521 if (objects_.Lookup(object_id)) { 551 if (objects_.Lookup(object_id)) {
522 GinJavaBoundObject::ObjectMap::iterator iter(&objects_); 552 GinJavaBoundObject::ObjectMap::iterator iter(&objects_);
523 while (!iter.IsAtEnd() && iter.GetCurrentKey() != object_id) 553 while (!iter.IsAtEnd() && iter.GetCurrentKey() != object_id)
524 iter.Advance(); 554 iter.Advance();
525 DCHECK(!iter.IsAtEnd()); 555 DCHECK(!iter.IsAtEnd());
526 RemoveHolder(render_frame_host, iter, 1); 556 RemoveHolder(render_frame_host, iter, 1);
527 } 557 }
528 } 558 }
529 559
530 } // namespace content 560 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698