1 // Copyright 2017 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 <memory>
6 #include <utility>
7 #include <vector>
8 
9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/run_loop.h"
12 #include "base/test/task_environment.h"
13 #include "base/test/test_simple_task_runner.h"
14 #include "base/threading/thread_task_runner_handle.h"
15 #include "device/vr/orientation/orientation_device.h"
16 #include "device/vr/orientation/orientation_device_provider.h"
17 #include "device/vr/test/fake_orientation_provider.h"
18 #include "device/vr/test/fake_sensor_provider.h"
19 #include "mojo/public/cpp/bindings/pending_receiver.h"
20 #include "mojo/public/cpp/bindings/pending_remote.h"
21 #include "mojo/public/cpp/bindings/remote.h"
22 #include "services/device/public/cpp/generic_sensor/sensor_reading.h"
23 #include "services/device/public/cpp/generic_sensor/sensor_reading_shared_buffer_reader.h"
24 #include "services/device/public/cpp/generic_sensor/sensor_traits.h"
25 #include "services/device/public/mojom/sensor.mojom.h"
26 #include "services/device/public/mojom/sensor_provider.mojom.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "ui/display/display.h"
29 #include "ui/display/screen.h"
30 #include "ui/gfx/geometry/quaternion.h"
31 
32 namespace device {
33 
34 class VROrientationDeviceProviderTest : public testing::Test {
35  protected:
36   VROrientationDeviceProviderTest() = default;
37   ~VROrientationDeviceProviderTest() override = default;
SetUp()38   void SetUp() override {
39     fake_sensor_provider_ = std::make_unique<FakeXRSensorProvider>();
40 
41     fake_sensor_ = std::make_unique<FakeOrientationSensor>(
42         sensor_.InitWithNewPipeAndPassReceiver());
43     shared_buffer_handle_ = mojo::SharedBufferHandle::Create(
44         sizeof(SensorReadingSharedBuffer) *
45         (static_cast<uint64_t>(mojom::SensorType::kMaxValue) + 1));
46 
47     mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider;
48     fake_sensor_provider_->Bind(
49         sensor_provider.InitWithNewPipeAndPassReceiver());
50     provider_ = std::make_unique<VROrientationDeviceProvider>(
51         std::move(sensor_provider));
52 
53     task_environment_.RunUntilIdle();
54   }
55 
TearDown()56   void TearDown() override {}
57 
InitializeDevice(mojom::SensorInitParamsPtr params)58   void InitializeDevice(mojom::SensorInitParamsPtr params) {
59     // Be sure GetSensor goes through so the callback is set.
60     task_environment_.RunUntilIdle();
61 
62     fake_sensor_provider_->CallCallback(std::move(params));
63 
64     // Allow the callback call to go through.
65     task_environment_.RunUntilIdle();
66   }
67 
FakeInitParams()68   mojom::SensorInitParamsPtr FakeInitParams() {
69     auto init_params = mojom::SensorInitParams::New();
70     init_params->sensor = std::move(sensor_);
71     init_params->default_configuration = PlatformSensorConfiguration(
72         SensorTraits<kOrientationSensorType>::kDefaultFrequency);
73 
74     init_params->client_receiver = sensor_client_.BindNewPipeAndPassReceiver();
75 
76     init_params->memory = shared_buffer_handle_->Clone(
77         mojo::SharedBufferHandle::AccessMode::READ_ONLY);
78 
79     init_params->buffer_offset =
80         SensorReadingSharedBuffer::GetOffset(kOrientationSensorType);
81 
82     return init_params;
83   }
84 
85   base::RepeatingCallback<void(device::mojom::XRDeviceId,
86                                mojom::VRDisplayInfoPtr,
87                                mojo::PendingRemote<mojom::XRRuntime> device)>
DeviceAndIdCallbackFailIfCalled()88   DeviceAndIdCallbackFailIfCalled() {
89     return base::BindRepeating(
90         [](device::mojom::XRDeviceId id, mojom::VRDisplayInfoPtr,
91            mojo::PendingRemote<mojom::XRRuntime> device) { FAIL(); });
92   }
93 
94   base::RepeatingCallback<void(device::mojom::XRDeviceId)>
DeviceIdCallbackFailIfCalled()95   DeviceIdCallbackFailIfCalled() {
96     return base::BindRepeating([](device::mojom::XRDeviceId id) { FAIL(); });
97   }
98 
99   base::RepeatingCallback<void(device::mojom::XRDeviceId,
100                                mojom::VRDisplayInfoPtr,
101                                mojo::PendingRemote<mojom::XRRuntime> device)>
DeviceAndIdCallbackMustBeCalled(base::RunLoop * loop)102   DeviceAndIdCallbackMustBeCalled(base::RunLoop* loop) {
103     return base::BindRepeating(
104         [](base::OnceClosure quit_closure, device::mojom::XRDeviceId id,
105            mojom::VRDisplayInfoPtr info,
106            mojo::PendingRemote<mojom::XRRuntime> device) {
107           ASSERT_TRUE(device);
108           ASSERT_TRUE(info);
109           std::move(quit_closure).Run();
110         },
111         loop->QuitClosure());
112   }
113 
114   base::RepeatingCallback<void(device::mojom::XRDeviceId)>
DeviceIdCallbackMustBeCalled(base::RunLoop * loop)115   DeviceIdCallbackMustBeCalled(base::RunLoop* loop) {
116     return base::BindRepeating(
117         [](base::OnceClosure quit_closure, device::mojom::XRDeviceId id) {
118           std::move(quit_closure).Run();
119         },
120         loop->QuitClosure());
121   }
122 
ClosureFailIfCalled()123   base::OnceClosure ClosureFailIfCalled() {
124     return base::BindOnce([]() { FAIL(); });
125   }
126 
ClosureMustBeCalled(base::RunLoop * loop)127   base::OnceClosure ClosureMustBeCalled(base::RunLoop* loop) {
128     return base::BindOnce(
129         [](base::OnceClosure quit_closure) { std::move(quit_closure).Run(); },
130         loop->QuitClosure());
131   }
132 
133   // Needed for MakeRequest to work.
134   base::test::TaskEnvironment task_environment_;
135 
136   std::unique_ptr<VROrientationDeviceProvider> provider_;
137 
138   std::unique_ptr<FakeXRSensorProvider> fake_sensor_provider_;
139   mojo::Remote<mojom::SensorProvider> sensor_provider_;
140 
141   // Fake Sensor Init params objects
142   std::unique_ptr<FakeOrientationSensor> fake_sensor_;
143   mojo::PendingRemote<mojom::Sensor> sensor_;
144   mojo::ScopedSharedBufferHandle shared_buffer_handle_;
145   mojo::Remote<mojom::SensorClient> sensor_client_;
146 
147   DISALLOW_COPY_AND_ASSIGN(VROrientationDeviceProviderTest);
148 };
149 
TEST_F(VROrientationDeviceProviderTest,InitializationTest)150 TEST_F(VROrientationDeviceProviderTest, InitializationTest) {
151   // Check that without running anything, the provider will not be initialized.
152   EXPECT_FALSE(provider_->Initialized());
153 }
154 
TEST_F(VROrientationDeviceProviderTest,InitializationCallbackSuccessTest)155 TEST_F(VROrientationDeviceProviderTest, InitializationCallbackSuccessTest) {
156   base::RunLoop wait_for_device;
157   base::RunLoop wait_for_init;
158 
159   provider_->Initialize(DeviceAndIdCallbackMustBeCalled(&wait_for_device),
160                         DeviceIdCallbackFailIfCalled(),
161                         ClosureMustBeCalled(&wait_for_init));
162 
163   InitializeDevice(FakeInitParams());
164 
165   wait_for_init.Run();
166   wait_for_device.Run();
167 
168   EXPECT_TRUE(provider_->Initialized());
169 }
170 
TEST_F(VROrientationDeviceProviderTest,InitializationCallbackFailureTest)171 TEST_F(VROrientationDeviceProviderTest, InitializationCallbackFailureTest) {
172   base::RunLoop wait_for_init;
173 
174   provider_->Initialize(DeviceAndIdCallbackFailIfCalled(),
175                         DeviceIdCallbackFailIfCalled(),
176                         ClosureMustBeCalled(&wait_for_init));
177 
178   InitializeDevice(nullptr);
179 
180   // Wait for the initialization to finish.
181   wait_for_init.Run();
182   EXPECT_TRUE(provider_->Initialized());
183 }
184 
185 }  // namespace device
186