Skip to content

Commit bb96d69

Browse files
committed
Support making hybrid apps for Pico headsets
1 parent 7df9262 commit bb96d69

7 files changed

Lines changed: 303 additions & 19 deletions

File tree

plugin/src/main/cpp/export/export_plugin.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,25 @@ OpenXREditorExportPlugin::HybridType OpenXREditorExportPlugin::_get_hybrid_app_s
9595
return (HybridType)(int)ProjectSettings::get_singleton()->get_setting_with_override("xr/openxr/hybrid_app");
9696
}
9797

98+
String OpenXREditorExportPlugin::_get_opening_activity_tag_for_panel_app() const {
99+
ProjectSettings *project_settings = ProjectSettings::get_singleton();
100+
101+
return vformat(
102+
" <activity android:name=\"org.godotengine.openxr.vendors.GodotPanelApp\" "
103+
"android:process=\":GodotPanelApp\" "
104+
"android:theme=\"@style/GodotPanelAppSplashTheme\" "
105+
"android:launchMode=\"singleInstancePerTask\" "
106+
"android:exported=\"true\" "
107+
"android:excludeFromRecents=\"%s\" "
108+
"android:screenOrientation=\"%s\" "
109+
"android:resizeableActivity=\"%s\" "
110+
"android:configChanges=\"orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode\" "
111+
"tools:ignore=\"UnusedAttribute\">\n",
112+
_bool_to_string(_get_bool_option("package/exclude_from_recents")),
113+
_get_android_orientation_label((DisplayServer::ScreenOrientation)(int)project_settings->get_setting_with_override("display/window/handheld/orientation")),
114+
_bool_to_string(project_settings->get_setting_with_override("display/window/size/resizable")));
115+
}
116+
98117
bool OpenXREditorExportPlugin::_is_openxr_enabled() const {
99118
return _get_int_option("xr_features/xr_mode", REGULAR_MODE_VALUE) == OPENXR_MODE_VALUE;
100119
}

plugin/src/main/cpp/export/meta_export_plugin.cpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -482,22 +482,7 @@ String MetaEditorExportPlugin::_get_android_manifest_application_element_content
482482

483483
HybridType hybrid_type = _get_hybrid_app_setting_value();
484484
if (hybrid_type != HYBRID_TYPE_DISABLED) {
485-
ProjectSettings *project_settings = ProjectSettings::get_singleton();
486-
487-
contents += vformat(
488-
" <activity android:name=\"org.godotengine.openxr.vendors.GodotPanelApp\" "
489-
"android:process=\":GodotPanelApp\" "
490-
"android:theme=\"@style/GodotPanelAppSplashTheme\" "
491-
"android:launchMode=\"singleInstancePerTask\" "
492-
"android:exported=\"true\" "
493-
"android:excludeFromRecents=\"%s\" "
494-
"android:screenOrientation=\"%s\" "
495-
"android:resizeableActivity=\"%s\" "
496-
"android:configChanges=\"orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode\" "
497-
"tools:ignore=\"UnusedAttribute\">\n",
498-
_bool_to_string(_get_bool_option("package/exclude_from_recents")),
499-
_get_android_orientation_label((DisplayServer::ScreenOrientation)(int)project_settings->get_setting_with_override("display/window/handheld/orientation")),
500-
_bool_to_string(project_settings->get_setting_with_override("display/window/size/resizable")));
485+
contents += _get_opening_activity_tag_for_panel_app();
501486

502487
contents +=
503488
" <intent-filter>\n"

plugin/src/main/cpp/export/pico_export_plugin.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ PackedStringArray PicoEditorExportPlugin::_get_export_features(const Ref<EditorE
119119
features.append(EYE_GAZE_INTERACTION_FEATURE);
120120
}
121121

122+
// Add a feature to indicate that this is a hybrid app.
123+
if (_is_openxr_enabled() && _get_hybrid_app_setting_value() != HYBRID_TYPE_DISABLED) {
124+
features.append(HYBRID_APP_FEATURE);
125+
}
126+
122127
return features;
123128
}
124129

@@ -200,5 +205,25 @@ String PicoEditorExportPlugin::_get_android_manifest_application_element_content
200205
contents += " <meta-data tools:node=\"replace\" android:name=\"Hand_Tracking_HighFrequency\" android:value=\"1\" />\n";
201206
}
202207

