Commit 7fe9e632 authored by Suman Kancherla's avatar Suman Kancherla Committed by Commit Bot

Reland "[ui/vr] Display different inheadset notifications"

This is a reland of fa29f6dd

The original change broke this test:
WebXrVrBrowserTestStandard.TestInSessionPermissionNotificationCloseWhileVisible
The reason was that the test assumes that BrowserRenderer will not
change. But, with this change, BrowserRenderer will be re-created
everytime StartOverlay() is called after a StopOverlay(). The fix is
to dynamically query for the BrowserRenderer from
VRBrowserRendererThreadWin.

Original change's description:
> [ui/vr] Display different inheadset notifications
>
> Shows a toast with instructions to exit VR session right after
> session starts.
>
> Also, displays inheadset notifications for previously granted
> permissions when entering immersive presentation, and also when
> they become in-use.
>
> Bug: 913502, 732449, 934056, 937383
> Change-Id: I5d17732da62d07cc7d037160e1914b9fa58f1917
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1527863
> Commit-Queue: Suman Kancherla <sumankancherla@chromium.org>
> Reviewed-by: Bill Orr <billorr@chromium.org>
> Reviewed-by: Klaus Weidner <klausw@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#646117}

Bug: 913502, 732449, 934056, 937383, 947927
Change-Id: Ia06d39fa3ba6c6f47072a35fd242757e4c148f0b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1548606Reviewed-by: default avatarBill Orr <billorr@chromium.org>
Commit-Queue: Suman Kancherla <sumankancherla@chromium.org>
Cr-Commit-Position: refs/heads/master@{#646644}
parent 4a2014ae
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_VR_MODEL_CAPTURING_STATE_MODEL_H_ #ifndef CHROME_BROWSER_VR_MODEL_CAPTURING_STATE_MODEL_H_
#define CHROME_BROWSER_VR_MODEL_CAPTURING_STATE_MODEL_H_ #define CHROME_BROWSER_VR_MODEL_CAPTURING_STATE_MODEL_H_
#include <string>
#include "chrome/browser/vr/vr_base_export.h" #include "chrome/browser/vr/vr_base_export.h"
namespace vr { namespace vr {
...@@ -15,6 +17,24 @@ struct VR_BASE_EXPORT CapturingStateModel { ...@@ -15,6 +17,24 @@ struct VR_BASE_EXPORT CapturingStateModel {
bool screen_capture_enabled = false; bool screen_capture_enabled = false;
bool location_access_enabled = false; bool location_access_enabled = false;
bool bluetooth_connected = false; bool bluetooth_connected = false;
bool operator==(const CapturingStateModel& rhs) const {
return audio_capture_enabled == rhs.audio_capture_enabled &&
video_capture_enabled == rhs.video_capture_enabled &&
screen_capture_enabled == rhs.screen_capture_enabled &&
location_access_enabled == rhs.location_access_enabled &&
bluetooth_connected == rhs.bluetooth_connected;
}
bool operator!=(const CapturingStateModel& rhs) const {
return !(*this == rhs);
}
bool IsAnyCapturingEnabled() const {
return audio_capture_enabled || video_capture_enabled ||
screen_capture_enabled || location_access_enabled ||
bluetooth_connected;
}
}; };
typedef bool CapturingStateModel::*CapturingStateModelMemberPtr; typedef bool CapturingStateModel::*CapturingStateModelMemberPtr;
......
...@@ -75,9 +75,8 @@ void UiUtils::PerformActionAndWaitForVisibilityStatus( ...@@ -75,9 +75,8 @@ void UiUtils::PerformActionAndWaitForVisibilityStatus(
main_thread_task_runner_->PostTask( main_thread_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce( base::BindOnce(&UiUtils::WatchElementForVisibilityStatusForTesting,
&BrowserRenderer::WatchElementForVisibilityStatusForTesting, base::Unretained(this), visibility_expectation));
base::Unretained(GetBrowserRenderer()), visibility_expectation));
wait_loop.Run(); wait_loop.Run();
...@@ -88,6 +87,19 @@ void UiUtils::PerformActionAndWaitForVisibilityStatus( ...@@ -88,6 +87,19 @@ void UiUtils::PerformActionAndWaitForVisibilityStatus(
<< UiTestOperationResultToString(result) << "'"; << UiTestOperationResultToString(result) << "'";
} }
void UiUtils::WatchElementForVisibilityStatusForTesting(
VisibilityChangeExpectation visibility_expectation) {
BrowserRenderer* browser_renderer = UiUtils::GetBrowserRenderer();
if (browser_renderer) {
interface_ =
std::make_unique<BrowserTestBrowserRendererBrowserInterface>(this);
browser_renderer->SetBrowserRendererBrowserInterfaceForTesting(
interface_.get());
browser_renderer->WatchElementForVisibilityStatusForTesting(
visibility_expectation);
}
}
void UiUtils::ReportUiOperationResult(const UiTestOperationType& action_type, void UiUtils::ReportUiOperationResult(const UiTestOperationType& action_type,
const UiTestOperationResult& result) { const UiTestOperationResult& result) {
ui_operation_results_[static_cast<int>(action_type)] = result; ui_operation_results_[static_cast<int>(action_type)] = result;
......
...@@ -55,6 +55,8 @@ class UiUtils { ...@@ -55,6 +55,8 @@ class UiUtils {
static VRBrowserRendererThreadWin* GetRendererThread(); static VRBrowserRendererThreadWin* GetRendererThread();
static BrowserRenderer* GetBrowserRenderer(); static BrowserRenderer* GetBrowserRenderer();
void WatchElementForVisibilityStatusForTesting(
VisibilityChangeExpectation visibility_expectation);
std::string UiTestOperationResultToString(UiTestOperationResult& result); std::string UiTestOperationResultToString(UiTestOperationResult& result);
std::unique_ptr<BrowserTestBrowserRendererBrowserInterface> interface_; std::unique_ptr<BrowserTestBrowserRendererBrowserInterface> interface_;
......
...@@ -7,18 +7,21 @@ ...@@ -7,18 +7,21 @@
#include <memory> #include <memory>
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
#include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
#include "chrome/browser/permissions/permission_manager.h"
#include "chrome/browser/permissions/permission_result.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ssl/security_state_tab_helper.h"
#include "chrome/browser/vr/metrics/session_metrics_helper.h" #include "chrome/browser/vr/metrics/session_metrics_helper.h"
#include "chrome/browser/vr/service/browser_xr_runtime.h" #include "chrome/browser/vr/service/browser_xr_runtime.h"
#include "chrome/browser/vr/service/xr_runtime_manager.h" #include "chrome/browser/vr/service/xr_runtime_manager.h"
#include "chrome/browser/vr/vr_tab_helper.h" #include "chrome/browser/vr/vr_tab_helper.h"
#include "chrome/browser/vr/win/vr_browser_renderer_thread_win.h" #include "chrome/browser/vr/win/vr_browser_renderer_thread_win.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_process_host.h" #include "content/public/common/service_manager_connection.h"
#include "content/public/browser/render_view_host.h" #include "services/device/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
namespace vr { namespace vr {
...@@ -26,11 +29,18 @@ namespace vr { ...@@ -26,11 +29,18 @@ namespace vr {
namespace { namespace {
static constexpr base::TimeDelta kPermissionPromptTimeout = static constexpr base::TimeDelta kPermissionPromptTimeout =
base::TimeDelta::FromSeconds(5); base::TimeDelta::FromSeconds(5);
static constexpr base::TimeDelta kPollCapturingStateInterval =
base::TimeDelta::FromSecondsD(0.2);
const CapturingStateModel g_default_capturing_state;
} // namespace } // namespace
VRUiHostImpl::VRUiHostImpl(device::mojom::XRDeviceId device_id, VRUiHostImpl::VRUiHostImpl(device::mojom::XRDeviceId device_id,
device::mojom::XRCompositorHostPtr compositor) device::mojom::XRCompositorHostPtr compositor)
: compositor_(std::move(compositor)), weak_ptr_factory_(this) { : compositor_(std::move(compositor)),
main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
weak_ptr_factory_(this) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DVLOG(1) << __func__; DVLOG(1) << __func__;
...@@ -39,6 +49,10 @@ VRUiHostImpl::VRUiHostImpl(device::mojom::XRDeviceId device_id, ...@@ -39,6 +49,10 @@ VRUiHostImpl::VRUiHostImpl(device::mojom::XRDeviceId device_id,
if (runtime) { if (runtime) {
runtime->AddObserver(this); runtime->AddObserver(this);
} }
auto* connector =
content::ServiceManagerConnection::GetForProcess()->GetConnector();
connector->BindInterface(device::mojom::kServiceName, &geolocation_config_);
} }
VRUiHostImpl::~VRUiHostImpl() { VRUiHostImpl::~VRUiHostImpl() {
...@@ -109,8 +123,11 @@ void VRUiHostImpl::SetWebXRWebContents(content::WebContents* contents) { ...@@ -109,8 +123,11 @@ void VRUiHostImpl::SetWebXRWebContents(content::WebContents* contents) {
web_contents_ = contents; web_contents_ = contents;
if (contents) { if (contents) {
StartUiRendering(); StartUiRendering();
InitCapturingStates();
ui_rendering_thread_->SetWebXrPresenting(true); ui_rendering_thread_->SetWebXrPresenting(true);
PollCapturingState();
PermissionRequestManager::CreateForWebContents(contents); PermissionRequestManager::CreateForWebContents(contents);
permission_request_manager_ = permission_request_manager_ =
PermissionRequestManager::FromWebContents(contents); PermissionRequestManager::FromWebContents(contents);
...@@ -129,6 +146,8 @@ void VRUiHostImpl::SetWebXRWebContents(content::WebContents* contents) { ...@@ -129,6 +146,8 @@ void VRUiHostImpl::SetWebXRWebContents(content::WebContents* contents) {
DVLOG(1) << __func__ << ": No PermissionRequestManager"; DVLOG(1) << __func__ << ": No PermissionRequestManager";
} }
} else { } else {
poll_capturing_state_task_.Cancel();
if (ui_rendering_thread_) if (ui_rendering_thread_)
ui_rendering_thread_->SetWebXrPresenting(false); ui_rendering_thread_->SetWebXrPresenting(false);
StopUiRendering(); StopUiRendering();
...@@ -159,6 +178,7 @@ void VRUiHostImpl::StartUiRendering() { ...@@ -159,6 +178,7 @@ void VRUiHostImpl::StartUiRendering() {
void VRUiHostImpl::StopUiRendering() { void VRUiHostImpl::StopUiRendering() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DVLOG(1) << __func__; DVLOG(1) << __func__;
ui_rendering_thread_ = nullptr; ui_rendering_thread_ = nullptr;
} }
...@@ -185,30 +205,130 @@ void VRUiHostImpl::OnBubbleAdded() { ...@@ -185,30 +205,130 @@ void VRUiHostImpl::OnBubbleAdded() {
SetLocationInfoOnUi(); SetLocationInfoOnUi();
if (indicators_visible_) {
indicators_visible_ = false;
ui_rendering_thread_->SetIndicatorsVisible(false);
}
ui_rendering_thread_->SetVisibleExternalPromptNotification( ui_rendering_thread_->SetVisibleExternalPromptNotification(
ExternalPromptNotificationType::kPromptGenericPermission); ExternalPromptNotificationType::kPromptGenericPermission);
is_prompt_showing_in_headset_ = true; is_external_prompt_showing_in_headset_ = true;
current_prompt_sequence_num_++; external_prompt_timeout_task_.Reset(
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( base::BindRepeating(&VRUiHostImpl::RemoveHeadsetNotificationPrompt,
FROM_HERE, weak_ptr_factory_.GetWeakPtr()));
base::BindOnce(&VRUiHostImpl::RemoveHeadsetNotificationPrompt, main_thread_task_runner_->PostDelayedTask(
weak_ptr_factory_.GetWeakPtr(), FROM_HERE, external_prompt_timeout_task_.callback(),
current_prompt_sequence_num_),
kPermissionPromptTimeout); kPermissionPromptTimeout);
} }
void VRUiHostImpl::OnBubbleRemoved() { void VRUiHostImpl::OnBubbleRemoved() {
RemoveHeadsetNotificationPrompt(current_prompt_sequence_num_); external_prompt_timeout_task_.Cancel();
RemoveHeadsetNotificationPrompt();
} }
void VRUiHostImpl::RemoveHeadsetNotificationPrompt(int prompt_sequence_num) { void VRUiHostImpl::RemoveHeadsetNotificationPrompt() {
if (!is_prompt_showing_in_headset_) if (!is_external_prompt_showing_in_headset_)
return;
if (prompt_sequence_num != current_prompt_sequence_num_)
return; return;
is_prompt_showing_in_headset_ = false; is_external_prompt_showing_in_headset_ = false;
ui_rendering_thread_->SetVisibleExternalPromptNotification( ui_rendering_thread_->SetVisibleExternalPromptNotification(
ExternalPromptNotificationType::kPromptNone); ExternalPromptNotificationType::kPromptNone);
indicators_shown_start_time_ = base::Time::Now();
}
void VRUiHostImpl::InitCapturingStates() {
active_capturing_ = g_default_capturing_state;
potential_capturing_ = g_default_capturing_state;
DCHECK(web_contents_);
PermissionManager* permission_manager = PermissionManager::Get(
Profile::FromBrowserContext(web_contents_->GetBrowserContext()));
const GURL& origin = web_contents_->GetLastCommittedURL();
content::RenderFrameHost* rfh = web_contents_->GetMainFrame();
potential_capturing_.audio_capture_enabled =
permission_manager
->GetPermissionStatusForFrame(
ContentSettingsType::CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, rfh,
origin)
.content_setting == CONTENT_SETTING_ALLOW;
potential_capturing_.video_capture_enabled =
permission_manager
->GetPermissionStatusForFrame(
ContentSettingsType::CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
rfh, origin)
.content_setting == CONTENT_SETTING_ALLOW;
potential_capturing_.location_access_enabled =
permission_manager
->GetPermissionStatusForFrame(
ContentSettingsType::CONTENT_SETTINGS_TYPE_GEOLOCATION, rfh,
origin)
.content_setting == CONTENT_SETTING_ALLOW;
indicators_shown_start_time_ = base::Time::Now();
indicators_visible_ = false;
}
void VRUiHostImpl::PollCapturingState() {
poll_capturing_state_task_.Reset(base::BindRepeating(
&VRUiHostImpl::PollCapturingState, base::Unretained(this)));
main_thread_task_runner_->PostDelayedTask(
FROM_HERE, poll_capturing_state_task_.callback(),
kPollCapturingStateInterval);
// Microphone, Camera, location.
CapturingStateModel active_capturing = active_capturing_;
TabSpecificContentSettings* settings =
TabSpecificContentSettings::FromWebContents(web_contents_);
if (settings) {
const ContentSettingsUsagesState& usages_state =
settings->geolocation_usages_state();
if (!usages_state.state_map().empty()) {
unsigned int state_flags = 0;
usages_state.GetDetailedInfo(nullptr, &state_flags);
active_capturing.location_access_enabled = !!(
state_flags & ContentSettingsUsagesState::TABSTATE_HAS_ANY_ALLOWED);
}
active_capturing.audio_capture_enabled =
(settings->GetMicrophoneCameraState() &
TabSpecificContentSettings::MICROPHONE_ACCESSED) &&
!(settings->GetMicrophoneCameraState() &
TabSpecificContentSettings::MICROPHONE_BLOCKED);
active_capturing.video_capture_enabled =
(settings->GetMicrophoneCameraState() &
TabSpecificContentSettings::CAMERA_ACCESSED) &
!(settings->GetMicrophoneCameraState() &
TabSpecificContentSettings::CAMERA_BLOCKED);
}
// Screen capture, bluetooth.
scoped_refptr<MediaStreamCaptureIndicator> indicator =
MediaCaptureDevicesDispatcher::GetInstance()
->GetMediaStreamCaptureIndicator();
active_capturing.screen_capture_enabled =
indicator->IsBeingMirrored(web_contents_);
active_capturing.bluetooth_connected =
web_contents_->IsConnectedToBluetoothDevice();
if (active_capturing_ != active_capturing) {
indicators_shown_start_time_ = base::Time::Now();
}
active_capturing_ = active_capturing;
ui_rendering_thread_->SetCapturingState(
active_capturing_, g_default_capturing_state, potential_capturing_);
if (indicators_shown_start_time_ + kPermissionPromptTimeout >
base::Time::Now()) {
if (!indicators_visible_ && !is_external_prompt_showing_in_headset_) {
indicators_visible_ = true;
ui_rendering_thread_->SetIndicatorsVisible(true);
}
} else {
if (indicators_visible_) {
indicators_visible_ = false;
ui_rendering_thread_->SetIndicatorsVisible(false);
}
}
} }
} // namespace vr } // namespace vr
...@@ -5,13 +5,17 @@ ...@@ -5,13 +5,17 @@
#ifndef CHROME_BROWSER_VR_UI_HOST_VR_UI_HOST_IMPL_H_ #ifndef CHROME_BROWSER_VR_UI_HOST_VR_UI_HOST_IMPL_H_
#define CHROME_BROWSER_VR_UI_HOST_VR_UI_HOST_IMPL_H_ #define CHROME_BROWSER_VR_UI_HOST_VR_UI_HOST_IMPL_H_
#include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "chrome/browser/permissions/permission_request_manager.h" #include "chrome/browser/permissions/permission_request_manager.h"
#include "chrome/browser/vr/model/capturing_state_model.h"
#include "chrome/browser/vr/service/browser_xr_runtime.h" #include "chrome/browser/vr/service/browser_xr_runtime.h"
#include "chrome/browser/vr/service/vr_ui_host.h" #include "chrome/browser/vr/service/vr_ui_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "services/device/public/mojom/geolocation_config.mojom.h"
namespace vr { namespace vr {
...@@ -46,17 +50,28 @@ class VRUiHostImpl : public VRUiHost, ...@@ -46,17 +50,28 @@ class VRUiHostImpl : public VRUiHost,
void OnBubbleAdded() override; void OnBubbleAdded() override;
void OnBubbleRemoved() override; void OnBubbleRemoved() override;
void RemoveHeadsetNotificationPrompt(int prompt_sequence_num); void RemoveHeadsetNotificationPrompt();
void SetLocationInfoOnUi(); void SetLocationInfoOnUi();
void InitCapturingStates();
void PollCapturingState();
device::mojom::XRCompositorHostPtr compositor_; device::mojom::XRCompositorHostPtr compositor_;
std::unique_ptr<VRBrowserRendererThreadWin> ui_rendering_thread_; std::unique_ptr<VRBrowserRendererThreadWin> ui_rendering_thread_;
device::mojom::VRDisplayInfoPtr info_; device::mojom::VRDisplayInfoPtr info_;
content::WebContents* web_contents_ = nullptr; content::WebContents* web_contents_ = nullptr;
PermissionRequestManager* permission_request_manager_ = nullptr; PermissionRequestManager* permission_request_manager_ = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
base::CancelableClosure external_prompt_timeout_task_;
bool is_external_prompt_showing_in_headset_ = false;
bool is_prompt_showing_in_headset_ = false; CapturingStateModel active_capturing_;
int current_prompt_sequence_num_ = 0; CapturingStateModel potential_capturing_;
device::mojom::GeolocationConfigPtr geolocation_config_;
base::CancelableClosure poll_capturing_state_task_;
base::Time indicators_shown_start_time_;
bool indicators_visible_ = false;
THREAD_CHECKER(thread_checker_); THREAD_CHECKER(thread_checker_);
......
This diff is collapsed.
...@@ -1307,6 +1307,7 @@ TEST_F(UiTest, RepositionHostedUi) { ...@@ -1307,6 +1307,7 @@ TEST_F(UiTest, RepositionHostedUi) {
// Ensures that permissions do not appear after showing hosted UI. // Ensures that permissions do not appear after showing hosted UI.
TEST_F(UiTest, DoNotShowIndicatorsAfterHostedUi) { TEST_F(UiTest, DoNotShowIndicatorsAfterHostedUi) {
#if !defined(OS_WIN)
CreateScene(kInWebVr); CreateScene(kInWebVr);
auto browser_ui = ui_->GetBrowserUiWeakPtr(); auto browser_ui = ui_->GetBrowserUiWeakPtr();
browser_ui->SetWebVrMode(true); browser_ui->SetWebVrMode(true);
...@@ -1323,12 +1324,14 @@ TEST_F(UiTest, DoNotShowIndicatorsAfterHostedUi) { ...@@ -1323,12 +1324,14 @@ TEST_F(UiTest, DoNotShowIndicatorsAfterHostedUi) {
model_->web_vr.showing_hosted_ui = false; model_->web_vr.showing_hosted_ui = false;
OnBeginFrame(); OnBeginFrame();
EXPECT_FALSE(IsVisible(kWebVrExclusiveScreenToast)); EXPECT_FALSE(IsVisible(kWebVrExclusiveScreenToast));
#endif
} }
// Ensures that permissions appear on long press, and that when the menu button // Ensures that permissions appear on long press, and that when the menu button
// is released that we do not show the exclusive screen toast. Distinguishing // is released that we do not show the exclusive screen toast. Distinguishing
// these cases requires knowledge of the previous state. // these cases requires knowledge of the previous state.
TEST_F(UiTest, LongPressMenuButtonInWebVrMode) { TEST_F(UiTest, LongPressMenuButtonInWebVrMode) {
#if !defined(OS_WIN)
CreateScene(kInWebVr); CreateScene(kInWebVr);
auto browser_ui = ui_->GetBrowserUiWeakPtr(); auto browser_ui = ui_->GetBrowserUiWeakPtr();
browser_ui->SetWebVrMode(true); browser_ui->SetWebVrMode(true);
...@@ -1360,6 +1363,7 @@ TEST_F(UiTest, LongPressMenuButtonInWebVrMode) { ...@@ -1360,6 +1363,7 @@ TEST_F(UiTest, LongPressMenuButtonInWebVrMode) {
std::make_unique<InputEvent>(InputEvent::kMenuButtonLongPressEnd)); std::make_unique<InputEvent>(InputEvent::kMenuButtonLongPressEnd));
ui_->HandleMenuButtonEvents(&events); ui_->HandleMenuButtonEvents(&events);
EXPECT_FALSE(model_->menu_button_long_pressed); EXPECT_FALSE(model_->menu_button_long_pressed);
#endif
} }
TEST_F(UiTest, MenuItems) { TEST_F(UiTest, MenuItems) {
......
...@@ -304,7 +304,7 @@ void GraphicsDelegateWin::PrepareBufferForContentQuadLayer( ...@@ -304,7 +304,7 @@ void GraphicsDelegateWin::PrepareBufferForContentQuadLayer(
} }
void GraphicsDelegateWin::PrepareBufferForBrowserUi() { void GraphicsDelegateWin::PrepareBufferForBrowserUi() {
gl_->ClearColor(0, 1, 0, 1); gl_->ClearColor(0, 0, 0, 0);
gl_->Clear(GL_COLOR_BUFFER_BIT); gl_->Clear(GL_COLOR_BUFFER_BIT);
DCHECK(prepared_drawing_buffer_ == DrawingBufferMode::kNone); DCHECK(prepared_drawing_buffer_ == DrawingBufferMode::kNone);
......
...@@ -13,13 +13,14 @@ SchedulerDelegateWin::~SchedulerDelegateWin() {} ...@@ -13,13 +13,14 @@ SchedulerDelegateWin::~SchedulerDelegateWin() {}
void SchedulerDelegateWin::OnPose(base::OnceCallback<void()> on_frame_ended, void SchedulerDelegateWin::OnPose(base::OnceCallback<void()> on_frame_ended,
gfx::Transform head_pose, gfx::Transform head_pose,
bool draw_overlay,
bool draw_ui) { bool draw_ui) {
on_frame_ended_ = std::move(on_frame_ended); on_frame_ended_ = std::move(on_frame_ended);
base::TimeTicks now = base::TimeTicks::Now(); base::TimeTicks now = base::TimeTicks::Now();
if (draw_ui) if (draw_overlay)
browser_renderer_->DrawBrowserFrame(now);
else
browser_renderer_->DrawWebXrFrame(now, head_pose); browser_renderer_->DrawWebXrFrame(now, head_pose);
else if (draw_ui)
browser_renderer_->DrawBrowserFrame(now);
} }
void SchedulerDelegateWin::OnPause() { void SchedulerDelegateWin::OnPause() {
......
...@@ -17,6 +17,7 @@ class SchedulerDelegateWin : public SchedulerDelegate { ...@@ -17,6 +17,7 @@ class SchedulerDelegateWin : public SchedulerDelegate {
// Tell browser when poses available, when we rendered, etc. // Tell browser when poses available, when we rendered, etc.
void OnPose(base::OnceCallback<void()> on_frame_ended, void OnPose(base::OnceCallback<void()> on_frame_ended,
gfx::Transform head_pose, gfx::Transform head_pose,
bool draw_overlay,
bool draw_ui); bool draw_ui);
private: private:
......
...@@ -57,6 +57,8 @@ void VRBrowserRendererThreadWin::StopOverlay() { ...@@ -57,6 +57,8 @@ void VRBrowserRendererThreadWin::StopOverlay() {
started_ = false; started_ = false;
graphics_ = nullptr; graphics_ = nullptr;
scheduler_ = nullptr; scheduler_ = nullptr;
ui_ = nullptr;
scheduler_ui_ = nullptr;
} }
void VRBrowserRendererThreadWin::SetVRDisplayInfo( void VRBrowserRendererThreadWin::SetVRDisplayInfo(
...@@ -115,6 +117,13 @@ void VRBrowserRendererThreadWin::StopWebXrTimeout() { ...@@ -115,6 +117,13 @@ void VRBrowserRendererThreadWin::StopWebXrTimeout() {
OnSpinnerVisibilityChanged(false); OnSpinnerVisibilityChanged(false);
} }
int VRBrowserRendererThreadWin::GetNextRequestId() {
current_request_id_++;
if (current_request_id_ >= 0x10000)
current_request_id_ = 0;
return current_request_id_;
}
void VRBrowserRendererThreadWin::OnWebXrTimeoutImminent() { void VRBrowserRendererThreadWin::OnWebXrTimeoutImminent() {
OnSpinnerVisibilityChanged(true); OnSpinnerVisibilityChanged(true);
scheduler_ui_->OnWebXrTimeoutImminent(); scheduler_ui_->OnWebXrTimeoutImminent();
...@@ -135,16 +144,48 @@ void VRBrowserRendererThreadWin::SetVisibleExternalPromptNotification( ...@@ -135,16 +144,48 @@ void VRBrowserRendererThreadWin::SetVisibleExternalPromptNotification(
ui_->SetVisibleExternalPromptNotification(prompt); ui_->SetVisibleExternalPromptNotification(prompt);
overlay_->SetOverlayAndWebXRVisibility(draw_state_.ShouldDrawUI(), if (overlay_)
draw_state_.ShouldDrawWebXR()); overlay_->SetOverlayAndWebXRVisibility(draw_state_.ShouldDrawUI(),
draw_state_.ShouldDrawWebXR());
if (draw_state_.ShouldDrawUI()) { if (draw_state_.ShouldDrawUI()) {
overlay_->RequestNextOverlayPose(base::BindOnce( if (overlay_) // False only while testing
&VRBrowserRendererThreadWin::OnPose, base::Unretained(this))); overlay_->RequestNextOverlayPose(
base::BindOnce(&VRBrowserRendererThreadWin::OnPose,
base::Unretained(this), GetNextRequestId()));
} else { } else {
StopOverlay(); StopOverlay();
} }
} }
void VRBrowserRendererThreadWin::SetIndicatorsVisible(bool visible) {
if (!draw_state_.SetIndicatorsVisible(visible))
return;
if (draw_state_.ShouldDrawUI())
StartOverlay();
if (overlay_)
overlay_->SetOverlayAndWebXRVisibility(draw_state_.ShouldDrawUI(),
draw_state_.ShouldDrawWebXR());
if (draw_state_.ShouldDrawUI()) {
if (overlay_) // False only while testing
overlay_->RequestNextOverlayPose(
base::BindOnce(&VRBrowserRendererThreadWin::OnPose,
base::Unretained(this), GetNextRequestId()));
} else {
StopOverlay();
}
}
void VRBrowserRendererThreadWin::SetCapturingState(
const CapturingStateModel& active_capturing,
const CapturingStateModel& background_capturing,
const CapturingStateModel& potential_capturing) {
if (ui_)
ui_->SetCapturingState(active_capturing, background_capturing,
potential_capturing);
}
VRBrowserRendererThreadWin* VRBrowserRendererThreadWin*
VRBrowserRendererThreadWin::GetInstanceForTesting() { VRBrowserRendererThreadWin::GetInstanceForTesting() {
return instance_for_testing_; return instance_for_testing_;
...@@ -263,22 +304,24 @@ void VRBrowserRendererThreadWin::StartOverlay() { ...@@ -263,22 +304,24 @@ void VRBrowserRendererThreadWin::StartOverlay() {
} }
void VRBrowserRendererThreadWin::OnSpinnerVisibilityChanged(bool visible) { void VRBrowserRendererThreadWin::OnSpinnerVisibilityChanged(bool visible) {
if (draw_state_.SetSpinnerVisible(visible)) { if (!draw_state_.SetSpinnerVisible(visible))
if (draw_state_.ShouldDrawUI()) { return;
StartOverlay(); if (draw_state_.ShouldDrawUI()) {
} StartOverlay();
}
if (overlay_) {
overlay_->SetOverlayAndWebXRVisibility(draw_state_.ShouldDrawUI(), if (overlay_) {
draw_state_.ShouldDrawWebXR()); overlay_->SetOverlayAndWebXRVisibility(draw_state_.ShouldDrawUI(),
} draw_state_.ShouldDrawWebXR());
}
if (draw_state_.ShouldDrawUI()) {
overlay_->RequestNextOverlayPose(base::BindOnce( if (draw_state_.ShouldDrawUI()) {
&VRBrowserRendererThreadWin::OnPose, base::Unretained(this))); if (overlay_) // False only while testing.
} else { overlay_->RequestNextOverlayPose(
StopOverlay(); base::BindOnce(&VRBrowserRendererThreadWin::OnPose,
} base::Unretained(this), GetNextRequestId()));
} else {
StopOverlay();
} }
} }
...@@ -288,12 +331,16 @@ void VRBrowserRendererThreadWin::OnWebXRSubmitted() { ...@@ -288,12 +331,16 @@ void VRBrowserRendererThreadWin::OnWebXRSubmitted() {
StopWebXrTimeout(); StopWebXrTimeout();
} }
void VRBrowserRendererThreadWin::OnPose(device::mojom::XRFrameDataPtr data) { void VRBrowserRendererThreadWin::OnPose(int request_id,
device::mojom::XRFrameDataPtr data) {
if (request_id != current_request_id_) {
// Old request. Do nothing.
return;
}
if (!draw_state_.ShouldDrawUI()) { if (!draw_state_.ShouldDrawUI()) {
// We shouldn't be showing UI. // We shouldn't be showing UI.
overlay_->SetOverlayAndWebXRVisibility(draw_state_.ShouldDrawUI(), overlay_->SetOverlayAndWebXRVisibility(draw_state_.ShouldDrawUI(),
draw_state_.ShouldDrawWebXR()); draw_state_.ShouldDrawWebXR());
if (graphics_) if (graphics_)
graphics_->ResetMemoryBuffer(); graphics_->ResetMemoryBuffer();
return; return;
...@@ -330,7 +377,8 @@ void VRBrowserRendererThreadWin::OnPose(device::mojom::XRFrameDataPtr data) { ...@@ -330,7 +377,8 @@ void VRBrowserRendererThreadWin::OnPose(device::mojom::XRFrameDataPtr data) {
// calling the callback if we are destroyed. // calling the callback if we are destroyed.
scheduler_->OnPose(base::BindOnce(&VRBrowserRendererThreadWin::SubmitFrame, scheduler_->OnPose(base::BindOnce(&VRBrowserRendererThreadWin::SubmitFrame,
base::Unretained(this), std::move(data)), base::Unretained(this), std::move(data)),
head_from_world, draw_state_.ShouldDrawUI()); head_from_world, draw_state_.ShouldDrawWebXR(),
draw_state_.ShouldDrawUI());
} }
void VRBrowserRendererThreadWin::SubmitFrame( void VRBrowserRendererThreadWin::SubmitFrame(
...@@ -345,24 +393,28 @@ void VRBrowserRendererThreadWin::SubmitFrame( ...@@ -345,24 +393,28 @@ void VRBrowserRendererThreadWin::SubmitFrame(
} }
void VRBrowserRendererThreadWin::SubmitResult(bool success) { void VRBrowserRendererThreadWin::SubmitResult(bool success) {
if (!success) { if (!success && graphics_) {
graphics_->ResetMemoryBuffer(); graphics_->ResetMemoryBuffer();
} }
if (scheduler_ui_ && success)
scheduler_ui_->OnWebXrFrameAvailable();
if (draw_state_.ShouldDrawUI() && started_) { if (draw_state_.ShouldDrawUI() && started_) {
overlay_->RequestNextOverlayPose(base::BindOnce( overlay_->RequestNextOverlayPose(
&VRBrowserRendererThreadWin::OnPose, base::Unretained(this))); base::BindOnce(&VRBrowserRendererThreadWin::OnPose,
base::Unretained(this), GetNextRequestId()));
} }
} }
// VRBrowserRendererThreadWin::DrawContentType functions. // VRBrowserRendererThreadWin::DrawContentType functions.
bool VRBrowserRendererThreadWin::DrawState::ShouldDrawUI() { bool VRBrowserRendererThreadWin::DrawState::ShouldDrawUI() {
return prompt_ != ExternalPromptNotificationType::kPromptNone || return prompt_ != ExternalPromptNotificationType::kPromptNone ||
spinner_visible_; spinner_visible_ || indicators_visible_;
} }
bool VRBrowserRendererThreadWin::DrawState::ShouldDrawWebXR() { bool VRBrowserRendererThreadWin::DrawState::ShouldDrawWebXR() {
return prompt_ == ExternalPromptNotificationType::kPromptNone && return (prompt_ == ExternalPromptNotificationType::kPromptNone &&
!spinner_visible_; !spinner_visible_) ||
indicators_visible_;
} }
bool VRBrowserRendererThreadWin::DrawState::SetPrompt( bool VRBrowserRendererThreadWin::DrawState::SetPrompt(
...@@ -380,4 +432,11 @@ bool VRBrowserRendererThreadWin::DrawState::SetSpinnerVisible(bool visible) { ...@@ -380,4 +432,11 @@ bool VRBrowserRendererThreadWin::DrawState::SetSpinnerVisible(bool visible) {
return old_ui != ShouldDrawUI() || old_webxr != ShouldDrawWebXR(); return old_ui != ShouldDrawUI() || old_webxr != ShouldDrawWebXR();
} }
bool VRBrowserRendererThreadWin::DrawState::SetIndicatorsVisible(bool visible) {
bool old_ui = ShouldDrawUI();
bool old_webxr = ShouldDrawWebXR();
indicators_visible_ = visible;
return old_ui != ShouldDrawUI() || old_webxr != ShouldDrawWebXR();
}
} // namespace vr } // namespace vr
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "chrome/browser/vr/browser_renderer.h" #include "chrome/browser/vr/browser_renderer.h"
#include "chrome/browser/vr/model/capturing_state_model.h"
#include "chrome/browser/vr/model/web_vr_model.h" #include "chrome/browser/vr/model/web_vr_model.h"
#include "chrome/browser/vr/service/browser_xr_runtime.h" #include "chrome/browser/vr/service/browser_xr_runtime.h"
#include "chrome/browser/vr/vr_export.h" #include "chrome/browser/vr/vr_export.h"
...@@ -37,6 +38,10 @@ class VR_EXPORT VRBrowserRendererThreadWin { ...@@ -37,6 +38,10 @@ class VR_EXPORT VRBrowserRendererThreadWin {
// The below function(s) affect(s) whether UI is drawn or not. // The below function(s) affect(s) whether UI is drawn or not.
void SetVisibleExternalPromptNotification( void SetVisibleExternalPromptNotification(
ExternalPromptNotificationType prompt); ExternalPromptNotificationType prompt);
void SetIndicatorsVisible(bool visible);
void SetCapturingState(const CapturingStateModel& active_capturing,
const CapturingStateModel& background_capturing,
const CapturingStateModel& potential_capturing);
static VRBrowserRendererThreadWin* GetInstanceForTesting(); static VRBrowserRendererThreadWin* GetInstanceForTesting();
BrowserRenderer* GetBrowserRendererForTesting(); BrowserRenderer* GetBrowserRendererForTesting();
...@@ -48,6 +53,7 @@ class VR_EXPORT VRBrowserRendererThreadWin { ...@@ -48,6 +53,7 @@ class VR_EXPORT VRBrowserRendererThreadWin {
// State changing methods. // State changing methods.
bool SetPrompt(ExternalPromptNotificationType prompt); bool SetPrompt(ExternalPromptNotificationType prompt);
bool SetSpinnerVisible(bool visible); bool SetSpinnerVisible(bool visible);
bool SetIndicatorsVisible(bool visible);
// State querying methods. // State querying methods.
bool ShouldDrawUI(); bool ShouldDrawUI();
...@@ -58,9 +64,10 @@ class VR_EXPORT VRBrowserRendererThreadWin { ...@@ -58,9 +64,10 @@ class VR_EXPORT VRBrowserRendererThreadWin {
ExternalPromptNotificationType::kPromptNone; ExternalPromptNotificationType::kPromptNone;
bool spinner_visible_ = false; bool spinner_visible_ = false;
bool indicators_visible_ = false;
}; };
void OnPose(device::mojom::XRFrameDataPtr data); void OnPose(int request_id, device::mojom::XRFrameDataPtr data);
void SubmitResult(bool success); void SubmitResult(bool success);
void SubmitFrame(device::mojom::XRFrameDataPtr data); void SubmitFrame(device::mojom::XRFrameDataPtr data);
void StartOverlay(); void StartOverlay();
...@@ -71,6 +78,7 @@ class VR_EXPORT VRBrowserRendererThreadWin { ...@@ -71,6 +78,7 @@ class VR_EXPORT VRBrowserRendererThreadWin {
void OnWebXrTimedOut(); void OnWebXrTimedOut();
void StartWebXrTimeout(); void StartWebXrTimeout();
void StopWebXrTimeout(); void StopWebXrTimeout();
int GetNextRequestId();
// We need to do some initialization of GraphicsDelegateWin before // We need to do some initialization of GraphicsDelegateWin before
// browser_renderer_, so we first store it in a unique_ptr, then transition // browser_renderer_, so we first store it in a unique_ptr, then transition
...@@ -94,6 +102,7 @@ class VR_EXPORT VRBrowserRendererThreadWin { ...@@ -94,6 +102,7 @@ class VR_EXPORT VRBrowserRendererThreadWin {
DrawState draw_state_; DrawState draw_state_;
bool started_ = false; bool started_ = false;
bool webxr_presenting_ = false; bool webxr_presenting_ = false;
int current_request_id_ = 0;
device::mojom::ImmersiveOverlayPtr overlay_; device::mojom::ImmersiveOverlayPtr overlay_;
device::mojom::VRDisplayInfoPtr display_info_; device::mojom::VRDisplayInfoPtr display_info_;
......
...@@ -64,10 +64,6 @@ void XRCompositorCommon::ClearPendingFrame() { ...@@ -64,10 +64,6 @@ void XRCompositorCommon::ClearPendingFrame() {
// frame, we allow the renderer to receive poses. // frame, we allow the renderer to receive poses.
std::move(delayed_get_frame_data_callback_).Run(); std::move(delayed_get_frame_data_callback_).Run();
} }
if (delayed_overlay_get_frame_data_callback_ && overlay_visible_) {
std::move(delayed_overlay_get_frame_data_callback_).Run();
}
} }
void XRCompositorCommon::SubmitFrameMissing(int16_t frame_index, void XRCompositorCommon::SubmitFrameMissing(int16_t frame_index,
...@@ -250,7 +246,6 @@ void XRCompositorCommon::ExitPresent() { ...@@ -250,7 +246,6 @@ void XRCompositorCommon::ExitPresent() {
// Kill outstanding overlays: // Kill outstanding overlays:
overlay_visible_ = false; overlay_visible_ = false;
delayed_overlay_get_frame_data_callback_.Reset();
overlay_binding_.Close(); overlay_binding_.Close();
texture_helper_.SetSourceAndOverlayVisible(false, false); texture_helper_.SetSourceAndOverlayVisible(false, false);
...@@ -402,16 +397,6 @@ void XRCompositorCommon::RequestNextOverlayPose( ...@@ -402,16 +397,6 @@ void XRCompositorCommon::RequestNextOverlayPose(
DCHECK(overlay_visible_); DCHECK(overlay_visible_);
TRACE_EVENT_INSTANT0("xr", "RequestOverlayPose", TRACE_EVENT_SCOPE_THREAD); TRACE_EVENT_INSTANT0("xr", "RequestOverlayPose", TRACE_EVENT_SCOPE_THREAD);
// If we've already given out a pose for the current frame delay giving out a
// pose until the next frame we are visible.
if (pending_frame_ && pending_frame_->overlay_has_pose_) {
DCHECK(!delayed_overlay_get_frame_data_callback_);
delayed_overlay_get_frame_data_callback_ =
base::BindOnce(&XRCompositorCommon::RequestNextOverlayPose,
base::Unretained(this), std::move(callback));
return;
}
// Ensure we have a pending frame. // Ensure we have a pending frame.
StartPendingFrame(); StartPendingFrame();
pending_frame_->overlay_has_pose_ = true; pending_frame_->overlay_has_pose_ = true;
......
...@@ -150,7 +150,6 @@ class XRCompositorCommon : public base::Thread, ...@@ -150,7 +150,6 @@ class XRCompositorCommon : public base::Thread,
bool webxr_visible_ = true; // The browser may hide a presenting session. bool webxr_visible_ = true; // The browser may hide a presenting session.
bool overlay_visible_ = false; bool overlay_visible_ = false;
base::OnceCallback<void()> delayed_get_frame_data_callback_; base::OnceCallback<void()> delayed_get_frame_data_callback_;
base::OnceCallback<void()> delayed_overlay_get_frame_data_callback_;
gfx::RectF left_webxr_bounds_; gfx::RectF left_webxr_bounds_;
gfx::RectF right_webxr_bounds_; gfx::RectF right_webxr_bounds_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment