Ocean
Loading...
Searching...
No Matches
NativeApplication.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_PLATFORM_META_QUEST_OPENXR_APPLICATION_NATIVE_APPLICATION_H
9#define META_OCEAN_PLATFORM_META_QUEST_OPENXR_APPLICATION_NATIVE_APPLICATION_H
10
12
14
16
18
19#include <openxr/openxr.h>
20
21#ifdef OCEAN_PLATFORM_BUILD_ANDROID
22 #include <android/native_window_jni.h>
23 #include <android_native_app_glue.h>
24 #include <android/window.h>
25#endif
26
27namespace Ocean
28{
29
30namespace Platform
31{
32
33namespace Meta
34{
35
36namespace Quest
37{
38
39namespace OpenXR
40{
41
42namespace Application
43{
44
45/**
46 * This class implements a basic OpenXR application for Quest devices based on an Android NativeActivity.
47 * @ingroup platformmetaquestopenxrapplication
48 */
49class OCEAN_PLATFORM_META_QUEST_OPENXR_APPLICATION_EXPORT NativeApplication
50{
51 protected:
52
53 /**
54 * Definition of an unordered map mapping from Android permissions to a counter which is used to delay the announcement of Android permissions;
55 * Positive counter values indicate that the permission has been granted and the counter is used to delay the announcement of the granted permission, cf. `handlePendingAndroidPermissions()` for details.
56 * Negative counter values are used to store the state of a permission.
57 */
58 typedef std::unordered_map<std::string, int> AndroidPermissionMap;
59
60 /// The counter value for permissions not yet requested.
61 static constexpr int permissionNotYetRequested_ = -2;
62
63 //// The counter value for permissions not yet granted.
64 static constexpr int permissionNotYetGranted_ = -1;
65
66 /**
67 * Definition of an unordered set holding strings.
68 */
69 typedef std::unordered_set<std::string> StringSet;
70
71 /**
72 * Definition of a vector holding XrViewConfigurationView objects.
73 */
74 typedef std::vector<XrViewConfigurationView> XrViewConfigurationViews;
75
76 public:
77
78 /**
79 * Destructs this object.
80 */
82
83 /**
84 * The run method of this application.
85 * Calling this function will start the application logic and will return before the application closes.
86 * True, if the application closes after a successful execution; False, if the application did not start successfully
87 */
88 virtual bool run();
89
90 /**
91 * Returns the device type that this application is configured for
92 * @return The device type
93 */
94 inline Device::DeviceType deviceType() const;
95
96 /**
97 * Returns the device name that this application is configured for
98 * @return The device name
99 */
100 inline std::string deviceName() const;
101
102 /**
103 * Requests an Android permission that needs to be granted by the user.
104 * In case the user grants the permission, the callback function `onPermissionGranted()` will be invoked (when requesting the permission for the first time).
105 * @param permission The name of the Android permission to request, must be valid
106 * @see onPermissionGranted().
107 */
108 void requestAndroidPermission(std::string&& permission);
109
110 /**
111 * Requests several Android permissions that needs to be granted by the user.
112 * In case the user grants the permission, the callback function `onPermissionGranted()` will be invoked (when requesting the permission for the first time).
113 * @param permissions The names of the Android permissions to request, must be valid
114 * @see onPermissionGranted().
115 */
116 inline void requestAndroidPermissions(std::vector<std::string>&& permissions);
117
118 /**
119 * Returns the Android permissions which have been granted by the user.
120 * @return The currently granted Android permissions
121 */
123
124 protected:
125
126#ifdef OCEAN_PLATFORM_BUILD_ANDROID
127
128 /**
129 * Creates a new application object.
130 * @param androidApp The android app object as provided in the main function of the native activity, must be valid
131 */
132 explicit NativeApplication(struct android_app* androidApp);
133
134#endif // OCEAN_PLATFORM_BUILD_ANDROID
135
136 /**
137 * Disabled copy constructor.
138 * @param nativeApplication Application object which would have been copied
139 */
140 NativeApplication(const NativeApplication& nativeApplication) = delete;
141
142 /**
143 * Returns the names of the necessary OpenXR extensions the application needs.
144 * @return The application's necessary OpenXR extensions
145 */
147
148 /**
149 * Main loop of the application.
150 */
151 virtual void applicationLoop();
152
153 /**
154 * Processes all pending Android events via ALooper_pollOnce.
155 */
156 virtual void processAndroidEvents();
157
158 /**
159 * Processes all pending OpenXR events.
160 */
161 virtual void processOpenXREvents();
162
163 /**
164 * Event functions for changed reference spaces.
165 * @param xrReferenceSpaceType The type of the reference which has changed
166 * @param previous_T_changed The transformation between the changed space and the previous space, invalid if unknown
167 * @param changeTime The time after which xrLocateSpace or xrLocateViews will return values that respect the change
168 */
169 virtual void onChangedReferenceSpace(const XrReferenceSpaceType xrReferenceSpaceType, const HomogenousMatrix4& previous_T_changed, const XrTime& changeTime);
170
171 /**
172 * Returns the current state of the OpenXR session.
173 * @return The session's state
174 */
175 inline XrSessionState xrSessionState() const;
176
177 /**
178 * Creates the OpenXR session.
179 * @param xrViewConfigurationViews The view configuration(s) for the frame buffer(s)
180 * @return True, if succeeded
181 */
182 virtual bool createOpenXRSession(const XrViewConfigurationViews& xrViewConfigurationViews) = 0;
183
184 /**
185 * Releases the OpenXR session.
186 */
187 virtual void releaseOpenXRSession() = 0;
188
189 /**
190 * Event function called after OpenXR has been initialized.
191 */
193
194 /**
195 * Event function called whenever the state of the OpenXR session changed.
196 * @param xrEventDataSessionStateChanged The new OpenXR session state
197 */
198 virtual void onOpenXRSessionChanged(const XrEventDataSessionStateChanged& xrEventDataSessionStateChanged);
199
200 /**
201 * Event function called whenever the session is ready, when the session state changed to XR_SESSION_STATE_READY.
202 */
203 virtual void onOpenXRSessionReady();
204
205 /**
206 * Event function called whenever the session is stopping, when the session state changed to XR_SESSION_STATE_STOPPING.
207 */
209
210 /**
211 * Event function call when an Android (or Oculus) permission is granted
212 * @param permission The name of the permission that has been granted
213 */
214 virtual void onAndroidPermissionGranted(const std::string& permission);
215
216 /**
217 * Event function call when the Android Activity is started.
218 */
219 virtual void onActivityStart();
220
221 /**
222 * Event function call when the Android Activity is resumed.
223 */
224 virtual void onActivityResume();
225
226 /**
227 * Event function call when the Android Activity is paused.
228 */
229 virtual void onActivityPause();
230
231 /**
232 * Event function call when the Android Activity is stopped.
233 */
234 virtual void onActivityStop();
235
236 /**
237 * Event function call when the Android Activity is destroyed.
238 */
239 virtual void onActivityDestroy();
240
241 /**
242 * Event function call when the window of the Android Activity is initialized.
243 */
244 virtual void onActivityInitWindow();
245
246 /**
247 * Event function call when the window of the Android Activity is terminated.
248 */
249 virtual void onActivityTermWindow();
250
251 /**
252 * Event function called at startup to set e.g., windows flags.
253 */
254 virtual void onStartup();
255
256 /**
257 * Idle event function called within the main loop whenever all Android related events have been processed.
258 */
259 virtual void onIdle() = 0;
260
261 /**
262 * Checks if a specific permission has been granted.
263 * @param permission The string identifier of a permission, must be valid
264 * @param translate Optionally translate permissions internally (short to long name), must be `false` in conjunction with Oculus permission such as `com.oculus.permission.USE_SCENE`
265 * @return True if the specified permission has been granted, otherwise false
266 */
267 bool isAndroidPermissionGranted(const std::string& permission, const bool translate = false) const;
268
269 /**
270 * Checks if any item from a set of pending permissions has been granted to the app
271 * If a pending permission has been found to be granted, it will be removed from the set of pending permissions and added to the set of granted permission.
272 * This will also call `onPermissionGranted()` in order to notify the application about the permission changes.
273 *
274 * Important note:
275 *
276 * In Android, when permissions are granted by the user for the firs time, there seems to be a delay
277 * for some permissions between when (A) they are marked as granted, i.e., `hasPermission()` returns
278 * `true` and (B) when the permission is actually granted and can be used. Any action that requires
279 * such an affected permission that is run in the time between (A) and (B) is still likely to fail (as
280 * if the permission had not been granted in the first place). The permission will be usable after
281 * a few moments (i.e., after a few milliseconds or after a few iterations of the main loop of the app).
282 *
283 * On consecutive starts of the app and assuming all requested permissions have been granted before,
284 * this is no longer a problem; `hasPermission()` returns `true` and the permission is immediately
285 * usable.
286 *
287 * The function applies a short delay before announcing them via `onPermissionGranted()` to all
288 * permissions.
289 *
290 * @param firstCheck True when this function is called for the first time since the app started, otherwise false; cf. the note above.
291 */
292 void handlePendingAndroidPermissions(const bool firstCheck);
293
294 /**
295 * Disabled copy operator.
296 * @param nativeApplication Application object which would have been copied
297 * @return Reference to this object
298 */
299 NativeApplication& operator=(const NativeApplication& nativeApplication) = delete;
300
301 /**
302 * Android's command event function.
303 * @param androidApp The android app object
304 * @param cmd The command
305 */
306 static void onAndroidCommand(struct android_app* androidApp, int32_t cmd);
307
308 protected:
309
310 /// The OpenXR instance used by this application.
312
313 /// The OpenXR view configuration type to be used.
314 XrViewConfigurationType xrViewConfigurationType_ = XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
315
316#ifdef OCEAN_PLATFORM_BUILD_ANDROID
317
318 /// The Java native interface envrionment.
319 JNIEnv* jniEnv_ = nullptr;
320
321 // The android app object as provided in the main function of the native activity.
322 struct android_app* androidApp_ = nullptr;
323
324#endif
325
326 /// True, if the application has been resumed; False, if the application has e.g., been paused or stopped.
327 bool applicationResumed_ = false;
328
329 /// The native Android window, if any.
330 ANativeWindow* androidNativeWindow_ = nullptr;
331
332 /// The device type that this application is configured for.
333 Device::DeviceType deviceType_ = Meta::Quest::Device::DT_UNKNOWN;
334
335 /// The map mapping the names of pending Android permissions to a delay counter.
337
338 /// The set holding the names of granted Android permissions.
340
341 /// The lock for Android permissions.
343
344 private:
345
346 /// The current OpenXR session state.
347 XrSessionState xrSessionState_ = XR_SESSION_STATE_UNKNOWN;
348
349 /// True, if the OpenXR session is ready to be used.
350 bool xrSessionIsReady_ = false;
351};
352
357
358inline std::string NativeApplication::deviceName() const
359{
361}
362
363inline void NativeApplication::requestAndroidPermissions(std::vector<std::string>&& permissions)
364{
365 const ScopedLock scopedLock(androidPermissionLock_);
366
367 for (std::string& permission : permissions)
368 {
369 requestAndroidPermission(std::move(permission));
370 }
371}
372
373inline XrSessionState NativeApplication::xrSessionState() const
374{
375 return xrSessionState_;
376}
377
378}
379
380}
381
382}
383
384}
385
386}
387
388}
389
390#endif // META_OCEAN_PLATFORM_META_QUEST_OPENXR_APPLICATION_NATIVE_APPLICATION_H
This class implements a recursive lock object.
Definition Lock.h:31
DeviceType
Definition of individual device types.
Definition platform/meta/quest/Device.h:37
static std::string deviceName()
Returns the name of the device.
Definition platform/meta/quest/Device.h:82
This class implements a basic OpenXR application for Quest devices based on an Android NativeActivity...
Definition NativeApplication.h:50
virtual void onActivityInitWindow()
Event function call when the window of the Android Activity is initialized.
Device::DeviceType deviceType() const
Returns the device type that this application is configured for.
Definition NativeApplication.h:353
void requestAndroidPermission(std::string &&permission)
Requests an Android permission that needs to be granted by the user.
virtual void onActivityStart()
Event function call when the Android Activity is started.
void handlePendingAndroidPermissions(const bool firstCheck)
Checks if any item from a set of pending permissions has been granted to the app If a pending permiss...
virtual void onAndroidPermissionGranted(const std::string &permission)
Event function call when an Android (or Oculus) permission is granted.
virtual void applicationLoop()
Main loop of the application.
NativeApplication & operator=(const NativeApplication &nativeApplication)=delete
Disabled copy operator.
std::unordered_map< std::string, int > AndroidPermissionMap
Definition of an unordered map mapping from Android permissions to a counter which is used to delay t...
Definition NativeApplication.h:58
NativeApplication(struct android_app *androidApp)
Creates a new application object.
virtual void onOpenXRSessionStopping()
Event function called whenever the session is stopping, when the session state changed to XR_SESSION_...
bool isAndroidPermissionGranted(const std::string &permission, const bool translate=false) const
Checks if a specific permission has been granted.
virtual void processOpenXREvents()
Processes all pending OpenXR events.
virtual void onOpenXRInstanceInitialized()
Event function called after OpenXR has been initialized.
virtual void onStartup()
Event function called at startup to set e.g., windows flags.
StringSet grantedAndroidPermissions() const
Returns the Android permissions which have been granted by the user.
virtual void onActivityStop()
Event function call when the Android Activity is stopped.
std::unordered_set< std::string > StringSet
Definition of an unordered set holding strings.
Definition NativeApplication.h:69
std::vector< XrViewConfigurationView > XrViewConfigurationViews
Definition of a vector holding XrViewConfigurationView objects.
Definition NativeApplication.h:74
virtual void releaseOpenXRSession()=0
Releases the OpenXR session.
virtual void onIdle()=0
Idle event function called within the main loop whenever all Android related events have been process...
AndroidPermissionMap pendingAndroidPermissionMap_
The map mapping the names of pending Android permissions to a delay counter.
Definition NativeApplication.h:336
XrSessionState xrSessionState() const
Returns the current state of the OpenXR session.
Definition NativeApplication.h:373
virtual void onChangedReferenceSpace(const XrReferenceSpaceType xrReferenceSpaceType, const HomogenousMatrix4 &previous_T_changed, const XrTime &changeTime)
Event functions for changed reference spaces.
std::string deviceName() const
Returns the device name that this application is configured for.
Definition NativeApplication.h:358
virtual void processAndroidEvents()
Processes all pending Android events via ALooper_pollOnce.
virtual void onActivityDestroy()
Event function call when the Android Activity is destroyed.
Platform::OpenXR::Instance xrInstance_
The OpenXR instance used by this application.
Definition NativeApplication.h:311
virtual bool createOpenXRSession(const XrViewConfigurationViews &xrViewConfigurationViews)=0
Creates the OpenXR session.
virtual void onActivityResume()
Event function call when the Android Activity is resumed.
StringSet grantedAndroidPermissionSet_
The set holding the names of granted Android permissions.
Definition NativeApplication.h:339
virtual void onActivityTermWindow()
Event function call when the window of the Android Activity is terminated.
virtual StringSet necessaryOpenXRExtensionNames() const
Returns the names of the necessary OpenXR extensions the application needs.
Device::DeviceType deviceType_
The device type that this application is configured for.
Definition NativeApplication.h:333
virtual void onOpenXRSessionReady()
Event function called whenever the session is ready, when the session state changed to XR_SESSION_STA...
Lock androidPermissionLock_
The lock for Android permissions.
Definition NativeApplication.h:342
virtual bool run()
The run method of this application.
virtual void onActivityPause()
Event function call when the Android Activity is paused.
virtual void onOpenXRSessionChanged(const XrEventDataSessionStateChanged &xrEventDataSessionStateChanged)
Event function called whenever the state of the OpenXR session changed.
void requestAndroidPermissions(std::vector< std::string > &&permissions)
Requests several Android permissions that needs to be granted by the user.
Definition NativeApplication.h:363
static void onAndroidCommand(struct android_app *androidApp, int32_t cmd)
Android's command event function.
XrSessionState xrSessionState_
The current OpenXR session state.
Definition NativeApplication.h:347
NativeApplication(const NativeApplication &nativeApplication)=delete
Disabled copy constructor.
This class wraps an OpenXR instance.
Definition Instance.h:30
This class implements a scoped lock object for recursive lock objects.
Definition Lock.h:135
The namespace covering the entire Ocean framework.
Definition Accessor.h:15