Skip to content

Commit

Permalink
Added the automatic login function for Games (#2435)
Browse files Browse the repository at this point in the history
Co-authored-by: Marvin W <[email protected]>
  • Loading branch information
DaVinci9196 and mar-v-in authored Aug 22, 2024
1 parent fa879c0 commit 265f594
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 25 deletions.
1 change: 1 addition & 0 deletions play-services-core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@
android:theme="@style/Theme.App.DayNight.Dialog.Alert.NoActionBar">
<intent-filter>
<action android:name="com.google.android.gms.common.account.CHOOSE_ACCOUNT" />
<action android:name="com.google.android.gms.common.account.CHOOSE_ACCOUNT_USERTILE"/>

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class AssistedSignInFragment(
val allowAutoLoginAccounts = mutableListOf<Account>()
runCatching {
accounts.forEach { account ->
val authStatus = checkAppAuthStatus(requireContext(), clientPackageName, options, account)
val authStatus = checkAccountAuthStatus(requireContext(), clientPackageName, options.scopes, account)
if (authStatus) {
allowAutoLoginAccounts.add(account)
}
Expand Down Expand Up @@ -287,4 +287,4 @@ class AssistedSignInFragment(
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ fun getServerAuthTokenManager(context: Context, packageName: String, options: Go
return serverAuthTokenManager
}

suspend fun checkAppAuthStatus(context: Context, packageName: String, options: GoogleSignInOptions?, account: Account): Boolean {
val authManager = getOAuthManager(context, packageName, options, account)
suspend fun checkAccountAuthStatus(context: Context, packageName: String, scopeList: List<Scope>?, account: Account): Boolean {
val scopes = scopeList.orEmpty().sortedBy { it.scopeUri }
val authManager = AuthManager(context, account.name, packageName, "oauth2:${scopes.joinToString(" ")}")
authManager.ignoreStoredPermission = true
return withContext(Dispatchers.IO) { authManager.requestAuth(true) }.auth != null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package org.microg.gms.games

import android.accounts.Account
import android.accounts.AccountManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
Expand All @@ -17,6 +18,7 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.google.android.gms.common.Scopes
import com.google.android.gms.common.api.CommonStatusCodes
import com.google.android.gms.common.api.Scope
import com.google.android.gms.common.api.Status
import com.google.android.gms.common.internal.ConnectionInfo
import com.google.android.gms.common.internal.GetServiceRequest
Expand All @@ -26,8 +28,10 @@ import com.google.android.gms.games.internal.connect.GamesSignInResponse
import com.google.android.gms.games.internal.connect.IGamesConnectCallbacks
import com.google.android.gms.games.internal.connect.IGamesConnectService
import org.microg.gms.BaseService
import org.microg.gms.auth.AuthConstants
import org.microg.gms.auth.AuthManager
import org.microg.gms.auth.AuthPrefs
import org.microg.gms.auth.signin.checkAccountAuthStatus
import org.microg.gms.common.GmsService
import org.microg.gms.common.PackageUtils
import org.microg.gms.utils.warnOnTransactionIssues
Expand Down Expand Up @@ -61,8 +65,9 @@ class GamesConnectServiceImpl(val context: Context, override val lifecycle: Life
callback?.onSignIn(Status(CommonStatusCodes.SIGN_IN_REQUIRED, null, resolution), null)
}

1 -> { // Auto sign-in on start, don't provide resolution if not
callback?.onSignIn(Status(CommonStatusCodes.SIGN_IN_REQUIRED), null)
1 -> { // Automatically try to log in with a supported account at startup,
// and provide an account selection solution if verification fails
callback?.onSignIn(Status(CommonStatusCodes.SIGN_IN_REQUIRED, null, resolution), null)
}

else -> {
Expand All @@ -71,23 +76,45 @@ class GamesConnectServiceImpl(val context: Context, override val lifecycle: Life
}
}
lifecycleScope.launchWhenStarted {
try {
val account = request?.previousStepResolutionResult?.resultData?.getParcelableExtra<Account>(EXTRA_ACCOUNT)
val status = autoSelectLogin(request)
if (status) {
Log.d(TAG, "signIn success")
callback?.onSignIn(Status.SUCCESS, GamesSignInResponse().apply { gameRunToken = UUID.randomUUID().toString() })
} else {
sendSignInRequired()
}
}
}

private suspend fun autoSelectLogin(request: GamesSignInRequest?): Boolean {
runCatching {
var account = request?.previousStepResolutionResult?.resultData?.getParcelableExtra<Account>(EXTRA_ACCOUNT)
?: GamesConfigurationService.getDefaultAccount(context, packageName)
?: return@launchWhenStarted sendSignInRequired()
val authManager = AuthManager(context, account.name, packageName, "oauth2:${Scopes.GAMES_LITE}")
if (!authManager.isPermitted && !AuthPrefs.isTrustGooglePermitted(context)) return@launchWhenStarted sendSignInRequired()
val result = performGamesSignIn(context, packageName, account)
if (result) {
callback?.onSignIn(Status.SUCCESS, GamesSignInResponse().apply { gameRunToken = UUID.randomUUID().toString() })
} else {
sendSignInRequired()
}
} catch (e: Exception) {
Log.w(TAG, e)
return@launchWhenStarted sendSignInRequired()
Log.d(TAG, "autoSelectLogin signInType: ${request?.signInType} account: $account")
val autoLogin = if (account == null && request?.signInType == 1) {
val accounts = AccountManager.get(context).getAccountsByType(AuthConstants.DEFAULT_ACCOUNT_TYPE)
account = accounts.filter { targetAccount ->
checkAccountAuthStatus(context, packageName, arrayListOf(Scope(Scopes.GAMES_LITE)), targetAccount)
}.getOrNull(0)
true
} else {
false
}
if (account == null) {
Log.d(TAG, "autoSelectLogin Accounts is Empty")
return false
}
val authManager = AuthManager(context, account.name, packageName, "oauth2:${Scopes.GAMES_LITE}")
if (!authManager.isPermitted && !AuthPrefs.isTrustGooglePermitted(context)) return false
val performGamesSignInStatus = performGamesSignIn(context, packageName, account)
if (performGamesSignInStatus && autoLogin) {
GamesConfigurationService.setDefaultAccount(context, packageName, account)
}
return performGamesSignInStatus
}.onFailure {
Log.d(TAG, "autoSelectLogin fail", it)
}
return false
}

override fun onTransact(code: Int, data: Parcel, reply: Parcel?, flags: Int): Boolean =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class GamesServiceImpl(val context: Context, override val lifecycle: Lifecycle,
}

override fun signOut(callbacks: IGamesCallbacks?) {
Log.d(TAG, "Not yet implemented: signOut")
Log.d(TAG, "signOut called")
lifecycleScope.launchWhenStarted {
GamesConfigurationService.setDefaultAccount(context, packageName, null)
callbacks?.onSignOutComplete()
Expand All @@ -140,8 +140,8 @@ class GamesServiceImpl(val context: Context, override val lifecycle: Lifecycle,
}

override fun getCurrentAccountName(): String? {
Log.d(TAG, "Not yet implemented: getCurrentAccountName")
return null
Log.d(TAG, "getCurrentAccountName called: ${account.name}")
return account.name
}

override fun loadGameplayAclInternal(callbacks: IGamesCallbacks?, gameId: String?) {
Expand All @@ -161,8 +161,8 @@ class GamesServiceImpl(val context: Context, override val lifecycle: Lifecycle,
}

override fun getCurrentPlayerId(): String? {
Log.d(TAG, "Not yet implemented: getCurrentPlayerId")
return null
Log.d(TAG, "getCurrentPlayerId called: ${player.playerId}")
return player.playerId
}

override fun getCurrentPlayer(): DataHolder? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ interface IGamesService {
Intent getAchievementsIntent() = 9004;
Intent getPlayerSearchIntent() = 9009;

// void getSelectSnapshotIntent(String str, boolean z, boolean z2, int i) = 12001;
// void loadSnapshotsResult(IGamesCallbacks callbacks, boolean forceReload) = 12002;
void loadEvents(IGamesCallbacks callbacks, boolean forceReload) = 12015;
void incrementEvent(String eventId, int incrementAmount) = 12016;
// void discardAndCloseSnapshot(in Contents contents) = 12018;
Expand Down

0 comments on commit 265f594

Please sign in to comment.