OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "mojo/edk/system/broker_host.h" | |
6 | |
7 #include <fcntl.h> | |
8 #include <unistd.h> | |
9 | |
10 #include <utility> | |
11 | |
12 #include "base/logging.h" | |
13 #include "base/memory/ref_counted.h" | |
14 #include "base/message_loop/message_loop.h" | |
15 #include "base/threading/thread_task_runner_handle.h" | |
16 #include "mojo/edk/embedder/embedder_internal.h" | |
17 #include "mojo/edk/embedder/platform_channel_utils_posix.h" | |
18 #include "mojo/edk/embedder/platform_handle_vector.h" | |
19 #include "mojo/edk/embedder/platform_shared_buffer.h" | |
20 #include "mojo/edk/system/broker_messages.h" | |
21 | |
22 namespace mojo { | |
23 namespace edk { | |
24 | |
25 namespace { | |
26 // To prevent abuse, limit the maximum size of shared memory buffers. | |
27 // TODO(amistry): Re-consider this limit, or do something smarter. | |
28 const size_t kMaxSharedBufferSize = 16 * 1024 * 1024; | |
29 } | |
30 | |
31 BrokerHost::BrokerHost(ScopedPlatformHandle platform_handle) { | |
32 CHECK(platform_handle.is_valid()); | |
33 | |
34 base::MessageLoop::current()->AddDestructionObserver(this); | |
35 | |
36 channel_ = Channel::Create(this, std::move(platform_handle), | |
37 base::ThreadTaskRunnerHandle::Get()); | |
38 channel_->Start(); | |
39 } | |
40 | |
41 BrokerHost::~BrokerHost() { | |
42 // We're always destroyed on the creation thread, which is the IO thread. | |
43 base::MessageLoop::current()->RemoveDestructionObserver(this); | |
44 | |
45 if (channel_) | |
46 channel_->ShutDown(); | |
47 } | |
48 | |
49 void BrokerHost::SendChannel(ScopedPlatformHandle handle) { | |
50 CHECK(handle.is_valid()); | |
51 CHECK(channel_); | |
52 | |
53 Channel::MessagePtr message = | |
54 CreateBrokerMessage(BrokerMessageType::INIT, 1, nullptr); | |
55 ScopedPlatformHandleVectorPtr handles; | |
56 handles.reset(new PlatformHandleVector(1)); | |
57 handles->at(0) = handle.release(); | |
58 message->SetHandles(std::move(handles)); | |
59 | |
60 channel_->Write(std::move(message)); | |
61 } | |
62 | |
63 void BrokerHost::OnBufferRequest(size_t num_bytes) { | |
64 scoped_refptr<PlatformSharedBuffer> buffer; | |
65 scoped_refptr<PlatformSharedBuffer> read_only_buffer; | |
66 if (num_bytes <= kMaxSharedBufferSize) { | |
67 buffer = PlatformSharedBuffer::Create(num_bytes); | |
68 if (buffer) | |
69 read_only_buffer = buffer->CreateReadOnlyDuplicate(); | |
70 if (!read_only_buffer) | |
71 buffer = nullptr; | |
72 } else { | |
73 LOG(ERROR) << "Shared buffer request too large: " << num_bytes; | |
74 } | |
75 | |
76 Channel::MessagePtr message = CreateBrokerMessage( | |
77 BrokerMessageType::BUFFER_RESPONSE, buffer ? 2 : 0, nullptr); | |
78 if (buffer) { | |
79 ScopedPlatformHandleVectorPtr handles; | |
80 handles.reset(new PlatformHandleVector(2)); | |
81 handles->at(0) = buffer->PassPlatformHandle().release(); | |
82 handles->at(1) = read_only_buffer->PassPlatformHandle().release(); | |
83 message->SetHandles(std::move(handles)); | |
84 } | |
85 | |
86 channel_->Write(std::move(message)); | |
87 } | |
88 | |
89 void BrokerHost::OnChannelMessage(const void* payload, | |
90 size_t payload_size, | |
91 ScopedPlatformHandleVectorPtr handles) { | |
92 if (payload_size < sizeof(BrokerMessageHeader)) | |
93 return; | |
94 | |
95 const BrokerMessageHeader* header = | |
96 static_cast<const BrokerMessageHeader*>(payload); | |
97 switch (header->type) { | |
98 case BrokerMessageType::BUFFER_REQUEST: | |
99 if (payload_size == | |
100 sizeof(BrokerMessageHeader) + sizeof(BufferRequestData)) { | |
101 const BufferRequestData* request = | |
102 reinterpret_cast<const BufferRequestData*>(header + 1); | |
103 OnBufferRequest(request->size); | |
104 return; | |
105 } | |
106 break; | |
107 | |
108 default: | |
109 break; | |
110 } | |
111 | |
112 LOG(ERROR) << "Unexpected broker message type: " << header->type; | |
113 } | |
114 | |
115 void BrokerHost::OnChannelError() { | |
116 if (channel_) { | |
117 channel_->ShutDown(); | |
118 channel_ = nullptr; | |
119 } | |
120 | |
121 delete this; | |
122 } | |
123 | |
124 void BrokerHost::WillDestroyCurrentMessageLoop() { | |
125 delete this; | |
126 } | |
127 | |
128 } // namespace edk | |
129 } // namespace mojo | |
OLD | NEW |