OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2014 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 "base/run_loop.h" |
| 6 #include "base/synchronization/waitable_event.h" |
| 7 #include "base/test/test_simple_task_runner.h" |
| 8 #include "content/common/gpu/gpu_channel.h" |
| 9 #include "content/common/gpu/gpu_channel_manager.h" |
| 10 #include "content/common/gpu/gpu_messages.h" |
| 11 #include "content/common/message_router.h" |
| 12 #include "gpu/command_buffer/common/value_state.h" |
| 13 #include "gpu/command_buffer/service/gl_utils.h" |
| 14 #include "gpu/command_buffer/service/valuebuffer_manager.h" |
| 15 #include "ipc/ipc_sync_channel.h" |
| 16 |
| 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 |
| 19 using base::WaitableEvent; |
| 20 using gpu::gles2::ValuebufferManager; |
| 21 using gpu::ValueState; |
| 22 |
| 23 namespace IPC { |
| 24 |
| 25 class SimpleWorker : public Listener, public Sender { |
| 26 public: |
| 27 SimpleWorker(Channel::Mode mode, const std::string& thread_name) |
| 28 : mode_(mode), |
| 29 ipc_thread_((thread_name + "_ipc").c_str()), |
| 30 shutdown_event_(true, false) { |
| 31 } |
| 32 |
| 33 ~SimpleWorker() override { |
| 34 } |
| 35 |
| 36 void AddRef() { } |
| 37 void Release() { } |
| 38 bool Send(Message* msg) override { return channel_->Send(msg); } |
| 39 |
| 40 virtual void Start() { |
| 41 StartThread(&ipc_thread_, base::MessageLoop::TYPE_IO); |
| 42 channel_.reset(CreateChannel()); |
| 43 } |
| 44 |
| 45 virtual void Shutdown() { |
| 46 WaitableEvent ipc_done(false, false); |
| 47 ipc_thread_.message_loop()->PostTask( |
| 48 FROM_HERE, base::Bind(&SimpleWorker::OnShutdown, this, &ipc_done)); |
| 49 |
| 50 channel_.reset(); |
| 51 |
| 52 ipc_done.Wait(); |
| 53 ipc_thread_.Stop(); |
| 54 } |
| 55 |
| 56 protected: |
| 57 SyncChannel* CreateChannel() { |
| 58 scoped_ptr<SyncChannel> channel = SyncChannel::Create( |
| 59 channel_name_, mode_, this, ipc_thread_.message_loop_proxy().get(), |
| 60 true, &shutdown_event_); |
| 61 return channel.release(); |
| 62 } |
| 63 |
| 64 void OnShutdown(WaitableEvent* ipc_event) { |
| 65 base::RunLoop().RunUntilIdle(); |
| 66 ipc_event->Signal(); |
| 67 } |
| 68 |
| 69 const base::Thread& ipc_thread() const { return ipc_thread_; } |
| 70 |
| 71 WaitableEvent* shutdown_event() { return &shutdown_event_; } |
| 72 |
| 73 SyncChannel* channel() { return channel_.get(); } |
| 74 |
| 75 private: |
| 76 bool OnMessageReceived(const Message& message) override { return false; } |
| 77 |
| 78 void StartThread(base::Thread* thread, base::MessageLoop::Type type) { |
| 79 base::Thread::Options options; |
| 80 options.message_loop_type = type; |
| 81 thread->StartWithOptions(options); |
| 82 } |
| 83 |
| 84 std::string channel_name_; |
| 85 Channel::Mode mode_; |
| 86 scoped_ptr<SyncChannel> channel_; |
| 87 base::Thread ipc_thread_; |
| 88 |
| 89 base::WaitableEvent shutdown_event_; |
| 90 |
| 91 DISALLOW_COPY_AND_ASSIGN(SimpleWorker); |
| 92 }; |
| 93 |
| 94 class SimpleServer : public SimpleWorker { |
| 95 public: |
| 96 explicit SimpleServer() |
| 97 : SimpleWorker(Channel::MODE_SERVER, "simpler_server") { } |
| 98 }; |
| 99 |
| 100 } // namespace IPC |
| 101 |
| 102 namespace content { |
| 103 |
| 104 class SimpleGpuClient : public IPC::SimpleWorker { |
| 105 public: |
| 106 SimpleGpuClient() |
| 107 : IPC::SimpleWorker(IPC::Channel::MODE_CLIENT, "simple_client"), |
| 108 router_(this) { |
| 109 } |
| 110 |
| 111 void Start() override { |
| 112 IPC::SimpleWorker::Start(); |
| 113 gpu_channel_manager_.reset( |
| 114 new GpuChannelManager(&router_, |
| 115 NULL, |
| 116 ipc_thread().message_loop_proxy().get(), |
| 117 shutdown_event(), |
| 118 channel())); |
| 119 } |
| 120 |
| 121 void Shutdown() override { |
| 122 gpu_channel_manager_.reset(); |
| 123 IPC::SimpleWorker::Shutdown(); |
| 124 } |
| 125 |
| 126 GpuChannelManager* gpu_channel_manager() { |
| 127 return gpu_channel_manager_.get(); |
| 128 } |
| 129 |
| 130 private: |
| 131 class SimpleMessageRouter : public MessageRouter { |
| 132 public: |
| 133 explicit SimpleMessageRouter(IPC::Sender* sender) |
| 134 : sender_(sender) { |
| 135 } |
| 136 |
| 137 bool Send(IPC::Message* msg) override { return sender_->Send(msg); } |
| 138 |
| 139 private: |
| 140 IPC::Sender* const sender_; |
| 141 }; |
| 142 |
| 143 SimpleMessageRouter router_; |
| 144 |
| 145 scoped_ptr<GpuChannelManager> gpu_channel_manager_; |
| 146 }; |
| 147 |
| 148 class GpuChannelManagerTest : public testing::Test { |
| 149 public: |
| 150 GpuChannelManagerTest() {} |
| 151 |
| 152 void SetUp() override { |
| 153 simple_client_.reset(new SimpleGpuClient()); |
| 154 simple_server_.reset(new IPC::SimpleServer()); |
| 155 simple_server_->Start(); |
| 156 simple_client_->Start(); |
| 157 } |
| 158 |
| 159 void TearDown() override { |
| 160 simple_client_->Shutdown(); |
| 161 simple_server_->Shutdown(); |
| 162 } |
| 163 |
| 164 protected: |
| 165 scoped_ptr<SimpleGpuClient> simple_client_; |
| 166 scoped_ptr<IPC::SimpleServer> simple_server_; |
| 167 |
| 168 private: |
| 169 base::MessageLoop message_loop_; |
| 170 }; |
| 171 |
| 172 TEST_F(GpuChannelManagerTest, SecureValueStateForwarding) { |
| 173 const int kClientId1 = 111; |
| 174 const int kClientId2 = 222; |
| 175 ValueState kValueState1; |
| 176 kValueState1.int_value[0] = 1111; |
| 177 ValueState kValueState2; |
| 178 kValueState2.int_value[0] = 3333; |
| 179 |
| 180 ASSERT_TRUE(simple_client_->gpu_channel_manager() != NULL); |
| 181 |
| 182 // Initialize gpu channels |
| 183 simple_client_->gpu_channel_manager()->OnMessageReceived( |
| 184 GpuMsg_EstablishChannel(kClientId1, false, false)); |
| 185 GpuChannel *channel1 = |
| 186 simple_client_->gpu_channel_manager()->LookupChannel(kClientId1); |
| 187 simple_client_->gpu_channel_manager()->OnMessageReceived( |
| 188 GpuMsg_EstablishChannel(kClientId2, false, false)); |
| 189 GpuChannel *channel2 = |
| 190 simple_client_->gpu_channel_manager()->LookupChannel(kClientId2); |
| 191 ASSERT_TRUE(channel1 != NULL); |
| 192 ASSERT_TRUE(channel2 != NULL); |
| 193 ASSERT_NE(channel1, channel2); |
| 194 |
| 195 // Make sure value states are only accessible by proper channels |
| 196 simple_client_->gpu_channel_manager()->OnMessageReceived( |
| 197 GpuMsg_UpdateValueState( |
| 198 kClientId1, GL_MOUSE_POSITION_CHROMIUM, kValueState1)); |
| 199 simple_client_->gpu_channel_manager()->OnMessageReceived( |
| 200 GpuMsg_UpdateValueState( |
| 201 kClientId2, GL_MOUSE_POSITION_CHROMIUM, kValueState2)); |
| 202 |
| 203 const gpu::ValueStateMap* pending_value_buffer_state1 = |
| 204 channel1->pending_valuebuffer_state(); |
| 205 const gpu::ValueStateMap* pending_value_buffer_state2 = |
| 206 channel2->pending_valuebuffer_state(); |
| 207 ASSERT_NE(pending_value_buffer_state1, pending_value_buffer_state2); |
| 208 |
| 209 const ValueState* state1 = |
| 210 pending_value_buffer_state1->GetState(GL_MOUSE_POSITION_CHROMIUM); |
| 211 const ValueState* state2 = |
| 212 pending_value_buffer_state2->GetState(GL_MOUSE_POSITION_CHROMIUM); |
| 213 ASSERT_NE(state1, state2); |
| 214 |
| 215 ASSERT_EQ(state1->int_value[0], kValueState1.int_value[0]); |
| 216 ASSERT_EQ(state2->int_value[0], kValueState2.int_value[0]); |
| 217 ASSERT_NE(state1->int_value[0], state2->int_value[0]); |
| 218 } |
| 219 |
| 220 } // namespace content |
OLD | NEW |