blob: 740366d743a81f173e58c90c094ea4ce74e7d83e [file] [log] [blame]
// Copyright 2016 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 "device/vr/vr_display_impl.h"
#include <memory>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "device/vr/public/mojom/vr_service.mojom.h"
#include "device/vr/test/fake_vr_device.h"
#include "device/vr/test/fake_vr_service_client.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace device {
class VRDisplayImplTest : public testing::Test {
public:
VRDisplayImplTest() {}
~VRDisplayImplTest() override {}
void onDisplaySynced() {}
protected:
void SetUp() override {
device_ = std::make_unique<FakeVRDevice>(static_cast<mojom::XRDeviceId>(1));
device_->SetPose(mojom::VRPose::New());
mojom::VRServiceClientPtr proxy;
client_ = std::make_unique<FakeVRServiceClient>(mojo::MakeRequest(&proxy));
}
std::unique_ptr<VRDisplayImpl> MakeDisplay(
mojom::XRSessionControllerPtr* controller) {
mojom::XRFrameDataProviderPtr data_provider;
auto display = std::make_unique<VRDisplayImpl>(
device(), mojo::MakeRequest(&data_provider),
mojo::MakeRequest(controller));
static_cast<mojom::XRSessionController*>(display.get())
->SetFrameDataRestricted(true);
return display;
}
void RequestSession(VRDisplayImpl* display_impl) {
device_->RequestSession(
mojom::XRRuntimeSessionOptionsPtr(),
base::BindOnce(
[](device::mojom::XRSessionPtr session,
mojom::XRSessionControllerPtr immersive_session_controller) {}));
}
void ExitPresent() { device_->StopSession(); }
bool presenting() { return device_->IsPresenting(); }
VRDeviceBase* device() { return device_.get(); }
FakeVRServiceClient* client() { return client_.get(); }
base::MessageLoop message_loop_;
std::unique_ptr<FakeVRDevice> device_;
std::unique_ptr<FakeVRServiceClient> client_;
DISALLOW_COPY_AND_ASSIGN(VRDisplayImplTest);
};
TEST_F(VRDisplayImplTest, DevicePresentationIsolation) {
mojom::XRSessionControllerPtr controller1;
std::unique_ptr<VRDisplayImpl> display_1 = MakeDisplay(&controller1);
static_cast<mojom::XRSessionController*>(display_1.get())
->SetFrameDataRestricted(false);
mojom::XRSessionControllerPtr controller2;
std::unique_ptr<VRDisplayImpl> display_2 = MakeDisplay(&controller2);
static_cast<mojom::XRSessionController*>(display_2.get())
->SetFrameDataRestricted(false);
// When not presenting either service should be able to access the device.
EXPECT_FALSE(device()->HasExclusiveSession());
bool was_called = false;
auto callback = [](bool expect_null, bool* was_called,
mojom::XRFrameDataPtr data) {
*was_called = true;
EXPECT_EQ(expect_null, !data);
};
static_cast<mojom::XRFrameDataProvider*>(display_1.get())
->GetFrameData(nullptr, base::BindOnce(callback, false, &was_called));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
was_called = false;
static_cast<mojom::XRFrameDataProvider*>(display_2.get())
->GetFrameData(nullptr, base::BindOnce(callback, false, &was_called));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
was_called = false;
// Attempt to present.
RequestSession(display_1.get());
EXPECT_TRUE(presenting());
EXPECT_TRUE(device()->HasExclusiveSession());
// While a device is presenting, no one should have access to magic window.
static_cast<mojom::XRFrameDataProvider*>(display_1.get())
->GetFrameData(nullptr, base::BindOnce(callback, true, &was_called));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
was_called = false;
static_cast<mojom::XRFrameDataProvider*>(display_2.get())
->GetFrameData(nullptr, base::BindOnce(callback, true, &was_called));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
was_called = false;
// Service 1 should be able to exit the presentation it initiated.
ExitPresent();
EXPECT_FALSE(presenting());
EXPECT_FALSE(device()->HasExclusiveSession());
// Once presentation had ended both services should be able to access the
// device.
static_cast<mojom::XRFrameDataProvider*>(display_1.get())
->GetFrameData(nullptr, base::BindOnce(callback, false, &was_called));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
was_called = false;
static_cast<mojom::XRFrameDataProvider*>(display_2.get())
->GetFrameData(nullptr, base::BindOnce(callback, false, &was_called));
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(was_called);
was_called = false;
}
} // namespace device