0

Standup Skeleton Code for Cardboard Runtime

Creates features and infrastructure and initial include to begin
building the Cardboard runtime for WebXR. Currently the runtime will
simply reject all session requests, but it links in and initializes the
sdk as a proof of concept that all build files should be mostly
structured right. Stands up the following skeletons/infrastructure:
* Feature Flag and About Flags entry
* Creates CardboardDevice/Provider and adds it (and does not add the
GVR Device) based on the Cardboard Feature Flag
* Adds build files for //third_party/cardboard
* Adds VR Buildflag for Cardboard
* Creates basic directory and build file structure for cardboard
* Incorporates cardboard build into Chrome build.

Bug: 989117
Change-Id: I3e0e4349cb1a031404c38b0a6175681575c23e4b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4160186
Commit-Queue: Alexander Cooper <alcooper@chromium.org>
Reviewed-by: Alex Gough <ajgo@chromium.org>
Reviewed-by: Piotr Bialecki <bialpio@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1096488}
This commit is contained in:
Alex Cooper
2023-01-24 23:29:54 +00:00
committed by Chromium LUCI CQ
parent 7e7dc6dc09
commit bdd9a76129
33 changed files with 769 additions and 2 deletions

@ -127,6 +127,10 @@ bool IsVMInitialized() {
return g_jvm != nullptr;
}
JavaVM* GetVM() {
return g_jvm;
}
void InitGlobalClassLoader(JNIEnv* env) {
DCHECK(g_class_loader == nullptr);

@ -79,6 +79,9 @@ BASE_EXPORT void InitVM(JavaVM* vm);
// Returns true if the global JVM has been initialized.
BASE_EXPORT bool IsVMInitialized();
// Returns the global JVM, or nullptr if it has not been initialized.
BASE_EXPORT JavaVM* GetVM();
// Initializes the global ClassLoader used by the GetClass and LazyGetClass
// methods. This is needed because JNI will use the base ClassLoader when there
// is no Java code on the stack. The base ClassLoader doesn't know about any of

@ -757,6 +757,10 @@ if (current_toolchain == default_toolchain) {
]
}
if (enable_cardboard) {
deps += [ "//third_party/cardboard:cardboard_java" ]
}
if (enable_vr) {
deps += [ ":chrome_vr_java_resources" ]
}

@ -22,6 +22,7 @@ default_chrome_public_jinja_variables = [
"channel=$android_channel",
"enable_vr=$enable_vr",
"include_arcore_manifest_flag=false",
"enable_cardboard=$enable_cardboard",
"zygote_preload_class=org.chromium.content_public.app.ZygotePreload",
]

@ -577,6 +577,16 @@ by a child template that "extends" this file.
{{ self.supports_vr() }}
</activity>
{% endif %}
{% set enable_cardboard = enable_cardboard|default(0) %}
{% if enable_cardboard == "true" %}
<!-- Based on //third_party/cardboard/src/sdk/qrcode/android/AndroidManifest.xml -->
<activity
android:name="com.google.cardboard.sdk.QrCodeCaptureActivity"
android:exported="false"
android:label="@string/title_activity_qr_code_capture"
android:theme="@style/Theme.AppCompat.NoActionBar">
</activity>
{% endif %}
<activity android:name="org.chromium.chrome.browser.signin.SyncConsentActivity"
android:theme="@style/Theme.Chromium.DialogWhenLarge"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|mcc|mnc|screenLayout|smallestScreenSize"

@ -7489,6 +7489,10 @@ static_library("browser") {
"//device/vr/android/arcore",
]
}
if (enable_cardboard) {
deps += [ "//device/vr/android/cardboard:vr_cardboard" ]
}
} else {
deps += [ "//device/vr/public/mojom:isolated_xr_service" ]
}

