| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 "content/browser/browser_io_surface_manager_mac.h" | |
| 6 | |
| 7 #include "testing/gtest/include/gtest/gtest.h" | |
| 8 #include "ui/gfx/mac/io_surface_manager.h" | |
| 9 | |
| 10 namespace content { | |
| 11 | |
| 12 class BrowserIOSurfaceManagerTest : public testing::Test { | |
| 13 public: | |
| 14 void EnsureRunning() { io_surface_manager_.EnsureRunning(); } | |
| 15 | |
| 16 IOSurfaceManagerToken GenerateGpuProcessToken() { | |
| 17 return io_surface_manager_.GenerateGpuProcessToken(); | |
| 18 } | |
| 19 | |
| 20 void InvalidateGpuProcessToken() { | |
| 21 io_surface_manager_.InvalidateGpuProcessToken(); | |
| 22 } | |
| 23 | |
| 24 IOSurfaceManagerToken GenerateChildProcessToken(int child_process_id) { | |
| 25 return io_surface_manager_.GenerateChildProcessToken(child_process_id); | |
| 26 } | |
| 27 | |
| 28 void InvalidateChildProcessToken(const IOSurfaceManagerToken& token) { | |
| 29 io_surface_manager_.InvalidateChildProcessToken(token); | |
| 30 } | |
| 31 | |
| 32 bool HandleRegisterIOSurfaceRequest( | |
| 33 const IOSurfaceManagerHostMsg_RegisterIOSurface& request, | |
| 34 IOSurfaceManagerMsg_RegisterIOSurfaceReply* reply) { | |
| 35 io_surface_manager_.HandleRegisterIOSurfaceRequest(request, reply); | |
| 36 return reply->result; | |
| 37 } | |
| 38 | |
| 39 bool HandleUnregisterIOSurfaceRequest( | |
| 40 const IOSurfaceManagerHostMsg_UnregisterIOSurface& request) { | |
| 41 return io_surface_manager_.HandleUnregisterIOSurfaceRequest(request); | |
| 42 } | |
| 43 | |
| 44 bool HandleAcquireIOSurfaceRequest( | |
| 45 const IOSurfaceManagerHostMsg_AcquireIOSurface& request, | |
| 46 IOSurfaceManagerMsg_AcquireIOSurfaceReply* reply) { | |
| 47 io_surface_manager_.HandleAcquireIOSurfaceRequest(request, reply); | |
| 48 return reply->result; | |
| 49 } | |
| 50 | |
| 51 // Helper function used to register an IOSurface for testing. | |
| 52 void RegisterIOSurface(const IOSurfaceManagerToken& gpu_process_token, | |
| 53 int io_surface_id, | |
| 54 int client_id, | |
| 55 mach_port_t io_surface_port) { | |
| 56 IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}}; | |
| 57 IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}}; | |
| 58 request.io_surface_id = io_surface_id; | |
| 59 request.client_id = client_id; | |
| 60 request.io_surface_port.name = GetIOSurfaceMachPort(); | |
| 61 memcpy(request.token_name, gpu_process_token.name, | |
| 62 sizeof(gpu_process_token.name)); | |
| 63 ASSERT_TRUE(HandleRegisterIOSurfaceRequest(request, &reply)); | |
| 64 ASSERT_TRUE(reply.result); | |
| 65 } | |
| 66 | |
| 67 mach_port_t GetIOSurfaceMachPort() { | |
| 68 if (!io_surface_) { | |
| 69 io_surface_.reset(gfx::IOSurfaceManager::CreateIOSurface( | |
| 70 gfx::Size(32, 32), gfx::BufferFormat::BGRA_8888)); | |
| 71 io_surface_port_.reset(IOSurfaceCreateMachPort(io_surface_)); | |
| 72 } | |
| 73 return io_surface_port_.get(); | |
| 74 } | |
| 75 | |
| 76 private: | |
| 77 BrowserIOSurfaceManager io_surface_manager_; | |
| 78 base::ScopedCFTypeRef<IOSurfaceRef> io_surface_; | |
| 79 base::mac::ScopedMachSendRight io_surface_port_; | |
| 80 }; | |
| 81 | |
| 82 TEST_F(BrowserIOSurfaceManagerTest, EnsureRunning) { | |
| 83 EnsureRunning(); | |
| 84 base::mac::ScopedMachSendRight service_port = | |
| 85 BrowserIOSurfaceManager::LookupServicePort(getpid()); | |
| 86 EXPECT_TRUE(service_port.is_valid()); | |
| 87 } | |
| 88 | |
| 89 TEST_F(BrowserIOSurfaceManagerTest, RegisterIOSurfaceSucceeds) { | |
| 90 const int kIOSurfaceId = 1; | |
| 91 const int kClientId = 1; | |
| 92 | |
| 93 base::ScopedCFTypeRef<IOSurfaceRef> io_surface( | |
| 94 gfx::IOSurfaceManager::CreateIOSurface(gfx::Size(32, 32), | |
| 95 gfx::BufferFormat::BGRA_8888)); | |
| 96 base::mac::ScopedMachSendRight io_surface_port( | |
| 97 IOSurfaceCreateMachPort(io_surface)); | |
| 98 | |
| 99 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 100 | |
| 101 IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}}; | |
| 102 IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}}; | |
| 103 | |
| 104 request.io_surface_id = kIOSurfaceId; | |
| 105 request.client_id = kClientId; | |
| 106 request.io_surface_port.name = GetIOSurfaceMachPort(); | |
| 107 memcpy(request.token_name, gpu_process_token.name, | |
| 108 sizeof(gpu_process_token.name)); | |
| 109 EXPECT_TRUE(HandleRegisterIOSurfaceRequest(request, &reply)); | |
| 110 EXPECT_TRUE(reply.result); | |
| 111 } | |
| 112 | |
| 113 TEST_F(BrowserIOSurfaceManagerTest, RegisterIOSurfaceFailsWithInvalidToken) { | |
| 114 const int kIOSurfaceId = 1; | |
| 115 const int kClientId = 1; | |
| 116 | |
| 117 IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}}; | |
| 118 IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}}; | |
| 119 request.io_surface_id = kIOSurfaceId; | |
| 120 request.client_id = kClientId; | |
| 121 // Fails as request doesn't contain a valid token. | |
| 122 EXPECT_FALSE(HandleRegisterIOSurfaceRequest(request, &reply)); | |
| 123 } | |
| 124 | |
| 125 TEST_F(BrowserIOSurfaceManagerTest, | |
| 126 RegisterIOSurfaceFailsWithChildProcessToken) { | |
| 127 const int kIOSurfaceId = 1; | |
| 128 const int kClientId = 1; | |
| 129 | |
| 130 IOSurfaceManagerToken child_process_token = | |
| 131 GenerateChildProcessToken(kClientId); | |
| 132 | |
| 133 IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}}; | |
| 134 IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}}; | |
| 135 request.io_surface_id = kIOSurfaceId; | |
| 136 request.client_id = kClientId; | |
| 137 memcpy(request.token_name, child_process_token.name, | |
| 138 sizeof(child_process_token.name)); | |
| 139 // Fails as child process is not allowed to register IOSurfaces. | |
| 140 EXPECT_FALSE(HandleRegisterIOSurfaceRequest(request, &reply)); | |
| 141 } | |
| 142 | |
| 143 TEST_F(BrowserIOSurfaceManagerTest, RegisterIOSurfaceFailsWithInvalidPort) { | |
| 144 const int kIOSurfaceId = 1; | |
| 145 const int kClientId = 1; | |
| 146 const mach_port_t kIOInvalidSurfacePortId = 100u; | |
| 147 | |
| 148 base::ScopedCFTypeRef<IOSurfaceRef> io_surface( | |
| 149 gfx::IOSurfaceManager::CreateIOSurface(gfx::Size(32, 32), | |
| 150 gfx::BufferFormat::BGRA_8888)); | |
| 151 base::mac::ScopedMachSendRight io_surface_port( | |
| 152 IOSurfaceCreateMachPort(io_surface)); | |
| 153 | |
| 154 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 155 | |
| 156 IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}}; | |
| 157 IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}}; | |
| 158 | |
| 159 request.io_surface_id = kIOSurfaceId; | |
| 160 request.client_id = kClientId; | |
| 161 request.io_surface_port.name = kIOInvalidSurfacePortId; | |
| 162 memcpy(request.token_name, gpu_process_token.name, | |
| 163 sizeof(gpu_process_token.name)); | |
| 164 EXPECT_FALSE(HandleRegisterIOSurfaceRequest(request, &reply)); | |
| 165 EXPECT_FALSE(reply.result); | |
| 166 } | |
| 167 | |
| 168 TEST_F(BrowserIOSurfaceManagerTest, UnregisterIOSurfaceSucceeds) { | |
| 169 const int kIOSurfaceId = 1; | |
| 170 const int kClientId = 1; | |
| 171 | |
| 172 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 173 | |
| 174 RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, 0); | |
| 175 | |
| 176 IOSurfaceManagerHostMsg_UnregisterIOSurface request = {{0}}; | |
| 177 request.io_surface_id = kIOSurfaceId; | |
| 178 request.client_id = kClientId; | |
| 179 memcpy(request.token_name, gpu_process_token.name, | |
| 180 sizeof(gpu_process_token.name)); | |
| 181 EXPECT_TRUE(HandleUnregisterIOSurfaceRequest(request)); | |
| 182 } | |
| 183 | |
| 184 TEST_F(BrowserIOSurfaceManagerTest, UnregisterIOSurfaceFailsWithInvalidToken) { | |
| 185 const int kIOSurfaceId = 1; | |
| 186 const int kClientId = 1; | |
| 187 | |
| 188 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 189 | |
| 190 RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, 0); | |
| 191 | |
| 192 IOSurfaceManagerHostMsg_UnregisterIOSurface request = {{0}}; | |
| 193 request.io_surface_id = kIOSurfaceId; | |
| 194 request.client_id = kClientId; | |
| 195 // Fails as request doesn't contain valid GPU token. | |
| 196 EXPECT_FALSE(HandleUnregisterIOSurfaceRequest(request)); | |
| 197 } | |
| 198 | |
| 199 TEST_F(BrowserIOSurfaceManagerTest, | |
| 200 UnregisterIOSurfaceFailsWithChildProcessToken) { | |
| 201 const int kIOSurfaceId = 1; | |
| 202 const int kClientId = 1; | |
| 203 | |
| 204 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 205 IOSurfaceManagerToken child_process_token = | |
| 206 GenerateChildProcessToken(kClientId); | |
| 207 | |
| 208 RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, 0); | |
| 209 | |
| 210 IOSurfaceManagerHostMsg_UnregisterIOSurface request = {{0}}; | |
| 211 request.io_surface_id = kIOSurfaceId; | |
| 212 request.client_id = kClientId; | |
| 213 memcpy(request.token_name, child_process_token.name, | |
| 214 sizeof(child_process_token.name)); | |
| 215 // Fails as child process is not allowed to unregister IOSurfaces. | |
| 216 EXPECT_FALSE(HandleUnregisterIOSurfaceRequest(request)); | |
| 217 } | |
| 218 | |
| 219 TEST_F(BrowserIOSurfaceManagerTest, AcquireIOSurfaceSucceeds) { | |
| 220 const int kIOSurfaceId = 10; | |
| 221 const int kClientId = 1; | |
| 222 const mach_port_t io_surface_port = GetIOSurfaceMachPort(); | |
| 223 | |
| 224 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 225 IOSurfaceManagerToken child_process_token = | |
| 226 GenerateChildProcessToken(kClientId); | |
| 227 | |
| 228 RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, | |
| 229 io_surface_port); | |
| 230 | |
| 231 IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}}; | |
| 232 IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}}; | |
| 233 request.io_surface_id = kIOSurfaceId; | |
| 234 memcpy(request.token_name, child_process_token.name, | |
| 235 sizeof(child_process_token.name)); | |
| 236 EXPECT_TRUE(HandleAcquireIOSurfaceRequest(request, &reply)); | |
| 237 } | |
| 238 | |
| 239 TEST_F(BrowserIOSurfaceManagerTest, AcquireIOSurfaceFailsWithInvalidToken) { | |
| 240 const int kIOSurfaceId = 10; | |
| 241 const int kClientId = 1; | |
| 242 const mach_port_t io_surface_port = GetIOSurfaceMachPort(); | |
| 243 | |
| 244 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 245 | |
| 246 RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, | |
| 247 io_surface_port); | |
| 248 | |
| 249 IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}}; | |
| 250 IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}}; | |
| 251 request.io_surface_id = kIOSurfaceId; | |
| 252 // Fails as request doesn't contain valid token. | |
| 253 EXPECT_FALSE(HandleAcquireIOSurfaceRequest(request, &reply)); | |
| 254 } | |
| 255 | |
| 256 TEST_F(BrowserIOSurfaceManagerTest, | |
| 257 AcquireIOSurfaceFailsWithWrongChildProcessToken) { | |
| 258 const int kIOSurfaceId = 10; | |
| 259 const int kClientId1 = 1; | |
| 260 const int kClientId2 = 2; | |
| 261 const mach_port_t io_surface_port = GetIOSurfaceMachPort(); | |
| 262 | |
| 263 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 264 IOSurfaceManagerToken child_process_token2 = | |
| 265 GenerateChildProcessToken(kClientId2); | |
| 266 | |
| 267 RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId1, | |
| 268 io_surface_port); | |
| 269 | |
| 270 IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}}; | |
| 271 IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}}; | |
| 272 request.io_surface_id = kIOSurfaceId; | |
| 273 memcpy(request.token_name, child_process_token2.name, | |
| 274 sizeof(child_process_token2.name)); | |
| 275 EXPECT_TRUE(HandleAcquireIOSurfaceRequest(request, &reply)); | |
| 276 // Fails as child process 2 is not allowed to acquire this IOSurface. | |
| 277 EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL), | |
| 278 reply.io_surface_port.name); | |
| 279 } | |
| 280 | |
| 281 TEST_F(BrowserIOSurfaceManagerTest, | |
| 282 AcquireIOSurfaceFailsAfterInvalidatingChildProcessToken) { | |
| 283 const int kIOSurfaceId = 10; | |
| 284 const int kClientId = 1; | |
| 285 const mach_port_t io_surface_port = GetIOSurfaceMachPort(); | |
| 286 | |
| 287 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 288 IOSurfaceManagerToken child_process_token = | |
| 289 GenerateChildProcessToken(kClientId); | |
| 290 | |
| 291 RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, | |
| 292 io_surface_port); | |
| 293 | |
| 294 InvalidateChildProcessToken(child_process_token); | |
| 295 | |
| 296 IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}}; | |
| 297 IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}}; | |
| 298 request.io_surface_id = kIOSurfaceId; | |
| 299 memcpy(request.token_name, child_process_token.name, | |
| 300 sizeof(child_process_token.name)); | |
| 301 // Fails as token is no longer valid. | |
| 302 EXPECT_FALSE(HandleAcquireIOSurfaceRequest(request, &reply)); | |
| 303 } | |
| 304 | |
| 305 TEST_F(BrowserIOSurfaceManagerTest, | |
| 306 AcquireIOSurfaceAfterInvalidatingGpuProcessToken) { | |
| 307 const int kIOSurfaceId = 10; | |
| 308 const int kClientId = 1; | |
| 309 const mach_port_t io_surface_port = GetIOSurfaceMachPort(); | |
| 310 | |
| 311 IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken(); | |
| 312 IOSurfaceManagerToken child_process_token = | |
| 313 GenerateChildProcessToken(kClientId); | |
| 314 | |
| 315 RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, | |
| 316 io_surface_port); | |
| 317 | |
| 318 InvalidateGpuProcessToken(); | |
| 319 | |
| 320 IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}}; | |
| 321 IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}}; | |
| 322 request.io_surface_id = kIOSurfaceId; | |
| 323 memcpy(request.token_name, child_process_token.name, | |
| 324 sizeof(child_process_token.name)); | |
| 325 EXPECT_TRUE(HandleAcquireIOSurfaceRequest(request, &reply)); | |
| 326 // Should return invalid port. | |
| 327 EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL), | |
| 328 reply.io_surface_port.name); | |
| 329 } | |
| 330 | |
| 331 } // namespace content | |
| OLD | NEW |