55 AppState ,
66 Linking ,
77 NativeEventSubscription ,
8+ NativeModules ,
89 Platform ,
910} from 'react-native' ;
1011
@@ -13,6 +14,32 @@ import { nativeModule } from '../nativeModule';
1314let appStateListener : NativeEventSubscription | undefined ;
1415let redirectListener : NativeEventSubscription | undefined ;
1516
17+ export async function isChromebook ( ) : Promise < boolean > {
18+ // expo go
19+ try {
20+ const Device = require ( 'expo-device' ) ;
21+ if ( Device ?. hasPlatformFeatureAsync ) {
22+ if ( await Device . hasPlatformFeatureAsync ( 'org.chromium.arc' ) ) return true ;
23+ if (
24+ await Device . hasPlatformFeatureAsync (
25+ 'org.chromium.arc.device_management' ,
26+ )
27+ )
28+ return true ;
29+ }
30+ } catch {
31+ // not using Expo
32+ }
33+
34+ // fallback to native module
35+ try {
36+ const nm = ( NativeModules as any ) ?. ChromeOS ;
37+ if ( nm ?. isChromeOS ) return ! ! ( await nm . isChromeOS ( ) ) ;
38+ } catch { }
39+
40+ return false ;
41+ }
42+
1643export const openAuthSessionAsync = async (
1744 url : string ,
1845 redirectUrls : string [ ] ,
@@ -25,6 +52,15 @@ export const openAuthSessionAsync = async (
2552 }
2653
2754 if ( Platform . OS === 'android' ) {
55+ try {
56+ const isChromebookRes = await isChromebook ( ) ;
57+ if ( isChromebookRes ) {
58+ return openAuthSessionChromeOs ( httpsUrl , redirectUrls ) ;
59+ }
60+ } catch {
61+ // ignore and fallback to android
62+ }
63+
2864 return openAuthSessionAndroid ( httpsUrl , redirectUrls ) ;
2965 }
3066} ;
@@ -66,6 +102,27 @@ const openAuthSessionAndroid = async (url: string, redirectUrls: string[]) => {
66102 }
67103} ;
68104
105+ const openAuthSessionChromeOs = async ( url : string , redirectUrls : string [ ] ) => {
106+ try {
107+ const [ redirectUrl ] = await Promise . all ( [
108+ Promise . race ( [
109+ // wait for app to redirect, resulting in a redirectUrl
110+ getRedirectPromise ( redirectUrls ) ,
111+ // wait for app to return some other way, resulting in null
112+ getAppStatePromise ( ) ,
113+ ] ) ,
114+ Linking . openURL ( url ) ,
115+ ] ) ;
116+
117+ if ( redirectUrl ) Linking . openURL ( redirectUrl ) ;
118+
119+ return redirectUrl ;
120+ } finally {
121+ removeAppStateListener ( ) ;
122+ removeRedirectListener ( ) ;
123+ }
124+ } ;
125+
69126const getAppStatePromise = ( ) : Promise < null > =>
70127 new Promise ( resolve => {
71128 // remove any stray listeners before creating new ones
0 commit comments