@ -276,6 +276,10 @@
#include "chrome/browser/ui/cocoa/screentime/screentime_features.h"
#endif // BUILDFLAG(IS_MAC)
#if BUILDFLAG(ENABLE_CARDBOARD)
#include "device/vr/public/cpp/features.h"
#endif // ENABLE_CARDBOARD
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "extensions/common/extension_features.h"
#include "extensions/common/switches.h"
@ -3327,6 +3331,11 @@ const FeatureEntry kFeatureEntries[] = {
flag_descriptions::kVerboseLoggingInNaclDescription, kOsAll,
MULTI_VALUE_TYPE(kVerboseLoggingInNaclChoices)},
#endif // ENABLE_NACL
#if BUILDFLAG(ENABLE_CARDBOARD)
{"enable-cardboard", flag_descriptions::kEnableCardboardName,
flag_descriptions::kEnableCardboardDescription, kOsAndroid,
FEATURE_VALUE_TYPE(device::features::kEnableCardboard)},
#endif // ENABLE_CARDBOARD
#if BUILDFLAG(ENABLE_EXTENSIONS)
{"extensions-on-chrome-urls",
flag_descriptions::kExtensionsOnChromeUrlsName,

@ -1841,6 +1841,11 @@
"owners": ["ydago"],
"expiry_milestone": 106
},
{
"name": "enable-cardboard",
"owners": [ "alcooper", "chrome-xr-eng@google.com"],
"expiry_milestone": 120
},
{
"name": "enable-cast-remoting-query-blocklist",
"owners": [ "rwkeane@google.com", "openscreen-eng@google.com" ],

@ -6371,6 +6371,14 @@ const char kDcheckIsFatalDescription[] =
"rather than crashing. If enabled, DCHECKs will crash the calling process.";
#endif // BUILDFLAG(DCHECK_IS_CONFIGURABLE)
#if BUILDFLAG(ENABLE_CARDBOARD)
extern const char kEnableCardboardName[] = "Enable Cardboard VR WebXR Runtime";
extern const char kEnableCardboardDescription[] =
"Enables the use of the Cardboard SDK runtime for WebXR instead of the"
"Google VR Services (or GVR) runtime to start a WebXR-based immersive-vr"
"session.";
#endif // ENABLE_CARDBOARD
#if BUILDFLAG(ENABLE_NACL)
const char kNaclName[] = "Native Client";
const char kNaclDescription[] =

@ -14,6 +14,7 @@
#include "chrome/common/buildflags.h"
#include "components/nacl/common/buildflags.h"
#include "components/paint_preview/buildflags/buildflags.h"
#include "device/vr/buildflags/buildflags.h"
#include "extensions/buildflags/buildflags.h"
#include "media/media_buildflags.h"
#include "pdf/buildflags.h"
@ -3685,6 +3686,11 @@ extern const char kDcheckIsFatalName[];
extern const char kDcheckIsFatalDescription[];
#endif // BUILDFLAG(DCHECK_IS_CONFIGURABLE)
#if BUILDFLAG(ENABLE_CARDBOARD)
extern const char kEnableCardboardName[];
extern const char kEnableCardboardDescription[];
#endif // ENABLE_CARDBOARD
#if BUILDFLAG(ENABLE_NACL)
extern const char kNaclName[];
extern const char kNaclDescription[];

@ -17,6 +17,7 @@
#include "content/public/browser/media_stream_request.h"
#include "content/public/browser/xr_install_helper.h"
#include "device/vr/buildflags/buildflags.h"
#include "device/vr/public/cpp/features.h"
#include "device/vr/public/cpp/vr_device_provider.h"
#include "device/vr/public/mojom/vr_service.mojom-shared.h"
#include "third_party/blink/public/common/mediastream/media_stream_request.h"
@ -33,6 +34,9 @@
#include "components/webxr/android/arcore_device_provider.h"
#include "components/webxr/android/arcore_install_helper.h"
#endif // BUILDFLAG(ENABLE_ARCORE)
#if BUILDFLAG(ENABLE_CARDBOARD)
#include "device/vr/android/cardboard/cardboard_device_provider.h"
#endif
#endif // BUILDFLAG(IS_WIN)
namespace {
@ -111,7 +115,18 @@ content::XRProviderList ChromeXrIntegrationClient::GetAdditionalProviders() {
content::XRProviderList providers;
#if BUILDFLAG(IS_ANDROID)
providers.push_back(std::make_unique<device::GvrDeviceProvider>());
bool add_gvr_device_provider = true;
#if BUILDFLAG(ENABLE_CARDBOARD)
// If the cardboard runtime is enabled we want to use it rather than the GVR
// runtime.
if (base::FeatureList::IsEnabled(device::features::kEnableCardboard)) {
providers.emplace_back(std::make_unique<device::CardboardDeviceProvider>());
add_gvr_device_provider = false;
}
#endif // ENABLE_CARDBOARD
if (add_gvr_device_provider) {
providers.push_back(std::make_unique<device::GvrDeviceProvider>());
}
#if BUILDFLAG(ENABLE_ARCORE)
base::android::ScopedJavaLocalRef<jobject> j_ar_compositor_delegate_provider =
vr::Java_ArCompositorDelegateProviderImpl_Constructor(

@ -1,5 +1,6 @@
include_rules = [
"+device/base",
"+device/vr/orientation",
"+device/vr/android/cardboard",
"+device/vr/test",
]

@ -192,6 +192,9 @@ bool BrowserXRRuntimeImpl::SupportsCustomIPD() const {
case device::mojom::XRDeviceId::FAKE_DEVICE_ID:
case device::mojom::XRDeviceId::ORIENTATION_DEVICE_ID:
case device::mojom::XRDeviceId::GVR_DEVICE_ID:
#if BUILDFLAG(ENABLE_CARDBOARD)
case device::mojom::XRDeviceId::CARDBOARD_DEVICE_ID:
#endif // ENABLE_CARDBOARD
return false;
#if BUILDFLAG(ENABLE_OPENXR)
case device::mojom::XRDeviceId::OPENXR_DEVICE_ID:
@ -210,6 +213,9 @@ bool BrowserXRRuntimeImpl::SupportsNonEmulatedHeight() const {
case device::mojom::XRDeviceId::ORIENTATION_DEVICE_ID:
return false;
case device::mojom::XRDeviceId::GVR_DEVICE_ID:
#if BUILDFLAG(ENABLE_CARDBOARD)
case device::mojom::XRDeviceId::CARDBOARD_DEVICE_ID:
#endif // ENABLE_CARDBOARD
#if BUILDFLAG(ENABLE_OPENXR)
case device::mojom::XRDeviceId::OPENXR_DEVICE_ID:
#endif

@ -0,0 +1,35 @@
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/rules.gni")
import("//device/vr/buildflags/buildflags.gni")
assert(enable_cardboard)
component("vr_cardboard") {
defines = [ "IS_VR_CARDBOARD_IMPL" ]
sources = [
"cardboard_device.cc",
"cardboard_device.h",
"cardboard_device_provider.cc",
"cardboard_device_provider.h",
"cardboard_sdk.h",
"cardboard_sdk_impl.cc",
"cardboard_sdk_impl.h",
]
public_deps = [
"//device/vr:vr_base",
"//device/vr/public/cpp",
]
deps = [
"//base",
"//device/vr/android:vr_android",
"//gpu/command_buffer/service:gles2",
"//third_party/cardboard",
"//ui/android",
"//ui/gfx",
]
}

@ -0,0 +1,3 @@
include_rules = [
"+third_party/cardboard/src/sdk/include"
]

@ -0,0 +1,50 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/vr/android/cardboard/cardboard_device.h"
#include <utility>
#include <vector>
#include "base/no_destructor.h"
#include "base/notreached.h"
namespace device {
namespace {
const std::vector<mojom::XRSessionFeature>& GetSupportedFeatures() {
static base::NoDestructor<std::vector<mojom::XRSessionFeature>>
kSupportedFeatures{{
mojom::XRSessionFeature::REF_SPACE_VIEWER,
mojom::XRSessionFeature::REF_SPACE_LOCAL,
mojom::XRSessionFeature::REF_SPACE_LOCAL_FLOOR,
}};
return *kSupportedFeatures;
}
} // namespace
CardboardDevice::CardboardDevice(std::unique_ptr<CardboardSdk> cardboard_sdk)
: VRDeviceBase(mojom::XRDeviceId::CARDBOARD_DEVICE_ID),
cardboard_sdk_(std::move(cardboard_sdk)) {
SetSupportedFeatures(GetSupportedFeatures());
}
CardboardDevice::~CardboardDevice() = default;
void CardboardDevice::RequestSession(
mojom::XRRuntimeSessionOptionsPtr options,
mojom::XRRuntime::RequestSessionCallback callback) {
// TODO(https://crbug.com/989117): Implement
std::move(callback).Run(nullptr);
}
void CardboardDevice::ShutdownSession(
mojom::XRRuntime::ShutdownSessionCallback on_completed) {
NOTREACHED();
}
} // namespace device

@ -0,0 +1,40 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_DEVICE_H_
#define DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_DEVICE_H_
#include <memory>
#include "base/component_export.h"
#include "base/memory/weak_ptr.h"
#include "device/vr/android/cardboard/cardboard_sdk.h"
#include "device/vr/vr_device_base.h"
namespace device {
class COMPONENT_EXPORT(VR_CARDBOARD) CardboardDevice : public VRDeviceBase {
public:
explicit CardboardDevice(std::unique_ptr<CardboardSdk> cardboard_sdk);
CardboardDevice(const CardboardDevice&) = delete;
CardboardDevice& operator=(const CardboardDevice&) = delete;
~CardboardDevice() override;
// VRDeviceBase
void RequestSession(
mojom::XRRuntimeSessionOptionsPtr options,
mojom::XRRuntime::RequestSessionCallback callback) override;
void ShutdownSession(mojom::XRRuntime::ShutdownSessionCallback) override;
private:
std::unique_ptr<CardboardSdk> cardboard_sdk_;
base::WeakPtrFactory<CardboardDevice> weak_ptr_factory_{this};
};
} // namespace device
#endif // DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_DEVICE_H_

@ -0,0 +1,33 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/vr/android/cardboard/cardboard_device_provider.h"
#include "device/vr/android/cardboard/cardboard_device.h"
#include "device/vr/android/cardboard/cardboard_sdk_impl.h"
namespace device {
CardboardDeviceProvider::CardboardDeviceProvider() = default;
CardboardDeviceProvider::~CardboardDeviceProvider() = default;
void CardboardDeviceProvider::Initialize(VRDeviceProviderClient* client) {
DVLOG(2) << __func__ << ": Cardboard is supported, creating device";
cardboard_device_ =
std::make_unique<CardboardDevice>(std::make_unique<CardboardSdkImpl>());
client->AddRuntime(cardboard_device_->GetId(),
cardboard_device_->GetDeviceData(),
cardboard_device_->BindXRRuntime());
initialized_ = true;
client->OnProviderInitialized();
}
bool CardboardDeviceProvider::Initialized() {
return initialized_;
}
} // namespace device

@ -0,0 +1,35 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_DEVICE_PROVIDER_H_
#define DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_DEVICE_PROVIDER_H_
#include <memory>
#include "base/component_export.h"
#include "device/vr/public/cpp/vr_device_provider.h"
namespace device {
class CardboardDevice;
class COMPONENT_EXPORT(VR_CARDBOARD) CardboardDeviceProvider
: public device::VRDeviceProvider {
public:
explicit CardboardDeviceProvider();
~CardboardDeviceProvider() override;
CardboardDeviceProvider(const CardboardDeviceProvider&) = delete;
CardboardDeviceProvider& operator=(const CardboardDeviceProvider&) = delete;
void Initialize(device::VRDeviceProviderClient* client) override;
bool Initialized() override;
private:
std::unique_ptr<device::CardboardDevice> cardboard_device_;
bool initialized_ = false;
};
} // namespace device
#endif // DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_DEVICE_PROVIDER_H_

@ -0,0 +1,28 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_SDK_H_
#define DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_SDK_H_
#include "base/component_export.h"
namespace device {
// The actual cardboard SDK provides a C-Style interface. This wrapper provides
// a bit more modern interface both to help abstract some of the create/destroy
// patterns that return/take raw pointers so that we can wrap them in a class
// that will automatically clean them up, as well as provides a mechanism to
// shim out the Cardboard SDK for testing purposes.
class COMPONENT_EXPORT(VR_CARDBOARD) CardboardSdk {
public:
CardboardSdk() = default;
virtual ~CardboardSdk() = default;
CardboardSdk(const CardboardSdk&) = delete;
CardboardSdk& operator=(const CardboardSdk&) = delete;
};
} // namespace device
#endif // DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_SDK_H_

@ -0,0 +1,22 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/vr/android/cardboard/cardboard_sdk_impl.h"
#include "base/android/jni_android.h"
#include "third_party/cardboard/src/sdk/include/cardboard.h"
namespace device {
CardboardSdkImpl::CardboardSdkImpl() {
// Per the documentation this will be a no-op because of the nullptr.
// TODO(https://crbug.com/989117): Move this to the RequestSession flow. It's
// included for the time being just to ensure that the library is at least
// used.
Cardboard_initializeAndroid(base::android::GetVM(), nullptr);
}
CardboardSdkImpl::~CardboardSdkImpl() = default;
} // namespace device

@ -0,0 +1,23 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_SDK_IMPL_H_
#define DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_SDK_IMPL_H_
#include "device/vr/android/cardboard/cardboard_sdk.h"
namespace device {
class CardboardSdkImpl : public CardboardSdk {
public:
CardboardSdkImpl();
~CardboardSdkImpl() override;
CardboardSdkImpl(const CardboardSdkImpl&) = delete;
CardboardSdkImpl& operator=(const CardboardSdkImpl&) = delete;
};
} // namespace device
#endif // DEVICE_VR_ANDROID_CARDBOARD_CARDBOARD_SDK_IMPL_H_

@ -12,5 +12,6 @@ buildflag_header("buildflags") {
"ENABLE_ARCORE=$enable_arcore",
"ENABLE_VR=$enable_vr",
"ENABLE_OPENXR=$enable_openxr",
"ENABLE_CARDBOARD=$enable_cardboard",
]
}

@ -11,6 +11,8 @@ declare_args() {
enable_gvr_services = is_android && !is_cast_android &&
(current_cpu == "arm" || current_cpu == "arm64")
enable_cardboard = false
use_command_buffer = is_win
# To build with OpenXR support, the OpenXR Loader needs to be pulled to

@ -33,6 +33,14 @@ BASE_FEATURE(kWebXrOrientationSensorDevice,
#endif
);
#if BUILDFLAG(ENABLE_CARDBOARD)
// Controls WebXR support for the Cardboard SDK Runtime. Note that enabling
// this will also disable the GVR runtime.
BASE_FEATURE(kEnableCardboard,
"EnableCardboard",
base::FEATURE_DISABLED_BY_DEFAULT);
#endif // ENABLE_CARDBOARD
#if BUILDFLAG(ENABLE_OPENXR)
// Controls WebXR support for the OpenXR Runtime.
BASE_FEATURE(kOpenXR, "OpenXR", base::FEATURE_ENABLED_BY_DEFAULT);

@ -16,6 +16,10 @@ COMPONENT_EXPORT(VR_FEATURES) BASE_DECLARE_FEATURE(kWebXrLayers);
COMPONENT_EXPORT(VR_FEATURES)
BASE_DECLARE_FEATURE(kWebXrOrientationSensorDevice);
#if BUILDFLAG(ENABLE_CARDBOARD)
COMPONENT_EXPORT(VR_FEATURES) BASE_DECLARE_FEATURE(kEnableCardboard);
#endif // ENABLE_CARDBOARD
#if BUILDFLAG(ENABLE_OPENXR)
COMPONENT_EXPORT(VR_FEATURES) BASE_DECLARE_FEATURE(kOpenXR);
COMPONENT_EXPORT(VR_FEATURES)

@ -27,6 +27,10 @@ mojom_component("vr_service") {
enabled_features += [ "enable_openxr" ]
}
if (enable_cardboard) {
enabled_features += [ "enable_cardboard" ]
}
shared_cpp_typemap = {
types = [
{

@ -35,6 +35,7 @@ enum XRDeviceId {
// WINDOWS_MIXED_REALITY_ID = 6,
ARCORE_DEVICE_ID = 7,
[EnableIf=enable_openxr] OPENXR_DEVICE_ID = 8,
[EnableIf=enable_cardboard] CARDBOARD_DEVICE_ID = 9,
};
enum XRHandedness {

143
third_party/cardboard/BUILD.gn vendored Normal file

@ -0,0 +1,143 @@
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//third_party/protobuf/proto_library.gni")
assert(is_android)
assert(!is_cast_android)
proto_java_library("cardboard_proto_java") {
sources = [ "src/proto/cardboard_device.proto" ]
proto_path = "//"
}
android_resources("cardboard_resources") {
sources = [
"src/sdk/qrcode/android/res/drawable-xxhdpi/qr_sample.png",
"src/sdk/qrcode/android/res/drawable-xxhdpi/tick_marks.png",
"src/sdk/qrcode/android/res/layout/qr_code_capture.xml",
"src/sdk/qrcode/android/res/values/colors.xml",
"src/sdk/qrcode/android/res/values/strings.xml",
"src/sdk/qrcode/android/res/values/styles.xml",
]
custom_package = "com.google.cardboard.sdk"
}
android_library("cardboard_java") {
sources = [
"src/sdk/device_params/android/java/com/google/cardboard/sdk/deviceparams/CardboardV1DeviceParams.java",
"src/sdk/device_params/android/java/com/google/cardboard/sdk/deviceparams/DeviceParamsUtils.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/HeadsetDetectionActivity.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/QrCodeCaptureActivity.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/AsyncTask.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/CardboardParamsUtils.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/InputStreamProvider.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/OutputStreamProvider.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/QrCodeContentProcessor.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/QrCodeTracker.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/QrCodeTrackerFactory.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/UrlFactory.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/camera/CameraSource.java",
"src/sdk/qrcode/android/java/com/google/cardboard/sdk/qrcode/camera/CameraSourcePreview.java",
"src/sdk/screen_params/android/java/com/google/cardboard/sdk/screenparams/ScreenParamsUtils.java",
]
resources_package = "com.google.cardboard.sdk"
deps = [
":cardboard_proto_java",
":cardboard_resources",
"$google_play_services_package:google_play_services_base_java",
"$google_play_services_package:google_play_services_basement_java",
"$google_play_services_package:google_play_services_vision_common_java",
"$google_play_services_package:google_play_services_vision_java",
"//third_party/android_deps:protobuf_lite_runtime_java",
"//third_party/androidx:androidx_annotation_annotation_jvm_java",
"//third_party/androidx:androidx_appcompat_appcompat_java",
"//third_party/androidx:androidx_core_core_java",
]
# TODO(alcooper): Switch this to "src/sdk/proguard-rules.pro" once b/264530605
# is fixed/rolled-in.
proguard_configs = [ "proguard-rules.pro" ]
}
static_library("cardboard") {
sources = [
"src/sdk/cardboard.cc",
"src/sdk/device_params/android/device_params.cc",
"src/sdk/device_params/android/device_params.h",
"src/sdk/distortion_mesh.cc",
"src/sdk/distortion_mesh.h",
"src/sdk/distortion_renderer.h",
"src/sdk/head_tracker.cc",
"src/sdk/head_tracker.h",
"src/sdk/include/cardboard.h",
"src/sdk/jni_utils/android/jni_utils.cc",
"src/sdk/jni_utils/android/jni_utils.h",
"src/sdk/lens_distortion.cc",
"src/sdk/lens_distortion.h",
"src/sdk/polynomial_radial_distortion.cc",
"src/sdk/polynomial_radial_distortion.h",
"src/sdk/qr_code.h",
"src/sdk/qrcode/android/qr_code.cc",
"src/sdk/qrcode/cardboard_v1/cardboard_v1.cc",
"src/sdk/qrcode/cardboard_v1/cardboard_v1.h",
"src/sdk/qrcode/ios/device_params_helper.h",
"src/sdk/qrcode/ios/nsurl_session_data_handler.h",
"src/sdk/qrcode/ios/qr_scan_view_controller.h",
"src/sdk/rendering/android/shaders/distortion_frag.spv.h",
"src/sdk/rendering/android/shaders/distortion_vert.spv.h",
"src/sdk/rendering/opengl_es2_distortion_renderer.cc",
"src/sdk/screen_params.h",
"src/sdk/screen_params/android/screen_params.cc",
"src/sdk/sensors/accelerometer_data.h",
"src/sdk/sensors/android/device_accelerometer_sensor.cc",
"src/sdk/sensors/android/sensor_event_producer.cc",
"src/sdk/sensors/device_accelerometer_sensor.h",
"src/sdk/sensors/device_gyroscope_sensor.h",
"src/sdk/sensors/gyroscope_bias_estimator.cc",
"src/sdk/sensors/gyroscope_bias_estimator.h",
"src/sdk/sensors/gyroscope_data.h",
"src/sdk/sensors/ios/sensor_helper.h",
"src/sdk/sensors/lowpass_filter.cc",
"src/sdk/sensors/lowpass_filter.h",
"src/sdk/sensors/mean_filter.cc",
"src/sdk/sensors/mean_filter.h",
"src/sdk/sensors/median_filter.cc",
"src/sdk/sensors/median_filter.h",
"src/sdk/sensors/neck_model.cc",
"src/sdk/sensors/neck_model.h",
"src/sdk/sensors/rotation_state.h",
"src/sdk/sensors/sensor_event_producer.h",
"src/sdk/sensors/sensor_fusion_ekf.cc",
"src/sdk/sensors/sensor_fusion_ekf.h",
"src/sdk/util/is_arg_null.h",
"src/sdk/util/is_initialized.cc",
"src/sdk/util/is_initialized.h",
"src/sdk/util/logging.h",
"src/sdk/util/matrix_3x3.cc",
"src/sdk/util/matrix_3x3.h",
"src/sdk/util/matrix_4x4.cc",
"src/sdk/util/matrix_4x4.h",
"src/sdk/util/matrixutils.cc",
"src/sdk/util/matrixutils.h",
"src/sdk/util/rotation.cc",
"src/sdk/util/rotation.h",
"src/sdk/util/vector.h",
"src/sdk/util/vectorutils.cc",
"src/sdk/util/vectorutils.h",
"src_overrides/sdk/sensors/android/device_gyroscope_sensor.cc",
]
include_dirs = [ "src/sdk" ]
libs = [
"android",
"log",
"GLESv2",
]
}

@ -11,4 +11,6 @@ The Cardboard SDK supports a simple API used for displaying VR scenes on
smartphones inserted into Cardboard viewers.
Local Modifications:
None at this time.
Created local top-level BUILD.gn based on src/sdk/build.gradle
Created local proguard-rules.pro to remove wildcard rules
Created local override for device_gyroscope_sensor to remove static initializers

@ -0,0 +1,22 @@
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# TODO(alcooper): This is a fork of src/sdk/proguard-rules.pro. Once b/264530605
# has been fixed/published roll to pick that up and switch to using that
# instead.
-keep class com.google.cardboard.sdk.DistortionRenderer { *; }
-keep class com.google.cardboard.sdk.HeadTracker { *; }
-keep class com.google.cardboard.sdk.Initialize { *; }
-keep class com.google.cardboard.sdk.LensDistortion { *; }
-keep class com.google.cardboard.sdk.QrCode { *; }
-keep class com.google.cardboard.sdk.qrcode.CardboardParamsUtils { *; }
-keep class com.google.cardboard.sdk.qrcode.CardboardParamsUtils.StorageSource { *; }
-keep class com.google.cardboard.sdk.qrcode.CardboardParamsUtils.UriToParamsStatus { *; }
-keep class com.google.cardboard.sdk.QrCodeCaptureActivity { *; }
-keep class com.google.cardboard.sdk.nativetypes.EyeTextureDescription { *; }
-keep class com.google.cardboard.sdk.nativetypes.EyeType { *; }
-keep class com.google.cardboard.sdk.nativetypes.Mesh { *; }
-keep class com.google.cardboard.sdk.nativetypes.UvPoint { *; }
-keep class com.google.cardboard.sdk.deviceparams.DeviceParamsUtils { *; }
-keep class com.google.cardboard.sdk.screenparams.ScreenParamsUtils { *; }
-keep class com.google.cardboard.sdk.screenparams.ScreenParamsUtils.ScreenPixelDensity { *; }

@ -0,0 +1,233 @@
/*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "third_party/cardboard/src/sdk/sensors/device_gyroscope_sensor.h"
#include <android/looper.h>
#include <android/sensor.h>
#include <stddef.h>
#include <memory>
#include <mutex> // NOLINT
#include "third_party/cardboard/src/sdk/sensors/accelerometer_data.h"
#include "third_party/cardboard/src/sdk/sensors/gyroscope_data.h"
#include "third_party/cardboard/src/sdk/util/logging.h"
// Workaround to avoid the inclusion of "android_native_app_glue.h.
#ifndef LOOPER_ID_USER
#define LOOPER_ID_USER 3
#endif
namespace cardboard {
namespace {
// Creates an Android sensor event queue for the current thread.
static ASensorEventQueue* CreateSensorQueue(ASensorManager* sensor_manager) {
ALooper* event_looper = ALooper_forThread();
if (event_looper == nullptr) {
event_looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
CARDBOARD_LOGI(
"AccelerometerSensor: Created new event looper for gyroscope sensor "
"capture thread.");
}
return ASensorManager_createEventQueue(sensor_manager, event_looper,
LOOPER_ID_USER, nullptr, nullptr);
}
// Initialize Gyroscope sensor on Android. If available we try to
// request a SENSOR_TYPE_GYROSCOPE_UNCALIBRATED.
// Since both seem to be using the same underlying code this will work if the
// same integer is used as the mode as in java.
// The reason for using the uncalibrated gyroscope is that the regular
// gyro is calibrated with a bias offset in the system. As we cannot influence
// the behavior of this algorithm and it will affect the gyro while moving,
// it is safer to initialize to the uncalibrated one and handle the gyro bias
// estimation in Cardboard SDK.
enum PrivateSensors {
// This is not defined in the native public sensors API, but it is in java.
// If we define this here and it gets defined later in NDK this should
// not compile.
// It is defined in AOSP in hardware/libhardware/include/hardware/sensors.h
ASENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14,
ASENSOR_TYPE_GYROSCOPE_UNCALIBRATED = 16,
ASENSOR_TYPE_ADDITIONAL_INFO = 33,
};
static const ASensor* GetUncalibratedGyroscope(ASensorManager* sensor_manager) {
return ASensorManager_getDefaultSensor(sensor_manager,
ASENSOR_TYPE_GYROSCOPE_UNCALIBRATED);
}
const ASensor* InitSensor(ASensorManager* sensor_manager) {
const ASensor* gyro = GetUncalibratedGyroscope(sensor_manager);
if (gyro != nullptr) {
CARDBOARD_LOGI("Android Gyro Sensor: ASENSOR_TYPE_GYRO_UNCALIBRATED");
return gyro;
}
CARDBOARD_LOGI("Android Gyro Sensor: ASENSOR_TYPE_GYROSCOPE");
return ASensorManager_getDefaultSensor(sensor_manager,
ASENSOR_TYPE_GYROSCOPE);
}
bool PollLooper(int timeout_ms, int* num_events) {
void* source = nullptr;
const int looper_id = ALooper_pollAll(timeout_ms, NULL, num_events,
reinterpret_cast<void**>(&source));
if (looper_id != LOOPER_ID_USER) {
return false;
}
if (*num_events <= 0) {
return false;
}
return true;
}
class SensorEventQueueReader {
public:
SensorEventQueueReader(ASensorManager* manager, const ASensor* sensor)
: manager_(manager),
sensor_(sensor),
queue_(CreateSensorQueue(manager_)) {}
~SensorEventQueueReader() {
ASensorManager_destroyEventQueue(manager_, queue_);
}
bool Start() {
ASensorEventQueue_enableSensor(queue_, sensor_);
const int min_delay = ASensor_getMinDelay(sensor_);
// Set sensor capture rate to the highest possible sampling rate.
ASensorEventQueue_setEventRate(queue_, sensor_, min_delay);
return true;
}
void Stop() { ASensorEventQueue_disableSensor(queue_, sensor_); }
bool WaitForEvent(int timeout_ms, ASensorEvent* event) {
int num_events;
if (!PollLooper(timeout_ms, &num_events)) {
return false;
}
return (ASensorEventQueue_getEvents(queue_, event, 1) > 0);
}
bool ReadEvent(ASensorEvent* event) {
return (ASensorEventQueue_getEvents(queue_, event, 1) > 0);
}
private:
ASensorManager* manager_; // Owned by android library.
const ASensor* sensor_; // Owned by android library.
ASensorEventQueue* queue_; // Owned by this.
};
} // namespace
// This struct holds android gyroscope specific sensor information.
struct DeviceGyroscopeSensor::SensorInfo {
SensorInfo() : sensor_manager(nullptr), sensor(nullptr) {}
ASensorManager* sensor_manager;
const ASensor* sensor;
std::unique_ptr<SensorEventQueueReader> reader;
};
namespace {
bool ParseGyroEvent(const ASensorEvent& event,
DeviceGyroscopeSensor::SensorInfo* sensor_info,
GyroscopeData* sample) {
if (event.type == ASENSOR_TYPE_ADDITIONAL_INFO) {
CARDBOARD_LOGI("ParseGyroEvent discarding additional info sensor event");
return false;
}
sample->sensor_timestamp_ns = event.timestamp;
sample->system_timestamp = event.timestamp; // Clock::time_point();
// The event values in ASensorEvent (event, acceleration and
// magnetic) are all in the same union type so they can be
// accessed by event.
if (event.type == ASENSOR_TYPE_GYROSCOPE) {
sample->data = {event.vector.x, event.vector.y, event.vector.z};
return true;
} else if (event.type == ASENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
sample->data = {event.vector.x, event.vector.y, event.vector.z};
return true;
} else {
CARDBOARD_LOGE("ParseGyroEvent discarding unexpected sensor event type %d",
event.type);
}
return false;
}
} // namespace
// This function returns gyroscope initial system bias
Vector3 DeviceGyroscopeSensor::GetInitialSystemBias() {
static Vector3 kInitialSystemBias{0, 0, 0};
return kInitialSystemBias;
}
DeviceGyroscopeSensor::DeviceGyroscopeSensor()
: sensor_info_(new SensorInfo()) {
sensor_info_->sensor_manager = ASensorManager_getInstance();
sensor_info_->sensor = InitSensor(sensor_info_->sensor_manager);
if (!sensor_info_->sensor) {
return;
}
sensor_info_->reader =
std::unique_ptr<SensorEventQueueReader>(new SensorEventQueueReader(
sensor_info_->sensor_manager, sensor_info_->sensor));
}
DeviceGyroscopeSensor::~DeviceGyroscopeSensor() {}
void DeviceGyroscopeSensor::PollForSensorData(
int timeout_ms,
std::vector<GyroscopeData>* results) const {
results->clear();
ASensorEvent event;
if (!sensor_info_->reader->WaitForEvent(timeout_ms, &event)) {
return;
}
do {
GyroscopeData sample;
if (ParseGyroEvent(event, sensor_info_.get(), &sample)) {
results->push_back(sample);
}
} while (sensor_info_->reader->ReadEvent(&event));
}
bool DeviceGyroscopeSensor::Start() {
if (!sensor_info_->reader) {
CARDBOARD_LOGE("Could not start gyroscope sensor.");
return false;
}
return sensor_info_->reader->Start();
}
void DeviceGyroscopeSensor::Stop() {
if (!sensor_info_->reader) {
return;
}
sensor_info_->reader->Stop();
}
} // namespace cardboard

@ -64352,6 +64352,7 @@ from previous Chrome versions.
<int value="1852630189" label="NTPBookmarkSuggestions:disabled"/>
<int value="1854017276" label="NavigationPredictorRendererWarmup:disabled"/>
<int value="1854048611" label="OmniboxSuggestionsRecyclerView:disabled"/>
<int value="1854141935" label="EnableCardboard:enabled"/>
<int value="1854226565" label="AutofillNoLocalSaveOnUnmaskSuccess:enabled"/>
<int value="1854646491" label="DetailedLanguageSettings:disabled"/>
<int value="1855524566" label="allow-insecure-websocket-from-https-origin"/>
@ -64823,6 +64824,7 @@ from previous Chrome versions.
<int value="2121870664"
label="lacros-data-backward-migration-policy:enabled"/>
<int value="2122023503" label="enable-win32k-lockdown-mimetypes"/>
<int value="2122256719" label="EnableCardboard:disabled"/>
<int value="2122863344" label="WebViewSurfaceControl:disabled"/>
<int value="2122876605" label="enable-bleeding-edge-rendering-fast-paths"/>
<int value="2123183411" label="BlinkHeapIncrementalMarking:enabled"/>