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

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: remove logging Created 6 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
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 GinJavaBridgeDispatcherHost::GinJavaBridgeDispatcherHost( 48 GinJavaBridgeDispatcherHost::GinJavaBridgeDispatcherHost(
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() {
boliu 2014/08/22 21:05:17 Is pending_replies_ guaranteed to be empty here? I
59 } 59 }
60 60
61 void GinJavaBridgeDispatcherHost::RenderFrameCreated( 61 void GinJavaBridgeDispatcherHost::RenderFrameCreated(
62 RenderFrameHost* render_frame_host) { 62 RenderFrameHost* render_frame_host) {
63 for (NamedObjectMap::const_iterator iter = named_objects_.begin(); 63 for (NamedObjectMap::const_iterator iter = named_objects_.begin();
64 iter != named_objects_.end(); 64 iter != named_objects_.end();
65 ++iter) { 65 ++iter) {
66 render_frame_host->Send(new GinJavaBridgeMsg_AddNamedObject( 66 render_frame_host->Send(new GinJavaBridgeMsg_AddNamedObject(
67 render_frame_host->GetRoutingID(), iter->first, iter->second)); 67 render_frame_host->GetRoutingID(), iter->first, iter->second));
68 } 68 }
69 } 69 }
70 70
71 void GinJavaBridgeDispatcherHost::RenderFrameDeleted( 71 void GinJavaBridgeDispatcherHost::RenderFrameDeleted(
72 RenderFrameHost* render_frame_host) { 72 RenderFrameHost* render_frame_host) {
73 DCHECK_CURRENTLY_ON(BrowserThread::UI);
74 std::map<RenderFrameHost*, IPC::Message*>::const_iterator it =
75 pending_replies_.find(render_frame_host);
76 if (it != pending_replies_.end()) {
77 IPC::Message* reply_msg = it->second;
78 base::ListValue result;
79 result.Append(base::Value::CreateNullValue());
80 IPC::WriteParam(reply_msg, result);
81 IPC::WriteParam(reply_msg, kGinJavaBridgeObjectIsGone);
mnaganov (inactive) 2014/08/24 13:31:49 Maybe, add a specific error code / message for thi
benm (inactive) 2014/08/26 15:42:40 Done.
82 render_frame_host->Send(reply_msg);
83 pending_replies_.erase(render_frame_host);
84 }
73 RemoveHolder(render_frame_host, 85 RemoveHolder(render_frame_host,
74 GinJavaBoundObject::ObjectMap::iterator(&objects_), 86 GinJavaBoundObject::ObjectMap::iterator(&objects_),
75 objects_.size()); 87 objects_.size());
76 } 88 }
77 89
78 GinJavaBoundObject::ObjectID GinJavaBridgeDispatcherHost::AddObject( 90 GinJavaBoundObject::ObjectID GinJavaBridgeDispatcherHost::AddObject(
79 const base::android::JavaRef<jobject>& object, 91 const base::android::JavaRef<jobject>& object,
80 const base::android::JavaRef<jclass>& safe_annotation_clazz, 92 const base::android::JavaRef<jclass>& safe_annotation_clazz,
81 bool is_named, 93 bool is_named,
82 RenderFrameHost* holder) { 94 RenderFrameHost* holder) {
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 new IsValidRenderFrameHostHelper(render_frame_host); 361 new IsValidRenderFrameHostHelper(render_frame_host);
350 web_contents()->ForEachFrame( 362 web_contents()->ForEachFrame(
351 base::Bind(&IsValidRenderFrameHostHelper::OnFrame, helper)); 363 base::Bind(&IsValidRenderFrameHostHelper::OnFrame, helper));
352 return helper->rfh_found(); 364 return helper->rfh_found();
353 } 365 }
354 366
355 void GinJavaBridgeDispatcherHost::SendReply( 367 void GinJavaBridgeDispatcherHost::SendReply(
356 RenderFrameHost* render_frame_host, 368 RenderFrameHost* render_frame_host,
357 IPC::Message* reply_msg) { 369 IPC::Message* reply_msg) {
358 DCHECK_CURRENTLY_ON(BrowserThread::UI); 370 DCHECK_CURRENTLY_ON(BrowserThread::UI);
371
359 if (IsValidRenderFrameHost(render_frame_host)) { 372 if (IsValidRenderFrameHost(render_frame_host)) {
373 DCHECK(pending_replies_.find(render_frame_host) != pending_replies_.end());
360 render_frame_host->Send(reply_msg); 374 render_frame_host->Send(reply_msg);
375 pending_replies_.erase(render_frame_host);
361 } else { 376 } else {
362 delete reply_msg; 377 // In this case, we must've already sent the reply when the redner frame
378 // was destroyed.
379 DCHECK(pending_replies_.find(render_frame_host) == pending_replies_.end());
363 } 380 }
364 } 381 }
365 382
366 void GinJavaBridgeDispatcherHost::OnGetMethods( 383 void GinJavaBridgeDispatcherHost::OnGetMethods(
367 RenderFrameHost* render_frame_host, 384 RenderFrameHost* render_frame_host,
368 GinJavaBoundObject::ObjectID object_id, 385 GinJavaBoundObject::ObjectID object_id,
369 IPC::Message* reply_msg) { 386 IPC::Message* reply_msg) {
370 DCHECK_CURRENTLY_ON(BrowserThread::UI); 387 DCHECK_CURRENTLY_ON(BrowserThread::UI);
371 DCHECK(render_frame_host); 388 DCHECK(render_frame_host);
372 if (!allow_object_contents_inspection_) { 389 if (!allow_object_contents_inspection_) {
373 IPC::WriteParam(reply_msg, std::set<std::string>()); 390 IPC::WriteParam(reply_msg, std::set<std::string>());
374 render_frame_host->Send(reply_msg); 391 render_frame_host->Send(reply_msg);
375 return; 392 return;
376 } 393 }
377 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id)); 394 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
378 if (!object) { 395 if (!object) {
379 LOG(ERROR) << "WebView: Unknown object: " << object_id; 396 LOG(ERROR) << "WebView: Unknown object: " << object_id;
380 IPC::WriteParam(reply_msg, std::set<std::string>()); 397 IPC::WriteParam(reply_msg, std::set<std::string>());
381 render_frame_host->Send(reply_msg); 398 render_frame_host->Send(reply_msg);
382 return; 399 return;
383 } 400 }
401 pending_replies_[render_frame_host] = reply_msg;
boliu 2014/08/22 21:05:17 DCHECK(pending_replies_.find(render_frame_host) ==
benm (inactive) 2014/08/26 15:42:40 good call.
384 base::PostTaskAndReplyWithResult( 402 base::PostTaskAndReplyWithResult(
385 g_background_thread.Get().message_loop()->message_loop_proxy(), 403 g_background_thread.Get().message_loop()->message_loop_proxy(),
386 FROM_HERE, 404 FROM_HERE,
387 base::Bind(&GinJavaBoundObject::GetMethodNames, object), 405 base::Bind(&GinJavaBoundObject::GetMethodNames, object),
388 base::Bind(&GinJavaBridgeDispatcherHost::SendMethods, 406 base::Bind(&GinJavaBridgeDispatcherHost::SendMethods,
389 AsWeakPtr(), 407 AsWeakPtr(),
390 render_frame_host, 408 render_frame_host,
391 reply_msg)); 409 reply_msg));
392 } 410 }
393 411
(...skipping 12 matching lines...) Expand all
406 IPC::Message* reply_msg) { 424 IPC::Message* reply_msg) {
407 DCHECK_CURRENTLY_ON(BrowserThread::UI); 425 DCHECK_CURRENTLY_ON(BrowserThread::UI);
408 DCHECK(render_frame_host); 426 DCHECK(render_frame_host);
409 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id)); 427 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
410 if (!object) { 428 if (!object) {
411 LOG(ERROR) << "WebView: Unknown object: " << object_id; 429 LOG(ERROR) << "WebView: Unknown object: " << object_id;
412 IPC::WriteParam(reply_msg, false); 430 IPC::WriteParam(reply_msg, false);
413 render_frame_host->Send(reply_msg); 431 render_frame_host->Send(reply_msg);
414 return; 432 return;
415 } 433 }
434 pending_replies_[render_frame_host] = reply_msg;
416 base::PostTaskAndReplyWithResult( 435 base::PostTaskAndReplyWithResult(
417 g_background_thread.Get().message_loop()->message_loop_proxy(), 436 g_background_thread.Get().message_loop()->message_loop_proxy(),
418 FROM_HERE, 437 FROM_HERE,
419 base::Bind(&GinJavaBoundObject::HasMethod, object, method_name), 438 base::Bind(&GinJavaBoundObject::HasMethod, object, method_name),
420 base::Bind(&GinJavaBridgeDispatcherHost::SendHasMethodReply, 439 base::Bind(&GinJavaBridgeDispatcherHost::SendHasMethodReply,
421 AsWeakPtr(), 440 AsWeakPtr(),
422 render_frame_host, 441 render_frame_host,
423 reply_msg)); 442 reply_msg));
424 } 443 }
425 444
(...skipping 16 matching lines...) Expand all
442 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id)); 461 scoped_refptr<GinJavaBoundObject> object(*objects_.Lookup(object_id));
443 if (!object) { 462 if (!object) {
444 LOG(ERROR) << "WebView: Unknown object: " << object_id; 463 LOG(ERROR) << "WebView: Unknown object: " << object_id;
445 base::ListValue result; 464 base::ListValue result;
446 result.Append(base::Value::CreateNullValue()); 465 result.Append(base::Value::CreateNullValue());
447 IPC::WriteParam(reply_msg, result); 466 IPC::WriteParam(reply_msg, result);
448 IPC::WriteParam(reply_msg, kGinJavaBridgeUnknownObjectId); 467 IPC::WriteParam(reply_msg, kGinJavaBridgeUnknownObjectId);
449 render_frame_host->Send(reply_msg); 468 render_frame_host->Send(reply_msg);
450 return; 469 return;
451 } 470 }
471 pending_replies_[render_frame_host] = reply_msg;
452 scoped_refptr<GinJavaMethodInvocationHelper> result = 472 scoped_refptr<GinJavaMethodInvocationHelper> result =
453 new GinJavaMethodInvocationHelper( 473 new GinJavaMethodInvocationHelper(
454 make_scoped_ptr(new GinJavaBoundObjectDelegate(object)) 474 make_scoped_ptr(new GinJavaBoundObjectDelegate(object))
455 .PassAs<GinJavaMethodInvocationHelper::ObjectDelegate>(), 475 .PassAs<GinJavaMethodInvocationHelper::ObjectDelegate>(),
456 method_name, 476 method_name,
457 arguments); 477 arguments);
458 result->Init(this); 478 result->Init(this);
459 g_background_thread.Get() 479 g_background_thread.Get()
460 .message_loop() 480 .message_loop()
461 ->message_loop_proxy() 481 ->message_loop_proxy()
(...skipping 18 matching lines...) Expand all
480 SendReply(render_frame_host, reply_msg); 500 SendReply(render_frame_host, reply_msg);
481 } else { 501 } else {
482 ProcessMethodInvocationObjectResult(render_frame_host, reply_msg, result); 502 ProcessMethodInvocationObjectResult(render_frame_host, reply_msg, result);
483 } 503 }
484 } 504 }
485 505
486 void GinJavaBridgeDispatcherHost::ProcessMethodInvocationObjectResult( 506 void GinJavaBridgeDispatcherHost::ProcessMethodInvocationObjectResult(
487 RenderFrameHost* render_frame_host, 507 RenderFrameHost* render_frame_host,
488 IPC::Message* reply_msg, 508 IPC::Message* reply_msg,
489 scoped_refptr<GinJavaMethodInvocationHelper> result) { 509 scoped_refptr<GinJavaMethodInvocationHelper> result) {
490 DCHECK_CURRENTLY_ON(BrowserThread::UI); 510 DCHECK_CURRENTLY_ON(BrowserThread::UI);
boliu 2014/08/22 21:05:17 nit: general chrome style is do the shorter branch
benm (inactive) 2014/08/26 15:42:40 Done.
491 if (!IsValidRenderFrameHost(render_frame_host)) { 511
492 delete reply_msg; 512 if (IsValidRenderFrameHost(render_frame_host)) {
493 return; 513 base::ListValue wrapped_result;
514 if (!result->GetObjectResult().is_null()) {
515 GinJavaBoundObject::ObjectID returned_object_id;
516 if (FindObjectId(result->GetObjectResult(), &returned_object_id)) {
517 (*objects_.Lookup(returned_object_id))->AddHolder(render_frame_host);
518 } else {
519 returned_object_id = AddObject(result->GetObjectResult(),
520 result->GetSafeAnnotationClass(),
521 false,
522 render_frame_host);
523 }
524 wrapped_result.Append(
525 GinJavaBridgeValue::CreateObjectIDValue(
526 returned_object_id).release());
527 } else {
528 wrapped_result.Append(base::Value::CreateNullValue());
529 }
530 IPC::WriteParam(reply_msg, wrapped_result);
531 IPC::WriteParam(reply_msg, result->GetInvocationError());
boliu 2014/08/22 21:05:17 Erase rfh from pending_replies_ in this branch, an
benm (inactive) 2014/08/26 15:42:40 We do that in SendReply already.
532 } else {
533 // In this case, we must've already sent the reply when the render frame
534 // was destroyed.
535 DCHECK(pending_replies_.find(render_frame_host) == pending_replies_.end());
494 } 536 }
495 base::ListValue wrapped_result; 537 SendReply(render_frame_host, reply_msg);
boliu 2014/08/22 21:05:17 SendReply will just delete the message if rfh is i
benm (inactive) 2014/08/26 15:42:40 Hold up; we shouldn't get into the case now where
496 if (!result->GetObjectResult().is_null()) {
497 GinJavaBoundObject::ObjectID returned_object_id;
498 if (FindObjectId(result->GetObjectResult(), &returned_object_id)) {
499 (*objects_.Lookup(returned_object_id))->AddHolder(render_frame_host);
500 } else {
501 returned_object_id = AddObject(result->GetObjectResult(),
502 result->GetSafeAnnotationClass(),
503 false,
504 render_frame_host);
505 }
506 wrapped_result.Append(
507 GinJavaBridgeValue::CreateObjectIDValue(returned_object_id).release());
508 } else {
509 wrapped_result.Append(base::Value::CreateNullValue());
510 }
511 IPC::WriteParam(reply_msg, wrapped_result);
512 IPC::WriteParam(reply_msg, result->GetInvocationError());
513 render_frame_host->Send(reply_msg);
514 } 538 }
515 539
516 void GinJavaBridgeDispatcherHost::OnObjectWrapperDeleted( 540 void GinJavaBridgeDispatcherHost::OnObjectWrapperDeleted(
517 RenderFrameHost* render_frame_host, 541 RenderFrameHost* render_frame_host,
518 GinJavaBoundObject::ObjectID object_id) { 542 GinJavaBoundObject::ObjectID object_id) {
519 DCHECK_CURRENTLY_ON(BrowserThread::UI); 543 DCHECK_CURRENTLY_ON(BrowserThread::UI);
520 DCHECK(render_frame_host); 544 DCHECK(render_frame_host);
521 if (objects_.Lookup(object_id)) { 545 if (objects_.Lookup(object_id)) {
522 GinJavaBoundObject::ObjectMap::iterator iter(&objects_); 546 GinJavaBoundObject::ObjectMap::iterator iter(&objects_);
523 while (!iter.IsAtEnd() && iter.GetCurrentKey() != object_id) 547 while (!iter.IsAtEnd() && iter.GetCurrentKey() != object_id)
524 iter.Advance(); 548 iter.Advance();
525 DCHECK(!iter.IsAtEnd()); 549 DCHECK(!iter.IsAtEnd());
526 RemoveHolder(render_frame_host, iter, 1); 550 RemoveHolder(render_frame_host, iter, 1);
527 } 551 }
528 } 552 }
529 553
530 } // namespace content 554 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698