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 "extensions/renderer/messaging_bindings.h" | 5 #include "extensions/renderer/messaging_bindings.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <string> | 10 #include <string> |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 const std::string& channel_name, | 72 const std::string& channel_name, |
73 const ExtensionMsg_TabConnectionInfo* source, | 73 const ExtensionMsg_TabConnectionInfo* source, |
74 const ExtensionMsg_ExternalConnectionInfo& info, | 74 const ExtensionMsg_ExternalConnectionInfo& info, |
75 const std::string& tls_channel_id, | 75 const std::string& tls_channel_id, |
76 bool* port_created, | 76 bool* port_created, |
77 ScriptContext* script_context) { | 77 ScriptContext* script_context) { |
78 MessagingBindings* bindings = g_messaging_map.Get()[script_context]; | 78 MessagingBindings* bindings = g_messaging_map.Get()[script_context]; |
79 DCHECK(bindings); | 79 DCHECK(bindings); |
80 | 80 |
81 int opposite_port_id = global_target_port_id ^ 1; | 81 int opposite_port_id = global_target_port_id ^ 1; |
82 if (bindings->GetPortWithGlobalId(opposite_port_id)) | 82 if (bindings->GetPortWithGlobalId(opposite_port_id) || |
| 83 bindings->DidCreatePortWithGlobalId(opposite_port_id)) |
83 return; // The channel was opened by this same context; ignore it. | 84 return; // The channel was opened by this same context; ignore it. |
84 | 85 |
85 ExtensionPort* port = | 86 ExtensionPort* port = |
86 bindings->CreateNewPortWithGlobalId(global_target_port_id); | 87 bindings->CreateNewPortWithGlobalId(global_target_port_id); |
87 int local_port_id = port->local_id(); | 88 int local_port_id = port->local_id(); |
88 // Remove the port. | 89 // Remove the port. |
89 base::ScopedClosureRunner remove_port( | 90 base::ScopedClosureRunner remove_port( |
90 base::Bind(&MessagingBindings::RemovePortWithLocalId, | 91 base::Bind(&MessagingBindings::RemovePortWithLocalId, |
91 bindings->GetWeakPtr(), local_port_id)); | 92 bindings->GetWeakPtr(), local_port_id)); |
92 | 93 |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 local_id, base::MakeUnique<ExtensionPort>(context(), local_id))) | 370 local_id, base::MakeUnique<ExtensionPort>(context(), local_id))) |
370 .first->second.get(); | 371 .first->second.get(); |
371 port->SetGlobalId(global_id); | 372 port->SetGlobalId(global_id); |
372 return port; | 373 return port; |
373 } | 374 } |
374 | 375 |
375 void MessagingBindings::RemovePortWithLocalId(int local_id) { | 376 void MessagingBindings::RemovePortWithLocalId(int local_id) { |
376 ports_.erase(local_id); | 377 ports_.erase(local_id); |
377 } | 378 } |
378 | 379 |
| 380 bool MessagingBindings::DidCreatePortWithGlobalId(int global_id) const { |
| 381 return created_global_port_ids_.count(global_id) > 0; |
| 382 } |
| 383 |
379 base::WeakPtr<MessagingBindings> MessagingBindings::GetWeakPtr() { | 384 base::WeakPtr<MessagingBindings> MessagingBindings::GetWeakPtr() { |
380 return weak_ptr_factory_.GetWeakPtr(); | 385 return weak_ptr_factory_.GetWeakPtr(); |
381 } | 386 } |
382 | 387 |
383 void MessagingBindings::PostMessage( | 388 void MessagingBindings::PostMessage( |
384 const v8::FunctionCallbackInfo<v8::Value>& args) { | 389 const v8::FunctionCallbackInfo<v8::Value>& args) { |
385 // Arguments are (int32_t port_id, string message). | 390 // Arguments are (int32_t port_id, string message). |
386 CHECK(args.Length() == 2); | 391 CHECK(args.Length() == 2); |
387 CHECK(args[0]->IsInt32()); | 392 CHECK(args[0]->IsInt32()); |
388 CHECK(args[1]->IsString()); | 393 CHECK(args[1]->IsString()); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 if (!web_frame->document().isNull() && | 477 if (!web_frame->document().isNull() && |
473 (web_frame->document().unloadStartedDoNotUse() || | 478 (web_frame->document().unloadStartedDoNotUse() || |
474 web_frame->document().processingBeforeUnloadDoNotUse())) { | 479 web_frame->document().processingBeforeUnloadDoNotUse())) { |
475 ports_created_in_before_unload_ += | 480 ports_created_in_before_unload_ += |
476 web_frame->document().processingBeforeUnloadDoNotUse() ? 1 : 0; | 481 web_frame->document().processingBeforeUnloadDoNotUse() ? 1 : 0; |
477 ports_created_in_unload_ += | 482 ports_created_in_unload_ += |
478 web_frame->document().unloadStartedDoNotUse() ? 1 : 0; | 483 web_frame->document().unloadStartedDoNotUse() ? 1 : 0; |
479 int global_id = frame_helper->RequestSyncPortId(info, channel_name, | 484 int global_id = frame_helper->RequestSyncPortId(info, channel_name, |
480 include_tls_channel_id); | 485 include_tls_channel_id); |
481 ports_[local_id]->SetGlobalId(global_id); | 486 ports_[local_id]->SetGlobalId(global_id); |
| 487 created_global_port_ids_.insert(global_id); |
482 } else { | 488 } else { |
483 ++ports_created_normal_; | 489 ++ports_created_normal_; |
484 frame_helper->RequestPortId( | 490 frame_helper->RequestPortId( |
485 info, channel_name, include_tls_channel_id, | 491 info, channel_name, include_tls_channel_id, |
486 base::Bind(&MessagingBindings::SetGlobalPortId, | 492 base::Bind(&MessagingBindings::SetGlobalPortId, |
487 weak_ptr_factory_.GetWeakPtr(), local_id)); | 493 weak_ptr_factory_.GetWeakPtr(), local_id)); |
| 494 created_local_port_ids_.insert(local_id); |
488 } | 495 } |
489 | 496 |
490 args.GetReturnValue().Set(static_cast<int32_t>(local_id)); | 497 args.GetReturnValue().Set(static_cast<int32_t>(local_id)); |
491 } | 498 } |
492 | 499 |
493 void MessagingBindings::OpenChannelToNativeApp( | 500 void MessagingBindings::OpenChannelToNativeApp( |
494 const v8::FunctionCallbackInfo<v8::Value>& args) { | 501 const v8::FunctionCallbackInfo<v8::Value>& args) { |
495 // The Javascript code should validate/fill the arguments. | 502 // The Javascript code should validate/fill the arguments. |
496 CHECK_EQ(args.Length(), 1); | 503 CHECK_EQ(args.Length(), 1); |
497 CHECK(args[0]->IsString()); | 504 CHECK(args[0]->IsString()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 // TODO(devlin): Why is this not part of info? | 551 // TODO(devlin): Why is this not part of info? |
545 std::string extension_id = *v8::String::Utf8Value(args[2]); | 552 std::string extension_id = *v8::String::Utf8Value(args[2]); |
546 std::string channel_name = *v8::String::Utf8Value(args[3]); | 553 std::string channel_name = *v8::String::Utf8Value(args[3]); |
547 | 554 |
548 ExtensionFrameHelper* frame_helper = ExtensionFrameHelper::Get(render_frame); | 555 ExtensionFrameHelper* frame_helper = ExtensionFrameHelper::Get(render_frame); |
549 DCHECK(frame_helper); | 556 DCHECK(frame_helper); |
550 frame_helper->RequestTabPortId( | 557 frame_helper->RequestTabPortId( |
551 info, extension_id, channel_name, | 558 info, extension_id, channel_name, |
552 base::Bind(&MessagingBindings::SetGlobalPortId, | 559 base::Bind(&MessagingBindings::SetGlobalPortId, |
553 weak_ptr_factory_.GetWeakPtr(), local_id)); | 560 weak_ptr_factory_.GetWeakPtr(), local_id)); |
| 561 created_local_port_ids_.insert(local_id); |
554 | 562 |
555 args.GetReturnValue().Set(static_cast<int32_t>(local_id)); | 563 args.GetReturnValue().Set(static_cast<int32_t>(local_id)); |
556 } | 564 } |
557 | 565 |
558 void MessagingBindings::ClosePort(int local_port_id, bool force_close) { | 566 void MessagingBindings::ClosePort(int local_port_id, bool force_close) { |
559 // TODO(robwu): Merge this logic with CloseChannel once the TODO in BindToGC | 567 // TODO(robwu): Merge this logic with CloseChannel once the TODO in BindToGC |
560 // has been addressed. | 568 // has been addressed. |
561 auto iter = ports_.find(local_port_id); | 569 auto iter = ports_.find(local_port_id); |
562 if (iter != ports_.end()) { | 570 if (iter != ports_.end()) { |
563 std::unique_ptr<ExtensionPort> port = std::move(iter->second); | 571 std::unique_ptr<ExtensionPort> port = std::move(iter->second); |
564 ports_.erase(iter); | 572 ports_.erase(iter); |
565 port->Close(force_close); | 573 port->Close(force_close); |
566 // If the port hasn't been initialized, we can't delete it just yet, because | 574 // If the port hasn't been initialized, we can't delete it just yet, because |
567 // we need to wait for it to send any pending messages. This is important | 575 // we need to wait for it to send any pending messages. This is important |
568 // to support the flow: | 576 // to support the flow: |
569 // var port = chrome.runtime.connect(); | 577 // var port = chrome.runtime.connect(); |
570 // port.postMessage({message}); | 578 // port.postMessage({message}); |
571 // port.disconnect(); | 579 // port.disconnect(); |
572 if (!port->initialized()) | 580 if (!port->initialized()) |
573 disconnected_ports_[port->local_id()] = std::move(port); | 581 disconnected_ports_[port->local_id()] = std::move(port); |
574 } | 582 } |
575 } | 583 } |
576 | 584 |
577 void MessagingBindings::SetGlobalPortId(int local_id, int global_id) { | 585 void MessagingBindings::SetGlobalPortId(int local_id, int global_id) { |
| 586 if (created_local_port_ids_.erase(local_id)) |
| 587 created_global_port_ids_.insert(global_id); |
| 588 |
578 auto iter = ports_.find(local_id); | 589 auto iter = ports_.find(local_id); |
579 if (iter != ports_.end()) { | 590 if (iter != ports_.end()) { |
580 iter->second->SetGlobalId(global_id); | 591 iter->second->SetGlobalId(global_id); |
581 return; | 592 return; |
582 } | 593 } |
583 | 594 |
584 iter = disconnected_ports_.find(local_id); | 595 iter = disconnected_ports_.find(local_id); |
585 DCHECK(iter != disconnected_ports_.end()); | 596 DCHECK(iter != disconnected_ports_.end()); |
586 iter->second->SetGlobalId(global_id); | 597 iter->second->SetGlobalId(global_id); |
587 // Setting the global id dispatches pending messages, so we can delete the | 598 // Setting the global id dispatches pending messages, so we can delete the |
588 // port now. | 599 // port now. |
589 disconnected_ports_.erase(iter); | 600 disconnected_ports_.erase(iter); |
590 } | 601 } |
591 | 602 |
592 int MessagingBindings::GetNextLocalId() { return next_local_id_++; } | 603 int MessagingBindings::GetNextLocalId() { return next_local_id_++; } |
593 | 604 |
594 } // namespace extensions | 605 } // namespace extensions |
OLD | NEW |