XR session will not start again after exit, need to reopen quest browser

After exit session, the three oculus dots appear, attempt to exit and renter session, just shows 3 dots. Need to exit oculus browser and reopen to properly close xr session it seems.

This problem also exists on https://threejs.org/examples/?q=vr#webxr_vr_sandbox testing with Quest2.

I added cleanup() method to the VRButton code below to help with this but no luck…

export class XRButton {

    constructor(renderer, myxr, sessionInit = {}){

        this.currentSession = null;
        this.renderer = renderer;
        this.myxr = myxr;


        // var _features = [
        //     'local-floor',           // Track floor level
        //     // 'bounded-floor',         // Define boundaries of play area
        //     // 'hand-tracking',         // Track hand movements
        //     // 'hit-test',             // Surface detection and hit testing
        //     // 'depth-sensing',         // Sense depth in environment
        //     // 'dom-overlay',          // Overlay HTML content
        //     // 'light-estimation',      // Estimate environmental lighting
        //     // 'anchors',              // Place persistent anchors in space
        //     // 'plane-detection',       // Detect horizontal/vertical surfaces
        //     // 'mesh-detection',        // Detect environmental geometry
        //     // 'local',                // Basic tracking in local space
        //     // 'viewer',               // Track viewer position
        //     // 'unbounded',            // Unlimited movement space
        //     // 'layers',               // Support for layers/compositing
        //     // 'secondary-views'        // Additional camera views
        // ];

        this.sessionOptions = {
            ...sessionInit,
            optionalFeatures: [
                'local-floor',
                'bounded-floor',
                'layers',
                ...( sessionInit.optionalFeatures || [] )
            ],
        };
        this.xrSessionIsGranted = false;

        this.debugAlerts = false;


    }

    

    init(){
        if(navigator.xr){
            navigator.xr.addEventListener( 'sessiongranted', () => {
                this.xrSessionIsGranted = true;
                if(this.debugAlerts)alert("Sessiong is granted");
            } );

            // if ( navigator.xr.offerSession !== undefined ) {
            //     navigator.xr.offerSession( VRMODE, this.sessionOptions )
            //         .then( (session) => this.onSessionStarted(session) )
            //         .catch( ( err ) => {
            //             console.error( err );
            //             $("#vr-error-content-msg").append(err);
            //             $("#vr-error").show();
    
            //         });
            //     if(this.debugAlerts)alert("Offer session on init");
            // }
        }
    }

    async onSessionStarted( session ) {

        session.addEventListener( 'end', ()=>{this.onSessionEnded()} );

        this.currentSession = session;

        await this.renderer.xr.setSession( session );

        
    }

    onSessionEnded( /*event*/ ) {

        if(this.currentSession){
            this.currentSession.removeEventListener( 'end', this.onSessionEnded );
        }

        this.currentSession = null;

        this.cleanup();

        this.myxr.exited();

    }

    click(){

        if(navigator.xr){

            if(this.debugAlerts)alert("Session granted: " + this.xrSessionIsGranted);
            if(this.debugAlerts)alert("Current session: " + this.currentSession);


            if ( this.currentSession === null || !this.currentSession ) {

                navigator.xr.requestSession( VRMODE, this.sessionOptions )
                    .then( (session) => this.onSessionStarted(session) )
                    .catch( ( err ) => {
                        console.error( err );
                        $("#vr-error-content-msg").append(err);
                        $("#vr-error").show();
                    } );

            } else {

                this.currentSession.end();

                if ( navigator.xr.offerSession !== undefined ) {

                    navigator.xr.offerSession( 'immersive-ar', this.sessionOptions )
                        .then( (session) => this.onSessionStarted(session) )
                        .catch( ( err ) => {
                            console.error( err );
                            $("#vr-error-content-msg").append(err);
                            $("#vr-error").show();
                        } );

                }

            }

        }else{
            console.error("XR not supported in this browser");
            $("#vr-error-content-msg").append("XR not supported in this browser");
            $("#vr-error").show();
        }
    }

    cleanup() {

        // End current session if it exists
        if (this.currentSession) {
            //this.currentSession.removeEventListener('end', this.onSessionEnded); //throws error
            this.currentSession.end();
            this.currentSession = null;
        }

        // Clean up renderer XR
        if (this.renderer && this.renderer.xr) {
            this.renderer.xr.setSession(null);
        }

        // Reset session granted flag
        this.xrSessionIsGranted = false;

        // Remove any XR-specific event listeners from navigator
        if (navigator.xr) {
            navigator.xr.removeEventListener('sessiongranted', () => {
                this.xrSessionIsGranted = true;
            });
        }

    }

}

They change that embedded browser like every few weeks, and break it in subtle ways each time.
Maybe someday it will stabilize.

1 Like