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 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 ipc_done.Wait(); |
| 52 ipc_thread_.Stop(); |
| 53 } |
| 54 |
| 55 protected: |
| 56 SyncChannel* CreateChannel() { |
| 57 scoped_ptr<SyncChannel> channel = SyncChannel::Create( |
| 58 channel_name_, mode_, this, ipc_thread_.message_loop_proxy().get(), |
| 59 true, &shutdown_event_); |
| 60 return channel.release(); |
| 61 } |
| 62 |
| 63 void OnShutdown(WaitableEvent* ipc_event) { |
| 64 base::RunLoop().RunUntilIdle(); |
| 65 ipc_event->Signal(); |
| 66 } |
| 67 |
| 68 const base::Thread& ipc_thread() const { return ipc_thread_; } |
| 69 |
| 70 WaitableEvent* shutdown_event() { return &shutdown_event_; } |
| 71 |
| 72 SyncChannel* channel() { return channel_.get(); } |
| 73 |
| 74 private: |
| 75 bool OnMessageReceived(const Message& message) override { return false; } |
| 76 |
| 77 void StartThread(base::Thread* thread, base::MessageLoop::Type type) { |
| 78 base::Thread::Options options; |
| 79 options.message_loop_type = type; |
| 80 thread->StartWithOptions(options); |
| 81 } |
| 82 |
| 83 std::string channel_name_; |
| 84 Channel::Mode mode_; |
| 85 scoped_ptr<SyncChannel> channel_; |
| 86 base::Thread ipc_thread_; |
| 87 |
| 88 base::WaitableEvent shutdown_event_; |
| 89 |
| 90 DISALLOW_COPY_AND_ASSIGN(SimpleWorker); |
| 91 }; |
| 92 |
| 93 class SimpleServer : public SimpleWorker { |
| 94 public: |
| 95 explicit SimpleServer() |
| 96 : SimpleWorker(Channel::MODE_SERVER, "simpler_server") { } |
| 97 }; |
| 98 |
| 99 } // namespace IPC |
| 100 |
| 101 namespace content { |
| 102 |
| 103 class SimpleGpuClient : public IPC::SimpleWorker { |
| 104 public: |
| 105 SimpleGpuClient() |
| 106 : IPC::SimpleWorker(IPC::Channel::MODE_CLIENT, "simple_client"), |
| 107 router_(this) { |
| 108 } |
| 109 |
| 110 void Start() override { |
| 111 IPC::SimpleWorker::Start(); |
| 112 gpu_channel_manager_.reset( |
| 113 new GpuChannelManager(&router_, |
| 114 NULL, |
| 115 ipc_thread().message_loop_proxy().get(), |
| 116 shutdown_event(), |
| 117 channel())); |
| 118 } |
| 119 |
| 120 GpuChannelManager* gpu_channel_manager() { |
| 121 return gpu_channel_manager_.get(); |
| 122 } |
| 123 |
| 124 private: |
| 125 class SimpleMessageRouter : public MessageRouter { |
| 126 public: |
| 127 explicit SimpleMessageRouter(IPC::Sender* sender) |
| 128 : sender_(sender) { |
| 129 } |
| 130 |
| 131 bool Send(IPC::Message* msg) override { return sender_->Send(msg); } |
| 132 |
| 133 private: |
| 134 IPC::Sender* const sender_; |
| 135 }; |
| 136 |
| 137 SimpleMessageRouter router_; |
| 138 |
| 139 scoped_ptr<GpuChannelManager> gpu_channel_manager_; |
| 140 }; |
| 141 |
| 142 class GpuChannelManagerTest : public testing::Test { |
| 143 public: |
| 144 GpuChannelManagerTest() {} |
| 145 |
| 146 void SetUp() override { |
| 147 simple_client_.reset(new SimpleGpuClient()); |
| 148 simple_server_.reset(new IPC::SimpleServer()); |
| 149 simple_server_->Start(); |
| 150 simple_client_->Start(); |
| 151 } |
| 152 |
| 153 void TearDown() override { |
| 154 message_loop_.RunUntilIdle(); |
| 155 |
| 156 simple_client_->Shutdown(); |
| 157 simple_server_->Shutdown(); |
| 158 } |
| 159 |
| 160 protected: |
| 161 scoped_ptr<SimpleGpuClient> simple_client_; |
| 162 scoped_ptr<IPC::SimpleServer> simple_server_; |
| 163 |
| 164 private: |
| 165 base::MessageLoop message_loop_; |
| 166 }; |
| 167 |
| 168 TEST_F(GpuChannelManagerTest, SecureValueStateForwarding) { |
| 169 const int kClientId1 = 111; |
| 170 const int kClientId2 = 222; |
| 171 ValueState kValueState1; |
| 172 kValueState1.int_value[0] = 1111; |
| 173 ValueState kValueState2; |
| 174 kValueState2.int_value[0] = 3333; |
| 175 |
| 176 ASSERT_TRUE(simple_client_->gpu_channel_manager() != NULL); |
| 177 |
| 178 // Initialize gpu channels |
| 179 simple_client_->gpu_channel_manager()->OnMessageReceived( |
| 180 GpuMsg_EstablishChannel(kClientId1, false, false)); |
| 181 GpuChannel *channel1 = |
| 182 simple_client_->gpu_channel_manager()->LookupChannel(kClientId1); |
| 183 simple_client_->gpu_channel_manager()->OnMessageReceived( |
| 184 GpuMsg_EstablishChannel(kClientId2, false, false)); |
| 185 GpuChannel *channel2 = |
| 186 simple_client_->gpu_channel_manager()->LookupChannel(kClientId2); |
| 187 ASSERT_TRUE(channel1 != NULL); |
| 188 ASSERT_TRUE(channel2 != NULL); |
| 189 ASSERT_NE(channel1, channel2); |
| 190 |
| 191 // Make sure value states are only accessible by proper channels |
| 192 simple_client_->gpu_channel_manager()->OnMessageReceived( |
| 193 GpuMsg_UpdateValueState( |
| 194 kClientId1, GL_MOUSE_POSITION_CHROMIUM, kValueState1)); |
| 195 simple_client_->gpu_channel_manager()->OnMessageReceived( |
| 196 GpuMsg_UpdateValueState( |
| 197 kClientId2, GL_MOUSE_POSITION_CHROMIUM, kValueState2)); |
| 198 |
| 199 const gpu::ValueStateMap* pending_value_buffer_state1 = |
| 200 channel1->pending_valuebuffer_state(); |
| 201 const gpu::ValueStateMap* pending_value_buffer_state2 = |
| 202 channel2->pending_valuebuffer_state(); |
| 203 ASSERT_NE(pending_value_buffer_state1, pending_value_buffer_state2); |
| 204 |
| 205 const ValueState* state1 = |
| 206 pending_value_buffer_state1->GetState(GL_MOUSE_POSITION_CHROMIUM); |
| 207 const ValueState* state2 = |
| 208 pending_value_buffer_state2->GetState(GL_MOUSE_POSITION_CHROMIUM); |
| 209 ASSERT_NE(state1, state2); |
| 210 |
| 211 ASSERT_EQ(state1->int_value[0], kValueState1.int_value[0]); |
| 212 ASSERT_EQ(state2->int_value[0], kValueState2.int_value[0]); |
| 213 ASSERT_NE(state1->int_value[0], state2->int_value[0]); |
| 214 } |
| 215 |
| 216 } // namespace content |
OLD | NEW |