| 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 |