OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |