Skip to content

Commit

Permalink
Finish migration to Play Games Services v2.
Browse files Browse the repository at this point in the history
Fix `isSignedIn`.
Remove use of GoogleSignIn.
Remove silent/explicit sign in methods.
Remove `enableSavedGames` from `signIn`.
Remove `isAuthenticated` check from `signIn`.
Remove `signOut` method.
Bump version to 4.0.0.
  • Loading branch information
theLee3 committed Oct 6, 2023
1 parent 7f14941 commit 242cb06
Show file tree
Hide file tree
Showing 11 changed files with 39 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import com.abedalkareem.games_services.models.value
import com.abedalkareem.games_services.util.PluginError
import com.abedalkareem.games_services.util.errorCode
import com.google.android.gms.auth.api.Auth
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.drive.Drive
import com.google.android.gms.games.AuthenticationResult
import com.google.android.gms.games.PlayGames
Expand All @@ -23,93 +20,36 @@ private const val RC_SIGN_IN = 9000

class Auth : PluginRegistry.ActivityResultListener {

private var googleSignInClient: GoogleSignInClient? = null
private var pendingOperation: PendingOperation? = null

fun isSignedIn(
activity: Activity?,
result: MethodChannel.Result
) {
val value = activity?.let { GoogleSignIn.getLastSignedInAccount(it) } != null
result.success(value)
}

fun silentSignIn(
activity: Activity?,
shouldEnableSavedGame: Boolean,
result: MethodChannel.Result
) {
fun isSignedIn(activity: Activity?, result: MethodChannel.Result) {
activity ?: return
if (!shouldEnableSavedGame) {
signInV2(activity, result)
return
}
val signInOption = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)

signInOption.requestScopes(Drive.SCOPE_APPFOLDER)

googleSignInClient = activity.let { GoogleSignIn.getClient(it, signInOption.build()) }
googleSignInClient?.silentSignIn()?.addOnCompleteListener { task ->
pendingOperation = PendingOperation(Method.SilentSignIn.value(), result, activity)
if (task.isSuccessful) {
handleSignInResult(activity)
} else {
Log.e("Error", "signInError", task.exception)
Log.i("ExplicitSignIn", "Trying explicit sign in")
explicitSignIn(activity)
}
}
}

private fun signInV2(activity: Activity, result: MethodChannel.Result) {
val gamesSignInClient = PlayGames.getGamesSignInClient(activity)
pendingOperation = PendingOperation(Method.SilentSignIn.value(), result, activity)
gamesSignInClient.isAuthenticated.addOnCompleteListener { isAuthenticatedTask: Task<AuthenticationResult> ->
val isAuthenticated = isAuthenticatedTask.isSuccessful &&
isAuthenticatedTask.result.isAuthenticated
if (isAuthenticated) {
handleSignInResult(activity)
} else {
gamesSignInClient.signIn().addOnSuccessListener {
it?.let { result -> Log.i("PlayService", "isAuthenticated: ${result.isAuthenticated} toString: $result") }
handleSignInResult(activity)
}.addOnFailureListener {
it.let { result -> Log.i("PlayService", "isAuthenticated: ${result.localizedMessage} toString: $result") }
finishPendingOperationWithError(PluginError.FailedToAuthenticate.errorCode(), it.message ?: "")
}
}
result.success(isAuthenticated)
}
}

private fun explicitSignIn(activity: Activity?) {
fun signIn(activity: Activity?, result: MethodChannel.Result) {
activity ?: return
val signInOption = GoogleSignInOptions.Builder(
GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN
)
.requestEmail()

signInOption.requestScopes(Drive.SCOPE_APPFOLDER)

googleSignInClient = GoogleSignIn.getClient(activity, signInOption.build())
activity.startActivityForResult(googleSignInClient?.signInIntent, RC_SIGN_IN)
val gamesSignInClient = PlayGames.getGamesSignInClient(activity)
pendingOperation = PendingOperation(Method.SignIn.value(), result, activity)
gamesSignInClient.signIn().addOnSuccessListener {
it?.let { result -> Log.i("PlayService", "isAuthenticated: ${result.isAuthenticated} toString: $result") }
handleSignInResult(activity)
}.addOnFailureListener {
it.let { result -> Log.i("PlayService", "isAuthenticated: ${result.localizedMessage} toString: $result") }
finishPendingOperationWithError(PluginError.FailedToAuthenticate.errorCode(), it.message ?: "")
}
}

private fun handleSignInResult(activity: Activity?) {
activity ?: return

finishPendingOperationWithSuccess()
}

fun signOut(result: MethodChannel.Result) {
googleSignInClient?.signOut()?.addOnCompleteListener { task ->
if (task.isSuccessful) {
result.success(null)
} else {
result.error(PluginError.FailedToSignOut.errorCode(), task.exception?.localizedMessage, null)
}
}
}

//region PendingOperation
private fun finishPendingOperationWithSuccess() {
Log.i(pendingOperation?.method, "success")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,12 @@ class GamesServicesPlugin : FlutterPlugin,
return
}
when (method) {
Method.SilentSignIn -> {
val shouldEnableSavedGame = call.argument<Boolean>("shouldEnableSavedGame") ?: false
auth.silentSignIn(activity, shouldEnableSavedGame, result)
Method.SignIn -> {
auth.signIn(activity, result)
}
Method.IsSignedIn -> {
auth.isSignedIn(activity, result)
}
Method.SignOut -> {
auth.signOut(result)
}
Method.ShowAchievements -> {
achievements?.showAchievements(activity, result)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package com.abedalkareem.games_services.models

enum class Method {
Unlock, Increment, SubmitScore, ShowLeaderboards, ShowAchievements,
LoadAchievements, SilentSignIn, IsSignedIn, GetPlayerID, GetPlayerName,
GetPlayerHiResImage, GetPlayerIconImage, GetPlayerScore, SignOut,
SaveGame, LoadGame, GetSavedGames, DeleteGame, LoadLeaderboardScores
LoadAchievements, SignIn, IsSignedIn, GetPlayerID, GetPlayerName,
GetPlayerHiResImage, GetPlayerIconImage, GetPlayerScore, SaveGame,
LoadGame, GetSavedGames, DeleteGame, LoadLeaderboardScores
}

fun Method.value(): String {
Expand Down
11 changes: 1 addition & 10 deletions games_services/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ class AppState extends State<App> {
onPressed: _isSignedIn,
child: const Text('Is signedIn'),
),
ElevatedButton(
onPressed: _signOut,
child: const Text('Is signOut'),
),
ElevatedButton(
onPressed: _showAchievements,
child: const Text('Show Achievements'),
Expand Down Expand Up @@ -133,7 +129,7 @@ class AppState extends State<App> {
}

void _signIn() async {
final result = await GameAuth.signIn(shouldEnableSavedGame: true);
final result = await GameAuth.signIn();
print(result);
}

Expand All @@ -142,11 +138,6 @@ class AppState extends State<App> {
print(result);
}

void _signOut() async {
final result = await GameAuth.signOut();
print(result);
}

void _getPlayerID() async {
final result = await Player.getPlayerID();
print(result);
Expand Down
14 changes: 2 additions & 12 deletions games_services/lib/src/game_auth.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,14 @@ import 'package:games_services_platform_interface/game_services_platform_interfa

abstract class GameAuth {
/// To sign in the user.
/// If you pass [shouldEnableSavedGame], a drive scope will be will be added to GoogleSignInOptions. This will happed just
/// android as for iOS/macOS nothing is required to be sent when authenticate.
/// You need to call the sign in before making any action,
/// (like sending a score or unlocking an achievement).
static Future<String?> signIn({bool shouldEnableSavedGame = false}) async {
return await GamesServicesPlatform.instance
.signIn(shouldEnableSavedGame: shouldEnableSavedGame);
static Future<String?> signIn() async {
return await GamesServicesPlatform.instance.signIn();
}

/// Check to see if the user is currently signed into
/// Game Center or Google Play Services
static Future<bool> get isSignedIn async =>
await GamesServicesPlatform.instance.isSignedIn ?? false;

/// To sign the user out of Goole Play Services.
/// After calling, you can no longer make any actions
/// on the user's account.
static Future<String?> signOut() async {
return await GamesServicesPlatform.instance.signOut();
}
}
15 changes: 3 additions & 12 deletions games_services/lib/src/games_services.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,15 @@ export 'package:games_services_platform_interface/models.dart';
/// [SaveGame] for anything related to save game.
class GamesServices {
/// To sign in the user.
/// If you pass [shouldEnableSavedGame], a drive scope will be will be added to GoogleSignInOptions. This will happed just
/// android as for iOS/macOS nothing is required to be sent when authenticate.
/// You need to call the sign in before making any action,
/// (like sending a score or unlocking an achievement).
static Future<String?> signIn({bool shouldEnableSavedGame = false}) async {
return await GameAuth.signIn(shouldEnableSavedGame: shouldEnableSavedGame);
static Future<String?> signIn() async {
return await GameAuth.signIn();
}

/// Check to see if the user is currently signed into
/// Game Center or Google Play Services
static Future<bool> get isSignedIn async => await GameAuth.isSignedIn;

/// To sign the user out of Goole Play Services.
/// After calling, you can no longer make any actions
/// on the user's account.
static Future<String?> signOut() async {
return await GameAuth.signOut();
}
static Future<bool> get isSignedIn => GameAuth.isSignedIn;

/// It will open the achievements screen.
static Future<String?> showAchievements() async {
Expand Down
11 changes: 6 additions & 5 deletions games_services/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ packages:
games_services_platform_interface:
dependency: "direct main"
description:
name: games_services_platform_interface
sha256: c71f484e38f7ed4126d4b2314ca8040422947a86b71c7fa52d3d13a5dbd6aef8
url: "https://pub.dev"
source: hosted
version: "3.0.3"
path: games_services_platform_interface
ref: finish-v2-migration
resolved-ref: a5b889fc5da889649318f7f237237cedc79f00b0
url: "https://github.com/theLee3/games_services.git"
source: git
version: "3.1.0"
lints:
dependency: transitive
description:
Expand Down
8 changes: 6 additions & 2 deletions games_services/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: games_services
description: A new Flutter plugin to support game center and google play games services.
version: 3.0.3
version: 4.0.0
homepage: https://github.com/Abedalkareem/games_services
repository: https://github.com/Abedalkareem/games_services
issue_tracker: https://github.com/Abedalkareem/games_services/issues
Expand All @@ -13,9 +13,13 @@ dependencies:
flutter:
sdk: flutter

games_services_platform_interface: ^3.0.3
games_services_platform_interface: # ^4.0.0
# path: ../games_services_platform_interface/
# uncomment in time of development.
git:
url: https://github.com/theLee3/games_services.git
ref: finish-v2-migration
path: games_services_platform_interface

dev_dependencies:
flutter_lints: ^2.0.1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,25 +102,16 @@ abstract class GamesServicesPlatform extends PlatformInterface {
throw UnimplementedError("not implemented.");

/// To sign in the user.
/// If you pass [shouldEnableSavedGame], a drive scope will be will be added to GoogleSignInOptions. This will happed just
/// android as for iOS/macOS nothing is required to be sent when authenticate.
/// You need to call the sign in before making any action,
/// (like sending a score or unlocking an achievement).
Future<String?> signIn({bool shouldEnableSavedGame = false}) async {
Future<String?> signIn() async {
throw UnimplementedError("not implemented.");
}

/// Check to see if the user is currently signed into
/// Game Center or Google Play Services
Future<bool?> get isSignedIn => throw UnimplementedError("not implemented.");

/// To sign the user out of Google Play Services.
/// After calling, you can no longer make any actions
/// on the user's account.
Future<String?> signOut() async {
throw UnimplementedError("not implemented.");
}

/// Show the iOS Access Point.
Future<String?> showAccessPoint(AccessPointLocation location) async {
throw UnimplementedError("not implemented.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,8 @@ class MethodChannelGamesServices extends GamesServicesPlatform {
}

@override
Future<String?> signIn({bool shouldEnableSavedGame = false}) async {
if (Device.isPlatformAndroid) {
return await _channel.invokeMethod(
"silentSignIn", {"shouldEnableSavedGame": shouldEnableSavedGame});
} else {
return await _channel.invokeMethod("signIn");
}
Future<String?> signIn() async {
return await _channel.invokeMethod("signIn");
}

@override
Expand Down Expand Up @@ -119,11 +114,6 @@ class MethodChannelGamesServices extends GamesServicesPlatform {
.invokeMethod("playerIsPersonalizedCommunicationRestricted");
}

@override
Future<String?> signOut() async {
return await _channel.invokeMethod("signOut");
}

@override
Future<String?> showAccessPoint(AccessPointLocation location) async {
return await _channel.invokeMethod(
Expand Down
2 changes: 1 addition & 1 deletion games_services_platform_interface/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: games_services_platform_interface
description: A common platform interface for the games_services plugin.
homepage: https://github.com/Abedalkareem/games_services
version: 3.0.3
version: 4.0.0

environment:
sdk: '>=2.12.0 <4.0.0'
Expand Down

0 comments on commit 242cb06

Please sign in to comment.