//
// Copyright (C) 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace Google {
using System;
using System.Runtime.Serialization;
using System.Threading.Tasks;
using Google.Impl;
using UnityEngine;
///
/// Google sign in API.
///
/// This class implements the GoogleSignInAPI for Unity.
/// Typical usage is to set the Configuration options as needed, then
/// get the DefaultInstance and call signIn or signInSilently. See
/// the
/// Google Sign-In API documentation for more details.
///
///
/// private static readonly GoogleSignInConfiguration configuration =
/// new GoogleSignInConfiguration {
/// WebClientId = "",
/// RequestIdToken = true
/// };
///
/// public void OnSignIn() {
/// GoogleSignIn.Configuration = configuration;
/// GoogleSignIn.Configuration.UseGameSignIn = false;
/// GoogleSignIn.Configuration.RequestIdToken = true;
/// GoogleSignIn.DefaultInstance.SignIn().ContinueWith(
/// OnAuthenticationFinished);
/// }
///
///
///
public class GoogleSignIn {
#if !UNITY_ANDROID && !UNITY_IOS
static GoogleSignIn() {
Debug.LogError("This platform is not supported");
}
#endif
private static GoogleSignIn theInstance = null;
private static GoogleSignInConfiguration theConfiguration = null;
private ISignInImpl impl;
/// The configuration settings for Google Sign-in.
/// The configuration should be set before calling the sign-in
/// methods. Once the configuration is set it cannot be changed.
///
public static GoogleSignInConfiguration Configuration {
set {
// Can set the configuration until the singleton is created.
if (theInstance == null || theConfiguration == value || theConfiguration == null) {
theConfiguration = value;
} else {
throw new SignInException(GoogleSignInStatusCode.DeveloperError,
"DefaultInstance already created. " +
" Cannot change configuration after creation.");
}
}
get {
return theConfiguration;
}
}
///
/// Singleton instance of this class.
///
/// The instance.
public static GoogleSignIn DefaultInstance {
get {
if (theInstance == null) {
#if UNITY_ANDROID || UNITY_IOS
theInstance = new GoogleSignIn(new GoogleSignInImpl(Configuration));
#else
theInstance = new GoogleSignIn(null);
throw new SignInException(
GoogleSignInStatusCode.DeveloperError,
"This platform is not supported by GoogleSignIn");
#endif
}
return theInstance;
}
}
internal GoogleSignIn(GoogleSignInImpl impl) {
this.impl = impl;
}
public void EnableDebugLogging(bool flag) {
impl.EnableDebugLogging(flag);
}
/// Starts the authentication process.
///
/// The authenication process is started and may display account picker
/// popups and consent prompts based on the state of authentication and
/// the requested elements.
///
public Task SignIn() {
var tcs = new TaskCompletionSource();
SignInHelperObject.Instance.StartCoroutine(
impl.SignIn().WaitForResult(tcs));
return tcs.Task;
}
/// Starts the silent authentication process.
///
/// The authenication process is started and will attempt to sign in without
/// displaying any UI. If this cannot be done, the developer should call
/// SignIn().
///
public Task SignInSilently() {
var tcs = new TaskCompletionSource();
SignInHelperObject.Instance.StartCoroutine(
impl.SignInSilently().WaitForResult(tcs));
return tcs.Task;
}
///
/// Signs out the User.
///
/// Future sign-in attempts will require the user to select the
/// account to use when signing in.
///
public void SignOut() {
theConfiguration = null;
impl.SignOut();
}
///
/// Disconnect this instance.
///
/// When the user is disconnected, it revokes all access that may
/// have been granted to this application. This includes any server side
/// access tokens derived from server auth codes. As a result, future
/// sign-in attempts will require the user to re-consent to the requested
/// scopes.
///
public void Disconnect() {
impl.Disconnect();
}
///
/// Sign in exception. This is a checked exception for handling specific
/// errors during the sign-in process.
///
[Serializable]
public class SignInException : Exception {
internal SignInException(GoogleSignInStatusCode status) {
Status = status;
}
public SignInException(GoogleSignInStatusCode status, string message) :
base(message) {
Status = status;
}
public SignInException(GoogleSignInStatusCode status, string message,
Exception innerException) : base(message, innerException) {
Status = status;
}
protected SignInException(GoogleSignInStatusCode status,
SerializationInfo info,
StreamingContext context) :
base(info, context) {
Status = status;
}
public GoogleSignInStatusCode Status {
get;
internal set;
}
}
}
internal interface ISignInImpl {
Future SignIn();
Future SignInSilently();
void EnableDebugLogging(bool flag);
void SignOut();
void Disconnect();
}
} // namespace Google