208+
HybridType hybrid_type = _get_hybrid_app_setting_value();
209+
if (hybrid_type != HYBRID_TYPE_DISABLED) {
210+
contents += " <meta-data tools:node=\"replace\" android:name=\"pvr.app.type\" android:value=\"2d\" />\n";
211+
212+
contents += _get_opening_activity_tag_for_panel_app();
213+
214+
contents +=
215+
" <intent-filter>\n"
216+
" <action android:name=\"android.intent.action.MAIN\" />\n"
217+
" <category android:name=\"android.intent.category.DEFAULT\" />\n";
218+
219+
if (hybrid_type == HYBRID_TYPE_START_AS_PANEL) {
220+
contents += " <category android:name=\"android.intent.category.LAUNCHER\" />\n";
221+
}
222+
223+
contents +=
224+
" </intent-filter>\n"
225+
" </activity>\n";
226+
}
227+
203228
return contents;
204229
}

plugin/src/main/cpp/include/export/export_plugin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ class OpenXREditorExportPlugin : public EditorExportPlugin {
116116

117117
HybridType _get_hybrid_app_setting_value() const;
118118

119+
String _get_opening_activity_tag_for_panel_app() const;
120+
119121
bool _is_openxr_enabled() const;
120122

121123
bool _get_bool_option(const String &option) const;

plugin/src/pico/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
<meta-data android:name="org.godotengine.plugin.v2.GodotOpenXRPico"
2323
android:value="org.godotengine.openxr.vendors.pico.GodotOpenXRPico" />
2424

25+
<meta-data android:name="org.godotengine.plugin.v2.GodotOpenXRHybridAppInternal"
26+
android:value="org.godotengine.openxr.vendors.GodotOpenXRHybridAppInternal" />
27+
2528
<!-- Enable VR mode on Pico headsets -->
2629
<meta-data android:name="pvr.app.type" android:value="vr" />
2730
<meta-data android:name="pvr.sdk.version" android:value="OpenXR" />";

samples/hybrid-app-sample/export_presets.cfg

Lines changed: 250 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
name="Quest"
44
platform="Android"
5-
runnable=true
5+
runnable=false
66
advanced_options=true
77
dedicated_server=false
88
custom_features=""
@@ -245,3 +245,252 @@ pico_xr_features/face_tracking=0
245245
pico_xr_features/hand_tracking=0
246246
xr_features/enable_magicleap_plugin=false
247247
magicleap_xr_features/hand_tracking=0
248+
pico_xr_features/hybrid_app=0
249+
250+
[preset.1]
251+
252+
name="Pico"
253+
platform="Android"
254+
runnable=true
255+
advanced_options=false
256+
dedicated_server=false
257+
custom_features=""
258+
export_filter="all_resources"
259+
include_filter=""
260+
exclude_filter=""
261+
export_path="../builds/PicoHybridAppSample.apk"
262+
patches=PackedStringArray()
263+
encryption_include_filters=""
264+
encryption_exclude_filters=""
265+
seed=0
266+
encrypt_pck=false
267+
encrypt_directory=false
268+
script_export_mode=2
269+
270+
[preset.1.options]
271+
272+
custom_template/debug=""
273+
custom_template/release=""
274+
gradle_build/use_gradle_build=true
275+
gradle_build/gradle_build_directory=""
276+
gradle_build/android_source_template=""
277+
gradle_build/compress_native_libraries=false
278+
gradle_build/export_format=0
279+
gradle_build/min_sdk=""
280+
gradle_build/target_sdk=""
281+
architectures/armeabi-v7a=false
282+
architectures/arm64-v8a=true
283+
architectures/x86=false
284+
architectures/x86_64=false
285+
version/code=1
286+
version/name=""
287+
package/unique_name="com.godotopenxrvendors.picohybridappsample"
288+
package/name=""
289+
package/signed=true
290+
package/app_category=2
291+
package/retain_data_on_uninstall=false
292+
package/exclude_from_recents=false
293+
package/show_in_android_tv=false
294+
package/show_in_app_library=true
295+
package/show_as_launcher_app=false
296+
launcher_icons/main_192x192=""
297+
launcher_icons/adaptive_foreground_432x432=""
298+
launcher_icons/adaptive_background_432x432=""
299+
launcher_icons/adaptive_monochrome_432x432=""
300+
graphics/opengl_debug=false
301+
xr_features/xr_mode=1
302+
wear_os/swipe_to_dismiss=true
303+
screen/immersive_mode=true
304+
screen/support_small=true
305+
screen/support_normal=true
306+
screen/support_large=true
307+
screen/support_xlarge=true
308+
user_data_backup/allow=false
309+
command_line/extra_args=""
310+
apk_expansion/enable=false
311+
apk_expansion/SALT=""
312+
apk_expansion/public_key=""
313+
permissions/custom_permissions=PackedStringArray()
314+
permissions/access_checkin_properties=false
315+
permissions/access_coarse_location=false
316+
permissions/access_fine_location=false
317+
permissions/access_location_extra_commands=false
318+
permissions/access_media_location=false
319+
permissions/access_mock_location=false
320+
permissions/access_network_state=false
321+
permissions/access_surface_flinger=false
322+
permissions/access_wifi_state=false
323+
permissions/account_manager=false
324+
permissions/add_voicemail=false
325+
permissions/authenticate_accounts=false
326+
permissions/battery_stats=false
327+
permissions/bind_accessibility_service=false
328+
permissions/bind_appwidget=false
329+
permissions/bind_device_admin=false
330+
permissions/bind_input_method=false
331+
permissions/bind_nfc_service=false
332+
permissions/bind_notification_listener_service=false
333+
permissions/bind_print_service=false
334+
permissions/bind_remoteviews=false
335+
permissions/bind_text_service=false
336+
permissions/bind_vpn_service=false
337+
permissions/bind_wallpaper=false
338+
permissions/bluetooth=false
339+
permissions/bluetooth_admin=false
340+
permissions/bluetooth_privileged=false
341+
permissions/brick=false
342+
permissions/broadcast_package_removed=false
343+
permissions/broadcast_sms=false
344+
permissions/broadcast_sticky=false
345+
permissions/broadcast_wap_push=false
346+
permissions/call_phone=false
347+
permissions/call_privileged=false
348+
permissions/camera=false
349+
permissions/capture_audio_output=false
350+
permissions/capture_secure_video_output=false
351+
permissions/capture_video_output=false
352+
permissions/change_component_enabled_state=false
353+
permissions/change_configuration=false
354+
permissions/change_network_state=false
355+
permissions/change_wifi_multicast_state=false
356+
permissions/change_wifi_state=false
357+
permissions/clear_app_cache=false
358+
permissions/clear_app_user_data=false
359+
permissions/control_location_updates=false
360+
permissions/delete_cache_files=false
361+
permissions/delete_packages=false
362+
permissions/device_power=false
363+
permissions/diagnostic=false
364+
permissions/disable_keyguard=false
365+
permissions/dump=false
366+
permissions/expand_status_bar=false
367+
permissions/factory_test=false
368+
permissions/flashlight=false
369+
permissions/force_back=false
370+
permissions/get_accounts=false
371+
permissions/get_package_size=false
372+
permissions/get_tasks=false
373+
permissions/get_top_activity_info=false
374+
permissions/global_search=false
375+
permissions/hardware_test=false
376+
permissions/inject_events=false
377+
permissions/install_location_provider=false
378+
permissions/install_packages=false
379+
permissions/install_shortcut=false
380+
permissions/internal_system_window=false
381+
permissions/internet=false
382+
permissions/kill_background_processes=false
383+
permissions/location_hardware=false
384+
permissions/manage_accounts=false
385+
permissions/manage_app_tokens=false
386+
permissions/manage_documents=false
387+
permissions/manage_external_storage=false
388+
permissions/master_clear=false
389+
permissions/media_content_control=false
390+
permissions/modify_audio_settings=false
391+
permissions/modify_phone_state=false
392+
permissions/mount_format_filesystems=false
393+
permissions/mount_unmount_filesystems=false
394+
permissions/nfc=false
395+
permissions/persistent_activity=false
396+
permissions/post_notifications=false
397+
permissions/process_outgoing_calls=false
398+
permissions/read_calendar=false
399+
permissions/read_call_log=false
400+
permissions/read_contacts=false
401+
permissions/read_external_storage=false
402+
permissions/read_frame_buffer=false
403+
permissions/read_history_bookmarks=false
404+
permissions/read_input_state=false
405+
permissions/read_logs=false
406+
permissions/read_media_audio=false
407+
permissions/read_media_images=false
408+
permissions/read_media_video=false
409+
permissions/read_media_visual_user_selected=false
410+
permissions/read_phone_state=false
411+
permissions/read_profile=false
412+
permissions/read_sms=false
413+
permissions/read_social_stream=false
414+
permissions/read_sync_settings=false
415+
permissions/read_sync_stats=false
416+
permissions/read_user_dictionary=false
417+
permissions/reboot=false
418+
permissions/receive_boot_completed=false
419+
permissions/receive_mms=false
420+
permissions/receive_sms=false
421+
permissions/receive_wap_push=false
422+
permissions/record_audio=false
423+
permissions/reorder_tasks=false
424+
permissions/restart_packages=false
425+
permissions/send_respond_via_message=false
426+
permissions/send_sms=false
427+
permissions/set_activity_watcher=false
428+
permissions/set_alarm=false
429+
permissions/set_always_finish=false
430+
permissions/set_animation_scale=false
431+
permissions/set_debug_app=false
432+
permissions/set_orientation=false
433+
permissions/set_pointer_speed=false
434+
permissions/set_preferred_applications=false
435+
permissions/set_process_limit=false
436+
permissions/set_time=false
437+
permissions/set_time_zone=false
438+
permissions/set_wallpaper=false
439+
permissions/set_wallpaper_hints=false
440+
permissions/signal_persistent_processes=false
441+
permissions/status_bar=false
442+
permissions/subscribed_feeds_read=false
443+
permissions/subscribed_feeds_write=false
444+
permissions/system_alert_window=false
445+
permissions/transmit_ir=false
446+
permissions/uninstall_shortcut=false
447+
permissions/update_device_stats=false
448+
permissions/use_credentials=false
449+
permissions/use_sip=false
450+
permissions/vibrate=false
451+
permissions/wake_lock=false
452+
permissions/write_apn_settings=false
453+
permissions/write_calendar=false
454+
permissions/write_call_log=false
455+
permissions/write_contacts=false
456+
permissions/write_external_storage=false
457+
permissions/write_gservices=false
458+
permissions/write_history_bookmarks=false
459+
permissions/write_profile=false
460+
permissions/write_secure_settings=false
461+
permissions/write_settings=false
462+
permissions/write_sms=false
463+
permissions/write_social_stream=false
464+
permissions/write_sync_settings=false
465+
permissions/write_user_dictionary=false
466+
xr_features/enable_khronos_plugin=false
467+
khronos_xr_features/vendors=0
468+
khronos_xr_features/htc/hand_tracking=0
469+
khronos_xr_features/htc/tracker=0
470+
khronos_xr_features/htc/eye_tracking=0
471+
khronos_xr_features/htc/lip_expression=0
472+
xr_features/enable_lynx_plugin=false
473+
xr_features/enable_meta_plugin=false
474+
meta_xr_features/eye_tracking=0
475+
meta_xr_features/face_tracking=0
476+
meta_xr_features/body_tracking=0
477+
meta_xr_features/hand_tracking=0
478+
meta_xr_features/hand_tracking_frequency=0
479+
meta_xr_features/passthrough=0
480+
meta_xr_features/render_model=0
481+
meta_xr_features/use_anchor_api=false
482+
meta_xr_features/use_anchor_sharing=false
483+
meta_xr_features/use_scene_api=false
484+
meta_xr_features/use_overlay_keyboard=false
485+
meta_xr_features/use_experimental_features=false
486+
meta_xr_features/boundary_mode=0
487+
meta_xr_features/quest_1_support=false
488+
meta_xr_features/quest_2_support=true
489+
meta_xr_features/quest_3_support=true
490+
meta_xr_features/quest_pro_support=true
491+
xr_features/enable_pico_plugin=true
492+
pico_xr_features/eye_tracking=0
493+
pico_xr_features/face_tracking=0
494+
pico_xr_features/hand_tracking=0
495+
xr_features/enable_magicleap_plugin=false
496+
magicleap_xr_features/hand_tracking=0

samples/hybrid-app-sample/main.gd

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ func _process(_delta: float) -> void:
5959
panel_switcher_layer.update_pointer(t.origin, -t.basis.z, pointer_pressed)
6060

6161
func _on_right_controller_pointer_button_pressed(p_name: String) -> void:
62-
if p_name == 'trigger_click':
62+
print("button: ", p_name)
63+
if p_name == 'trigger_click' or p_name == 'select_button':
6364
pointer_pressed = true
6465

6566
func _on_right_controller_pointer_button_released(p_name: String) -> void:
66-
if p_name == 'trigger_click':
67+
if p_name == 'trigger_click' or p_name == 'select_button':
6768
pointer_pressed = false

0 commit comments

Comments
 (0)