Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
85ad077
Port PhoneVR client to ALVR v21 API (shared EGL context, decoder conf…
righthandpaw Oct 4, 2026
057113c
Add wgpu-hal patch: share the app's EGL context with ALVR's GL context
righthandpaw Oct 4, 2026
478c077
Update MIGRATION_NOTES
righthandpaw Oct 4, 2026
ee433f6
Make gradlew executable
righthandpaw Oct 4, 2026
2622995
Point ALVR submodule at 9f118394 (21.0.0-dev14)
righthandpaw Oct 4, 2026
a0e93d7
Fix minor typos
righthandpaw Oct 4, 2026
54bcaae
ARCore build plumbing: link ARCore, pass enableARCore through JNI (un…
righthandpaw Oct 5, 2026
f083ec3
ARCore build plumbing: link ARCore, pass enableARCore through JNI (un…
righthandpaw Oct 5, 2026
e592b18
ARCore session, camera texture and per-frame diagnostics (step 2a)
righthandpaw Oct 6, 2026
a616165
ARCore position and orientation correction (step 2b)
righthandpaw Oct 6, 2026
ae2ce64
Reuse the last decoded frame when no new frame arrives (fixes stutter)
righthandpaw Oct 6, 2026
b9276af
Fix floor height
righthandpaw Oct 6, 2026
0cc5ee9
Step 4 and 5: floor height, orientation gate
righthandpaw Oct 7, 2026
96ce113
ARCore: floor height, check samples against the residual, world-yaw c…
righthandpaw Oct 8, 2026
e01a84a
Start ARCore after video starts flowing (fixes frozen stream on some …
righthandpaw Oct 10, 2026
20a85ad
wgpu-hal patch: share EGL context; disable GL debug output (fixes Pow…
righthandpaw Oct 10, 2026
8db689e
Update migration notes: ARCore timing, PowerVR debug-output crash, te…
righthandpaw Oct 10, 2026
08e471a
README: document ALVR v21 port, ARCore tracking, tested phones, build…
righthandpaw Oct 10, 2026
075cadc
Cleanup: remove DIAG logging and old decoder block; trim wgpu-hal pat…
righthandpaw Oct 13, 2026
551f605
Reduce display prediction interval to 30 ms to stop reprojection over…
righthandpaw Oct 14, 2026
05054b7
Add client-side upscaling option and stream FOV scale
righthandpaw Oct 18, 2026
3f3fab7
Add settings screen (ARCore switch, FOV zoom, floor mode); client ups…
righthandpaw Oct 20, 2026
f28ab07
Pin ARCore SDK download to release v1.46.0
righthandpaw Oct 20, 2026
c38c132
Name APK PhoneVR-v<version>-ARcore-v21; own signing key; relative wgp…
righthandpaw Oct 21, 2026
f8f5b88
Close InitActivity after launching ALVRActivity so wired mode connects
righthandpaw Oct 22, 2026
4f56591
Update README
righthandpaw Oct 23, 2026
721df3b
Add own head orientation filter (Mahony + stillness-based gyro bias)
claude Oct 24, 2026
db80491
Update version build and menu clean-up
righthandpaw Oct 26, 2026
2be07d9
Add neck model for seated 3DoF (no ARCore)
claude Oct 27, 2026
c799a8d
Merge pull request #2 from righthandpaw/neck-model
righthandpaw Oct 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 68 additions & 139 deletions README.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions code/mobile/android/PhoneVR/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,9 @@ google-services.json

# Android Profiling
*.hprof
arcore-android-sdk-main/
/wgpu-hal-25.0.2/
*.bak
*.orig
*.rej
signing.properties
2 changes: 1 addition & 1 deletion code/mobile/android/PhoneVR/ALVR
Submodule ALVR updated 972 files
27 changes: 9 additions & 18 deletions code/mobile/android/PhoneVR/app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,44 +1,35 @@
cmake_minimum_required(VERSION 3.4.3)

#use rtti, exceptions for asio library ## -std=c++17
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -frtti -fexceptions -Wc++11-narrowing -Wreorder")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -g")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O3 -std=c++17 -g")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -std=c++17 -g")

set(ANDROID_STL c++_static)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)

file(GLOB_RECURSE LIB_SRC
../../../../common/libs/ifaddrs/*.c
../../../../common/libs/json/single_include/*.hpp
)

add_library(native-lib-alvr SHARED
src/main/cpp/alvr_main.cpp
${LIB_SRC}
)

# Import the ARCore (Google Play Services for AR) library.
add_library(arcore SHARED IMPORTED)
set_target_properties(arcore PROPERTIES IMPORTED_LOCATION
${ARCORE_LIBPATH}/${ANDROID_ABI}/libarcore_sdk_c.so
INTERFACE_INCLUDE_DIRECTORIES ${ARCORE_INCLUDE}
)

set(libs_dir ${CMAKE_CURRENT_SOURCE_DIR}/libraries)
set(alvr_build_dir ${CMAKE_CURRENT_SOURCE_DIR}/../ALVR/build/alvr_client_core)

target_include_directories(native-lib-alvr
PUBLIC ../../../../common/libs/asio/asio/include
PUBLIC ../../../../common/libs/eigen/Eigen
PUBLIC ../../../../common/libs/ifaddrs
PUBLIC ../../../../common/libs/json/single_include/

# ALVR Headers
PUBLIC ${alvr_build_dir}
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../cardboard
PUBLIC ${ARCORE_INCLUDE}
)

target_link_libraries(native-lib-alvr
log android EGL GLESv3 mediandk
log android EGL GLESv3 mediandk arcore
${alvr_build_dir}/${ANDROID_ABI}/libalvr_client_core.so
${libs_dir}/jni/${ANDROID_ABI}/libGfxPluginCardboard.so
)

IF(${HAVEGVR})
add_subdirectory(src/gvr)
ENDIF()
50 changes: 47 additions & 3 deletions code/mobile/android/PhoneVR/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,43 @@ apply plugin: 'com.google.gms.google-services'
apply from: '../versioning.gradle'
apply plugin: "com.diffplug.spotless"

def arcore_libpath = "${rootProject.layout.buildDirectory.get()}/arcore-native"

configurations { natives }
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

def defaultALVRFlavour = "--release"

// Part of the APK file name: PhoneVR-v<VERSION_NAME>-<releaseLabel>-<buildType>.apk
// e.g. PhoneVR-v2.0.0-beta-ARcore-v21-release.apk (VERSION_NAME is set in ../version.properties)
def releaseLabel = "ARcore-v21"

android {
signingConfigs {
releaseconfig {
if( System.getenv('GITHUB_EVENT_NAME') == 'pull_request' || System.getenv("Store") == null || System.getenv("Key") == null ) {
// Your own release key. signing.properties is NOT committed (it is in .gitignore) and
// holds: storeFile, storePassword, keyAlias, keyPassword.
def localSigningFile = rootProject.file("signing.properties")
if (localSigningFile.exists()) {
def localSigning = new Properties()
localSigningFile.withInputStream { localSigning.load(it) }
storeFile file(localSigning['storeFile'])
storePassword localSigning['storePassword']
keyAlias localSigning['keyAlias']
keyPassword localSigning['keyPassword']
println "[PVR] Configuring releaseconfig with your own key from signing.properties"
}
else if( System.getenv('GITHUB_EVENT_NAME') == 'pull_request' || System.getenv("Store") == null || System.getenv("Key") == null ) {
// If its a PR Supply a dummy KeySigningConfig
// Or in Local env if Store and Keys are not present in ENV Vars do the same
storeFile file("PhoneVRKeyStorePR.jks")
storePassword "test1234"
keyAlias "PhoneVRKeyPR"
keyPassword "test1234"
println "[PVR] Configuring releaseconfigs for testing a PR..."
println "[PVR] WARNING: this APK is signed with the public TEST key (no signing.properties). Do not share it."
}
else {
storeFile file(keystoreProperties['storeFile'])
Expand All @@ -41,6 +61,11 @@ android {
applicationId "viritualisres.phonevr"
minSdkVersion 24
targetSdkVersion 33

ndk {
abiFilters "arm64-v8a"
}

versionCode buildVersionCode()
versionName buildVersionName()

Expand All @@ -50,6 +75,8 @@ android {
externalNativeBuild {
cmake {
cppFlags "-std=c++17 -fexceptions -frtti" //-DANDROID_USE_LEGACY_TOOLCHAIN_FILE=ON"
arguments "-DARCORE_LIBPATH=${arcore_libpath}/jni",
"-DARCORE_INCLUDE=${project.rootDir}/arcore-android-sdk-main/libraries/include"
}
}

Expand Down Expand Up @@ -77,6 +104,12 @@ android {
defaultALVRFlavour = ""
}
}
// APK file name, e.g. PhoneVR-v2.0.0-beta-ARcore-v21-release.apk
applicationVariants.all { variant ->
variant.outputs.all {
outputFileName = "PhoneVR-v${defaultConfig.versionName}-${releaseLabel}-${variant.buildType.name}.apk"
}
}
buildFeatures {
buildConfig = true // TODO: Remove BuildConfig, Gradle suggests this usage is inefficient > v8 disabled by default
viewBinding true
Expand All @@ -93,7 +126,8 @@ android {
}
noGvr {
dimension "gvr"
versionNameSuffix "-nogvr"
//versionNameSuffix "-nogvr"
versionNameSuffix ""
}
}
sourceSets {
Expand Down Expand Up @@ -167,13 +201,16 @@ dependencies {

gvrImplementation 'com.google.vr:sdk-base:1.200.0@aar'
implementation 'com.google.cardboard.sdk:cardboard-sdk:1.17.0@aar'
implementation 'io.github.zxing-cpp:android:2.3.0-SNAPSHOT'
implementation 'io.github.zxing-cpp:android:2.3.0'
implementation 'com.google.protobuf:protobuf-javalite:3.19.4'
implementation 'androidx.camera:camera-core:1.3.4'
implementation 'androidx.camera:camera-view:1.3.4'
implementation 'androidx.camera:camera-lifecycle:1.3.4'
implementation 'androidx.camera:camera-camera2:1.3.4'

implementation 'com.google.ar:core:1.46.0'
natives 'com.google.ar:core:1.46.0'

def acraVersion = '5.7.0'
implementation "ch.acra:acra-mail:$acraVersion"
implementation "ch.acra:acra-dialog:$acraVersion"
Expand All @@ -199,6 +236,13 @@ task extractNdk(type: Copy) {
include "jni/**/libgvr.so"
}
}
configurations.natives.files.each { f ->
copy {
from zipTree(f)
into arcore_libpath
include "jni/**/*"
}
}
}

task deleteNdk(type: Delete) {
Expand Down
9 changes: 9 additions & 0 deletions code/mobile/android/PhoneVR/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

<uses-feature
android:glEsVersion="0x00030001"
Expand Down Expand Up @@ -46,6 +47,11 @@
tools:replace="android:extractNativeLibs"
android:extractNativeLibs="true">

<!-- ARCore is optional: the app also works (rotation only) on phones without it. -->
<meta-data
android:name="com.google.ar.core"
android:value="optional" />

<activity
android:name=".InitActivity"
android:label="@string/app_name"
Expand All @@ -70,6 +76,9 @@
android:finishOnTaskLaunch="true"
android:launchMode="singleInstance"
android:process=":acra" />
<activity
android:name=".SettingsActivity"
android:label="@string/settings_title" />
<activity
android:name=".ALVRActivity"
android:screenOrientation="landscape"
Expand Down
Loading