blob: b8863e4ad9dcdf1ff2a297f696280071434db192 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/browser/browser_io_surface_manager_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
class BrowserIOSurfaceManagerTest : public testing::Test {
public:
void EnsureRunning() { io_surface_manager_.EnsureRunning(); }
IOSurfaceManagerToken GenerateGpuProcessToken() {
return io_surface_manager_.GenerateGpuProcessToken();
}
void InvalidateGpuProcessToken() {
io_surface_manager_.InvalidateGpuProcessToken();
}
IOSurfaceManagerToken GenerateChildProcessToken(int child_process_id) {
return io_surface_manager_.GenerateChildProcessToken(child_process_id);
}
void InvalidateChildProcessToken(const IOSurfaceManagerToken& token) {
io_surface_manager_.InvalidateChildProcessToken(token);
}
bool HandleRegisterIOSurfaceRequest(
const IOSurfaceManagerHostMsg_RegisterIOSurface& request,
IOSurfaceManagerMsg_RegisterIOSurfaceReply* reply) {
io_surface_manager_.HandleRegisterIOSurfaceRequest(request, reply);
return reply->result;
}
bool HandleUnregisterIOSurfaceRequest(
const IOSurfaceManagerHostMsg_UnregisterIOSurface& request) {
return io_surface_manager_.HandleUnregisterIOSurfaceRequest(request);
}
bool HandleAcquireIOSurfaceRequest(
const IOSurfaceManagerHostMsg_AcquireIOSurface& request,
IOSurfaceManagerMsg_AcquireIOSurfaceReply* reply) {
io_surface_manager_.HandleAcquireIOSurfaceRequest(request, reply);
return reply->result;
}
// Helper function used to register an IOSurface for testing.
void RegisterIOSurface(const IOSurfaceManagerToken& gpu_process_token,
int io_surface_id,
int client_id,
mach_port_t io_surface_port) {
IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}};
IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}};
request.io_surface_id = io_surface_id;
request.client_id = client_id;
request.io_surface_port.name = io_surface_port;
memcpy(request.token_name, gpu_process_token.name,
sizeof(gpu_process_token.name));
ASSERT_TRUE(HandleRegisterIOSurfaceRequest(request, &reply));
ASSERT_TRUE(reply.result);
}
private:
BrowserIOSurfaceManager io_surface_manager_;
};
TEST_F(BrowserIOSurfaceManagerTest, EnsureRunning) {
EnsureRunning();
base::mac::ScopedMachSendRight service_port =
BrowserIOSurfaceManager::LookupServicePort(getpid());
EXPECT_TRUE(service_port.is_valid());
}
TEST_F(BrowserIOSurfaceManagerTest, RegisterIOSurfaceSucceeds) {
const int kIOSurfaceId = 1;
const int kClientId = 1;
IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}};
IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}};
request.io_surface_id = kIOSurfaceId;
request.client_id = kClientId;
memcpy(request.token_name, gpu_process_token.name,
sizeof(gpu_process_token.name));
EXPECT_TRUE(HandleRegisterIOSurfaceRequest(request, &reply));
EXPECT_TRUE(reply.result);
}
TEST_F(BrowserIOSurfaceManagerTest, RegisterIOSurfaceFailsWithInvalidToken) {
const int kIOSurfaceId = 1;
const int kClientId = 1;
IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}};
IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}};
request.io_surface_id = kIOSurfaceId;
request.client_id = kClientId;
// Fails as request doesn't contain a valid token.
EXPECT_FALSE(HandleRegisterIOSurfaceRequest(request, &reply));
}
TEST_F(BrowserIOSurfaceManagerTest,
RegisterIOSurfaceFailsWithChildProcessToken) {
const int kIOSurfaceId = 1;
const int kClientId = 1;
IOSurfaceManagerToken child_process_token =
GenerateChildProcessToken(kClientId);
IOSurfaceManagerHostMsg_RegisterIOSurface request = {{0}};
IOSurfaceManagerMsg_RegisterIOSurfaceReply reply = {{0}};
request.io_surface_id = kIOSurfaceId;
request.client_id = kClientId;
memcpy(request.token_name, child_process_token.name,
sizeof(child_process_token.name));
// Fails as child process is not allowed to register IOSurfaces.
EXPECT_FALSE(HandleRegisterIOSurfaceRequest(request, &reply));
}
TEST_F(BrowserIOSurfaceManagerTest, UnregisterIOSurfaceSucceeds) {
const int kIOSurfaceId = 1;
const int kClientId = 1;
IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, 0);
IOSurfaceManagerHostMsg_UnregisterIOSurface request = {{0}};
request.io_surface_id = kIOSurfaceId;
request.client_id = kClientId;
memcpy(request.token_name, gpu_process_token.name,
sizeof(gpu_process_token.name));
EXPECT_TRUE(HandleUnregisterIOSurfaceRequest(request));
}
TEST_F(BrowserIOSurfaceManagerTest, UnregisterIOSurfaceFailsWithInvalidToken) {
const int kIOSurfaceId = 1;
const int kClientId = 1;
IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, 0);
IOSurfaceManagerHostMsg_UnregisterIOSurface request = {{0}};
request.io_surface_id = kIOSurfaceId;
request.client_id = kClientId;
// Fails as request doesn't contain valid GPU token.
EXPECT_FALSE(HandleUnregisterIOSurfaceRequest(request));
}
TEST_F(BrowserIOSurfaceManagerTest,
UnregisterIOSurfaceFailsWithChildProcessToken) {
const int kIOSurfaceId = 1;
const int kClientId = 1;
IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
IOSurfaceManagerToken child_process_token =
GenerateChildProcessToken(kClientId);
RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId, 0);
IOSurfaceManagerHostMsg_UnregisterIOSurface request = {{0}};
request.io_surface_id = kIOSurfaceId;
request.client_id = kClientId;
memcpy(request.token_name, child_process_token.name,
sizeof(child_process_token.name));
// Fails as child process is not allowed to unregister IOSurfaces.
EXPECT_FALSE(HandleUnregisterIOSurfaceRequest(request));
}
TEST_F(BrowserIOSurfaceManagerTest, AcquireIOSurfaceSucceeds) {
const int kIOSurfaceId = 10;
const int kClientId = 1;
const mach_port_t kIOSurfacePortId = 100u;
IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
IOSurfaceManagerToken child_process_token =
GenerateChildProcessToken(kClientId);
RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId,
kIOSurfacePortId);
IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
request.io_surface_id = kIOSurfaceId;
memcpy(request.token_name, child_process_token.name,
sizeof(child_process_token.name));
EXPECT_TRUE(HandleAcquireIOSurfaceRequest(request, &reply));
EXPECT_EQ(kIOSurfacePortId, reply.io_surface_port.name);
}
TEST_F(BrowserIOSurfaceManagerTest, AcquireIOSurfaceFailsWithInvalidToken) {
const int kIOSurfaceId = 10;
const int kClientId = 1;
const mach_port_t kIOSurfacePortId = 100u;
IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId,
kIOSurfacePortId);
IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
request.io_surface_id = kIOSurfaceId;
// Fails as request doesn't contain valid token.
EXPECT_FALSE(HandleAcquireIOSurfaceRequest(request, &reply));
}
TEST_F(BrowserIOSurfaceManagerTest,
AcquireIOSurfaceFailsWithWrongChildProcessToken) {
const int kIOSurfaceId = 10;
const int kClientId1 = 1;
const int kClientId2 = 2;
const mach_port_t kIOSurfacePortId = 100u;
IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
IOSurfaceManagerToken child_process_token2 =
GenerateChildProcessToken(kClientId2);
RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId1,
kIOSurfacePortId);
IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
request.io_surface_id = kIOSurfaceId;
memcpy(request.token_name, child_process_token2.name,
sizeof(child_process_token2.name));
EXPECT_TRUE(HandleAcquireIOSurfaceRequest(request, &reply));
// Fails as child process 2 is not allowed to acquire this IOSurface.
EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL),
reply.io_surface_port.name);
}
TEST_F(BrowserIOSurfaceManagerTest,
AcquireIOSurfaceFailsAfterInvalidatingChildProcessToken) {
const int kIOSurfaceId = 10;
const int kClientId = 1;
const mach_port_t kIOSurfacePortId = 100u;
IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
IOSurfaceManagerToken child_process_token =
GenerateChildProcessToken(kClientId);
RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId,
kIOSurfacePortId);
InvalidateChildProcessToken(child_process_token);
IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
request.io_surface_id = kIOSurfaceId;
memcpy(request.token_name, child_process_token.name,
sizeof(child_process_token.name));
// Fails as token is no longer valid.
EXPECT_FALSE(HandleAcquireIOSurfaceRequest(request, &reply));
}
TEST_F(BrowserIOSurfaceManagerTest,
AcquireIOSurfaceAfterInvalidatingGpuProcessToken) {
const int kIOSurfaceId = 10;
const int kClientId = 1;
const mach_port_t kIOSurfacePortId = 100u;
IOSurfaceManagerToken gpu_process_token = GenerateGpuProcessToken();
IOSurfaceManagerToken child_process_token =
GenerateChildProcessToken(kClientId);
RegisterIOSurface(gpu_process_token, kIOSurfaceId, kClientId,
kIOSurfacePortId);
InvalidateGpuProcessToken();
IOSurfaceManagerHostMsg_AcquireIOSurface request = {{0}};
IOSurfaceManagerMsg_AcquireIOSurfaceReply reply = {{0}};
request.io_surface_id = kIOSurfaceId;
memcpy(request.token_name, child_process_token.name,
sizeof(child_process_token.name));
EXPECT_TRUE(HandleAcquireIOSurfaceRequest(request, &reply));
// Should return invalid port.
EXPECT_EQ(static_cast<mach_port_t>(MACH_PORT_NULL),
reply.io_surface_port.name);
}
} // namespace content