@@ -230,50 +230,57 @@ class GoogleSignIn {
230230 }
231231
232232 Future <void > _ensureInitialized () {
233- if (_initialization == null ) {
234- _initialization = channel.invokeMethod <void >('init' , < String , dynamic > {
235- 'signInOption' : (signInOption ?? SignInOption .standard).toString (),
236- 'scopes' : scopes ?? < String > [],
237- 'hostedDomain' : hostedDomain,
238- })
239- ..catchError ((dynamic _) {
240- // Invalidate initialization if it errored out.
241- _initialization = null ;
242- });
243- }
244- return _initialization;
233+ return _initialization ?? =
234+ channel.invokeMethod <void >('init' , < String , dynamic > {
235+ 'signInOption' : (signInOption ?? SignInOption .standard).toString (),
236+ 'scopes' : scopes ?? < String > [],
237+ 'hostedDomain' : hostedDomain,
238+ })
239+ ..catchError ((dynamic _) {
240+ // Invalidate initialization if it errored out.
241+ _initialization = null ;
242+ });
245243 }
246244
247- /// Keeps track of the most recently scheduled method call.
248- _MethodCompleter _lastMethodCompleter;
245+ /// The most recently scheduled method call.
246+ Future <void > _lastMethodCall;
247+
248+ /// Returns a [Future] that completes with a success after [future] , whether
249+ /// it completed with a value or an error.
250+ static Future <void > _waitFor (Future <void > future) {
251+ final Completer <void > completer = Completer <void >();
252+ future.whenComplete (completer.complete).catchError ((dynamic _) {
253+ // Ignore if previous call completed with an error.
254+ });
255+ return completer.future;
256+ }
249257
250258 /// Adds call to [method] in a queue for execution.
251259 ///
252260 /// At most one in flight call is allowed to prevent concurrent (out of order)
253261 /// updates to [currentUser] and [onCurrentUserChanged] .
254- Future <GoogleSignInAccount > _addMethodCall (String method) {
255- if (_lastMethodCompleter == null ) {
256- _lastMethodCompleter = _MethodCompleter (method)
257- ..complete (_callMethod (method));
258- return _lastMethodCompleter.future;
262+ Future <GoogleSignInAccount > _addMethodCall (String method) async {
263+ Future <GoogleSignInAccount > response;
264+ if (_lastMethodCall == null ) {
265+ response = _callMethod (method);
266+ } else {
267+ response = _lastMethodCall.then ((_) {
268+ // If after the last completed call `currentUser` is not `null` and requested
269+ // method is a sign in method, re-use the same authenticated user
270+ // instead of making extra call to the native side.
271+ const List <String > kSignInMethods = < String > [
272+ 'signIn' ,
273+ 'signInSilently'
274+ ];
275+ if (kSignInMethods.contains (method) && _currentUser != null ) {
276+ return _currentUser;
277+ } else {
278+ return _callMethod (method);
279+ }
280+ });
259281 }
260-
261- final _MethodCompleter completer = _MethodCompleter (method);
262- _lastMethodCompleter.future.whenComplete (() {
263- // If after the last completed call currentUser is not null and requested
264- // method is a sign in method, re-use the same authenticated user
265- // instead of making extra call to the native side.
266- const List <String > kSignInMethods = < String > ['signIn' , 'signInSilently' ];
267- if (kSignInMethods.contains (method) && _currentUser != null ) {
268- completer.complete (_currentUser);
269- } else {
270- completer.complete (_callMethod (method));
271- }
272- }).catchError ((dynamic _) {
273- // Ignore if previous call completed with an error.
274- });
275- _lastMethodCompleter = completer;
276- return _lastMethodCompleter.future;
282+ _lastMethodCall = _waitFor (response);
283+ return response;
277284 }
278285
279286 /// The currently signed in account, or null if the user is signed out.
@@ -296,12 +303,17 @@ class GoogleSignIn {
296303 /// returned Future completes with [PlatformException] whose `code` can be
297304 /// either [kSignInRequiredError] (when there is no authenticated user) or
298305 /// [kSignInFailedError] (when an unknown error occurred).
299- Future <GoogleSignInAccount > signInSilently ({bool suppressErrors = true }) {
300- final Future <GoogleSignInAccount > result = _addMethodCall ('signInSilently' );
301- if (suppressErrors) {
302- return result.catchError ((dynamic _) => null );
306+ Future <GoogleSignInAccount > signInSilently (
307+ {bool suppressErrors = true }) async {
308+ try {
309+ return await _addMethodCall ('signInSilently' );
310+ } catch (_) {
311+ if (suppressErrors) {
312+ return null ;
313+ } else {
314+ rethrow ;
315+ }
303316 }
304- return result;
305317 }
306318
307319 /// Returns a future that resolves to whether a user is currently signed in.
@@ -334,26 +346,3 @@ class GoogleSignIn {
334346 /// authentication.
335347 Future <GoogleSignInAccount > disconnect () => _addMethodCall ('disconnect' );
336348}
337-
338- class _MethodCompleter {
339- _MethodCompleter (this .method);
340-
341- final String method;
342- final Completer <GoogleSignInAccount > _completer =
343- Completer <GoogleSignInAccount >();
344-
345- Future <void > complete (FutureOr <GoogleSignInAccount > value) async {
346- if (value is Future <GoogleSignInAccount >) {
347- try {
348- _completer.complete (await value);
349- } catch (e, stacktrace) {
350- _completer.completeError (e, stacktrace);
351- }
352- } else {
353- _completer.complete (value);
354- }
355- }
356-
357- bool get isCompleted => _completer.isCompleted;
358- Future <GoogleSignInAccount > get future => _completer.future;
359- }
0 commit comments