[Unity3D] Google Play Games Plugin에서 ERROR_NOT_AUTHORIZED 에러가 발생할 때

Google Play Games Plugin을 Unity에 붙이고 로그인을 시도하면 ERROR_NOT_AUTHORIZED 에러가 발생하면서 로그인이 안되는 경우가 있습니다.

이 문제는 Google Play Console의 설정을 제대로 하지 않은 경우게 발생합니다.

문제 해결을 위해서 두가지를 확인해야 합니다.

첫번째는 Unity에서 GPGS의 설정입니다.

  1. Unity에서 <Window-Google Play Games-Setup-Android setup...> 메뉴를 선택합니다.

  2. 아래와 같은 창이 뜹니다. 이 창의 항목들을 설정해 줘야 합니다.

  3. Directory to save constant, Constants class name은 적당하게 입력해 줍니다.
    Directory to save constant : Resource Definition 에 정의된 값들을 저장한 C# 파일을 생성할 폴더 위치
    Constants class name : Resource Definition에 정의된 값들을 저장한 C# Class의 이름
  4. Resources Definition은 Google Play Console에서 가져옵니다.
    업적, 이벤트 중 하무거나 하나 추가하고나면 '리소스 받기' 메뉴가 나타납니다. 업적과 이벤트를 하나도 추가하지 않고 받아올 수도 있을텐데 버튼이 등장하지 않네요.

  5. Web App Client ID는 입력을 해도 되고 안해도 되는 부분인데 Firebase나 외부 로그인 모듈을 사용하려면 입력해 줍니다.

두번째는 Google Play Console의 설정입니다.

  1. Google Play Console API 사이트에 접속합니다.
    https://console.developers.google.com
  2. OAuth 2.0 클라이언트 ID에서 Android 클라이언트 정보가 있는지 확인해 봅니다.
    (아마 별다른 셋팅이 없었다면 없을 겁니다.)

  3. '사용자 인증 정보 만들기' 를 클릭하고 'OAuth 클라이언트 ID'를 선택합니다.

  4. 아래와 같은 화면이 있고 '서명 인증서 지문' 과 '패키지 이름'을 입력해야 합니다.

  5. Google Play Console의 프로젝트에서 SHA-1 인증서 지문을 복사하여 4번 항목의 '서명 인증서 지문' 부분에 붙여넣습니다.

    만약 인증서를 업로드 하라거나 어쩌구 메시지가 뜨면 APK를 빌드할 때 사용한 key store를 등록해야 합니다. 관련 정보는 해당 메뉴의 도움말을 참고하세요.
    업로드 인증서를 실수로 입력하는 경우가 많으니 주의!

4번 항목의 '패키지 이름'은 Unity에서 APK를 빌드할 때 사용한 것을 넣어줍니다.

위의 두가지가 조금이라도 잘못 설정되어 있으면 로그인이 제대로 안됩니다.

[Unity3D] Google Play Games Plugin에서 ERROR_NOT_AUTHORIZED 오류로 로그인 실패 또는 IdToken 받아오기 실패

Unity에서 Google 로그인을 구현하기 위해서는 Google Play Games Service Plugin(gpgs)을 사용해야 합니다.

저는 Firebase를 통해서 Google Play, Facebook, Guest 로그인을 구현하는 과정이었고, Firebase에서 Google Play 인증을 위해서는 Google Play에서 IdToken을 받아서 Firebase 인증 모듈에 전달해줘야 합니다.

처음 만난 문제는 gpgs에서 로그인은 성공하여 Social.localUser.id 정보는 들어 있지만 IdToken, Email, ServerAuthCode 등의 정보는 비어있어서 Firebase에 인증 정보를 넘길 수 없었습니다.

이때의 gpgs 초기화 코드는 아래의 상태였습니다.

// GPG를 Activate()하면 Social.localUser가 GPG의 계정 정보로 설정됨
// 안드로이드 빌더 초기화
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
    .RequestServerAuthCode(false)
    .RequestIdToken()
    .RequestEmail()
    .Build();

PlayGamesPlatform.InitializeInstance(config);

// 구글 플레이 로그를 확인할려면 활성화
PlayGamesPlatform.DebugLogEnabled = true;

// 구글 플레이 활성화
PlayGamesPlatform.Activate();

분명히 config를 통해서 RequestIdToken()을 호출하여 요청을 추가하였음에도 불구하고 IdToken 항목이 비어있었습니다.

Unity Log를 확인한 것으로는 원인을 찾을 수 없었고, Android Studio의 Logcat으로 디바이스 로그를 확인하던 중 이상한 부분을 발견할 수 있었습니다.

06-11 22:50:17.497 7610-7663/? I/Unity: Try google play login
06-11 22:50:17.510 7610-7663/? I/Unity: Starting Auth with token client.
06-11 22:50:17.563 7610-7663/? W/Unity: !!! [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 WARNING: Creating new PlayGamesPlatform
 
 (Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/DebugBindings.gen.cpp Line: 51)
06-11 22:50:17.564 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 DEBUG: Activating PlayGamesPlatform.
06-11 22:50:17.565 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 DEBUG: PlayGamesPlatform activated: GooglePlayGames.PlayGamesPlatform
06-11 22:50:17.566 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 DEBUG: Activating PlayGamesPlatform.
06-11 22:50:17.567 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 DEBUG: PlayGamesPlatform activated: GooglePlayGames.PlayGamesPlatform
06-11 22:50:17.568 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 DEBUG: Creating platform-specific Play Games client.
 [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 DEBUG: Creating Android IPlayGamesClient Client
06-11 22:50:17.578 7610-7663/? D/TokenFragment: Creating fragment
06-11 22:50:17.579 7610-7610/? D/TokenFragment: onStart()
06-11 22:50:17.585 7610-7610/? D/TokenFragment: onResume called
 Building client for: a98c718 (a:false e:true i:true wc: 619017498880-4eeh5dlhl8jso58368gv4tf0s2qs4s8i.apps.googleusercontent.com f: false)
06-11 22:50:17.587 7610-7663/? I/Unity: ---- [0] -- 105
06-11 22:50:17.592 7610-7610/? W/PopupManager: You have not specified a View to use as content view for popups. Falling back to the Activity content view. Note that this may not work as expected in multi-screen environments
06-11 22:50:17.617 5637-6375/? D/[WeatherGearO(220318052351)]: {[EF07ED23AAA1263A1FC0BD061AAAD81CFEF15A971ABD51417EE09B7660DD4FB818A9462C7397822725FFF2738B19ADA7]}
06-11 22:50:17.648 7610-7610/? D/TokenFragment: No connected Games API
06-11 22:50:17.649 7610-7610/? E/TokenFragment: Setting result error code to: 13
06-11 22:50:17.653 5637-5637/? D/[WeatherGearO(220318052351)]: {[20CE3D41AD5C8B99E86585ABAB0BF03E702BEB2FC2CA5F53D66FB562B77F4529B627A611ACF593EFCAECBBA4E800B8A9081BC429F8CCD72700680F6A1D6A48CC]}
06-11 22:50:17.657 5637-5637/? D/[WeatherGearO(220318052351)]: {[E5B16E2CDC4F169AEF5B4319C5BDF7110156A5C36B5B4FD8C066ADFAD237FF3B8D85C1771AE8244AE78CE8BB9C6079741D01C71F84AB90238AB7DED8E9D360BC]}
06-11 22:50:17.658 5637-5637/? D/[WeatherGearO(220318052351)]: {[E5B16E2CDC4F169AEF5B4319C5BDF711320D5E9C4351D1F5E6CB8FF1DF59CF2C64BE1F0F10EBA2467C1DD93AB2A27A40A65FAEFDFFB43F75B64AAEDA7C3A5B59]}
06-11 22:50:17.659 5637-5637/? D/[WeatherGearO(220318052351)]: {[20CE3D41AD5C8B99E86585ABAB0BF03EE5160ED4AAE0971C0D182570D628C6CD0253855F5B1B3CDBA2912A6CEF37A6C4]}
06-11 22:50:17.668 5637-5637/? D/[WeatherGearO(220318052351)]: {[20CE3D41AD5C8B99E86585ABAB0BF03E856D7DF2593883BBCF72D0E06237841289C8E379B2D1A1A78B856DF6D06ACDC0]}
06-11 22:50:17.672 5637-5637/? D/[SA_SDK]SAAgent: SAAgent - onDestroy:SAWeather_Service
06-11 22:50:17.673 5637-6370/? W/[SA_SDK]SAAgent: Performing agent cleanup
06-11 22:50:17.673 5637-6370/? I/[SA_SDK]SASocket: Connection is already closed
06-11 22:50:17.675 5637-5637/? D/[WeatherGearO(220318052351)]: {[EF07ED23AAA1263A1FC0BD061AAAD81CA3F446FA4E808076CF16D0F746E839D242804AFF8476C203988BABCD46197438]}
06-11 22:50:17.676 5637-6370/? I/[SA_SDK]SAAgent: Agent ID retrieved successfully for com.samsung.accessory.saweather.service.SAWeather_Service Agent ID:37723
06-11 22:50:17.676 5909-5947/? I/SAFrameworkConnection: Clean up fwk connection agentId:37723 com.samsung.android.gearoplugin
06-11 22:50:17.680 5909-6078/? V/SAFrameworkConnection: Removed incremental update callback for:/system/weather2_0
06-11 22:50:17.680 5637-6370/? D/[SA_SDK]SAAdapter: Agent callback removed. Current size - 10
06-11 22:50:17.685 7610-7610/? D/TokenPendingResult: Calling onResult for callback: GooglePlayGames.Android.TokenResultCallback result: Status: Status{statusCode=ERROR, resolution=null} email: <null> id:<null> access: <null>
06-11 22:50:17.708 5173-30288/? I/AuthChimeraService: Executing send connection operation
06-11 22:50:17.715 5173-28166/? W/FirebaseAuth: [PhoneNumberAuthPostProcessor] postProcess starts
 [PhoneNumberAuthPostProcessor] postProcess ends
06-11 22:50:17.716 7610-7858/? D/FirebaseAuth: Notifying id token listeners about user ( tY2DUCs391aFgwIVLufabvlvSwP2 ).
06-11 22:50:17.732 7610-7610/? D/GamesUnitySDK: Performing Android initialization of the GPG SDK
06-11 22:50:17.771 7610-7610/? I/Unity: Building GPG services, implicitly attempts silent auth
06-11 22:50:17.773 7610-7610/? I/GamesNativeSDK: Using existing jar.
06-11 22:50:17.776 7610-7610/? I/GamesNativeSDK: Writing 1941 bytes to jar file
06-11 22:50:17.779 7610-7610/? W/zygote: Skipping duplicate class check due to unrecognized classloader
06-11 22:50:17.784 7610-7610/? I/GamesNativeSDK: Using existing jar.
 Writing 1066 bytes to jar file
06-11 22:50:17.787 7610-7610/? W/zygote: Skipping duplicate class check due to unrecognized classloader
06-11 22:50:17.793 7610-7610/? W/PopupManager: You have not specified a View to use as content view for popups. Falling back to the Activity content view. Note that this may not work as expected in multi-screen environments
06-11 22:50:17.794 7610-7897/? I/GamesNativeSDK: Auth operation started: SIGN IN
 Connecting to Google Play...
06-11 22:50:17.814 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 DEBUG: Starting Auth Transition. Op: SIGN_IN status: 13
06-11 22:50:17.815 7610-7610/? D/TokenFragment: Done with processRequest, result is pending.
06-11 22:50:17.815 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 DEBUG: Invoking callbacks, AuthState changed from silentPending to Unauthenticated.
06-11 22:50:17.816 7610-7610/? D/FirebaseApp: Notifying auth state listeners.
 Notified 0 auth state listeners.
06-11 22:50:17.850 5173-10655/? W/GamesServiceBroker: Client connected with SDK 12211000, Services 12685025, and Games 59040048
06-11 22:50:17.850 5173-5886/? W/GamesServiceBroker: Client connected with SDK 12211000, Services 12685025, and Games 59040048
06-11 22:50:17.861 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:17 +09:00 DEBUG: there are pending auth callbacks - starting AuthUI
06-11 22:50:17.880 7610-7663/? I/Unity: Token[0:8] = eyJhbGci
06-11 22:50:17.909 5173-3007/? W/GamesServiceBroker: Client connected with SDK 13004000, Services 12685025, and Games 59040048
06-11 22:50:17.974 5173-7898/? I/AsyncOpDispatcher: 44-AuthAccountWithNoServerAuthCallback
06-11 22:50:18.085 5112-8279/? I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
06-11 22:50:18.181 3254-3254/? I/android.hardware.wifi@1.0-service: getLinkLayerStats
06-11 22:50:18.200 3788-3811/? D/StorageManagerService: getExternalStorageMountMode : 2
06-11 22:50:18.201 3788-3811/? D/StorageManagerService: getExternalStorageMountMode : 3
06-11 22:50:18.208 3788-3811/? D/StorageManagerService: getExternalStorageMountMode : final mountMode=2, uid : 10220, packageName : com.skt.prod.phonebook
06-11 22:50:18.217 3788-3811/? I/ApplicationPolicy: isApplicationExternalStorageWhitelisted:com.skt.prod.phonebook user:0
06-11 22:50:18.217 3788-3811/? D/ApplicationPolicy: isApplicationExternalStorageWhitelisted: DO is not enabled on user 0. Allowed.
06-11 22:50:18.217 3788-3811/? D/ActivityManager: package com.skt.prod.phonebook, user - 0 is SDcard whitelisted
06-11 22:50:18.217 3788-3811/? I/ApplicationPolicy: isApplicationExternalStorageBlacklisted:com.skt.prod.phonebook user:0
06-11 22:50:18.217 3788-3811/? D/ApplicationPolicy: isApplicationExternalStorageBlacklisted: DO is not enabled on user 0. Allowed.
06-11 22:50:18.241 5112-8279/? W/Auth: [GetToken] GetToken failed with status code: NeedPermission
06-11 22:50:18.257 3788-3811/? W/ActivityManager: Slow operation: 60ms so far, now at startProcess: returned from zygote!
 Slow operation: 60ms so far, now at startProcess: done updating battery stats
06-11 22:50:18.258 3788-3811/? W/ActivityManager: Slow operation: 60ms so far, now at startProcess: building log message
06-11 22:50:18.258 3788-3811/? I/ActivityManager: Start proc 7899:com.skt.prod.phonebook/u0a220 for service com.skt.prod.phonebook/.sync.SyncManagerService
06-11 22:50:18.258 3788-3811/? W/ActivityManager: Slow operation: 61ms so far, now at startProcess: starting to update pids map
 Slow operation: 61ms so far, now at startProcess: done updating pids map
 Slow operation: 63ms so far, now at startProcess: done starting proc!
06-11 22:50:18.260 7899-7899/? E/Zygote: isWhitelistProcess - Process is Whitelisted
06-11 22:50:18.273 7899-7899/? W/SELinux: SELinux selinux_android_compute_policy_index : Policy Index[2], Con:u:r:zygote:s0 RAM:SEPF_SM-G950N_8.0.0_0005, [-1 -1 -1 -1 0 1]
06-11 22:50:18.276 7899-7899/? I/SELinux: SELinux: seapp_context_lookup: seinfo=trustonicpartner, level=s0:c512,c768, pkgname=com.skt.prod.phonebook 
06-11 22:50:18.301 5173-7321/? W/Auth: [GoogleAuthUtil] GoogleAuthUtil
06-11 22:50:18.326 5173-3007/? W/GamesServiceBroker: Client connected with SDK 13004000, Services 12685025, and Games 59040048
06-11 22:50:18.330 7610-7610/? I/TokenFragment: onConnected called
06-11 22:50:18.339 3788-4468/? I/ClientCertificateManager Service: fixContextInfoForMP() returning Caller uid: 10220 ,Container id: 0
 fixContextInfoForMP() returning Caller uid: 10220 ,Container id: 0
 ClientCertificateManager.isPremiumContainer() : false for user : 0
06-11 22:50:18.341 5173-3007/? W/GamesServiceBroker: Client connected with SDK 13004000, Services 12685025, and Games 59040048
06-11 22:50:18.355 3788-4622/? I/ClientCertificateManager Service: fixContextInfoForMP() returning Caller uid: 10220 ,Container id: 0
06-11 22:50:18.356 3788-4622/? I/ClientCertificateManager Service: fixContextInfoForMP() returning Caller uid: 10220 ,Container id: 0
 ClientCertificateManager.isPremiumContainer() : false for user : 0
06-11 22:50:18.371 7899-7899/? D/ActivityThread: Added TimaKeyStore provider
06-11 22:50:18.372 5173-7898/? I/AsyncOpDispatcher: 44-AuthAccountWithNoServerAuthCallback
06-11 22:50:18.375 3788-4323/? I/ActivityManager: DSS on for com.skt.prod.phonebook and scale is 1.0
06-11 22:50:18.457 3788-4323/? W/AppOps: Bad call: specified package com.google.android.play.games under uid 10382 but it is really 10250
 java.lang.RuntimeException: here
 at com.android.server.AppOpsService.getOpsRawLocked(AppOpsService.java:1402)
 at com.android.server.AppOpsService.checkPackage(AppOpsService.java:1106)
 at com.android.internal.app.IAppOpsService$Stub.onTransact(IAppOpsService.java:169)
 at android.os.Binder.execTransact(Binder.java:682)
06-11 22:50:18.487 7899-7916/? I/vndksupport: sphal namespace is not configured for this process. Loading /vendor/lib/egl/libGLES_mali.so from the current namespace instead.
06-11 22:50:18.525 5173-3007/? W/GamesServiceBroker: Client connected with SDK 13004000, Services 12685025, and Games 59040048
06-11 22:50:18.528 7899-7899/? D/FirebaseApp: com.google.firebase.auth.FirebaseAuth is not linked. Skipping initialization.
06-11 22:50:18.544 7899-7899/? D/FirebaseApp: com.google.firebase.crash.FirebaseCrash is not linked. Skipping initialization.
06-11 22:50:18.551 7899-7916/? D/libEGL: loaded /vendor/lib/egl/libGLES_mali.so
06-11 22:50:18.557 7899-7899/? I/FA: App measurement is starting up, version: 11020
 To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
06-11 22:50:18.571 7610-7610/? V/GamesNativeSDK: Play Games callback indicates connection.
06-11 22:50:18.593 7610-7897/? I/GamesNativeSDK: Successfully connected to Google Play.
06-11 22:50:18.598 7899-7899/? I/FA: To enable faster debug mode event logging run:
 adb shell setprop debug.firebase.analytics.app com.skt.prod.phonebook
06-11 22:50:18.604 3788-4323/? D/SamsungAlarmManager: Cancel Alarm calling from uid:10220 pid :7899 / op:PendingIntent{bddad2c: PendingIntentRecord{42e53f5 com.skt.prod.phonebook broadcastIntent}}
06-11 22:50:18.611 7899-7899/? I/FirebaseInitProvider: FirebaseApp initialization successful
06-11 22:50:18.619 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Starting Auth Transition. Op: SIGN_IN status: VALID
06-11 22:50:18.632 5173-10310/? I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
06-11 22:50:18.664 3788-4468/? D/ConnectivityService: filterNetworkStateForUid() uid: 10220 networkInfo: [type: WIFI[] - WIFI, state: CONNECTED/CONNECTED, reason: (unspecified), extra: "starter_5G", failover: false, available: true, roaming: false, metered: false]
06-11 22:50:18.674 3788-4468/? W/StorageManager: getStorageLowBytes lowPercent : 5, lowBytes : 2913012121, maxLowBytes : 524288000
06-11 22:50:18.679 3788-5348/? W/AppOps: Bad call: specified package com.google.android.play.games under uid 10382 but it is really 10250
 java.lang.RuntimeException: here
 at com.android.server.AppOpsService.getOpsRawLocked(AppOpsService.java:1402)
 at com.android.server.AppOpsService.checkPackage(AppOpsService.java:1106)
 at com.android.internal.app.IAppOpsService$Stub.onTransact(IAppOpsService.java:169)
 at android.os.Binder.execTransact(Binder.java:682)
06-11 22:50:18.680 3788-4468/? W/StorageManager: getStorageLowBytes lowPercent : 5, lowBytes : 2913012121, maxLowBytes : 524288000
06-11 22:50:18.681 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Entering internal callback for PlayerManager#InternalFetchSelfCallback
06-11 22:50:18.682 3788-4468/? W/AppOps: Bad call: specified package com.google.android.play.games under uid 10382 but it is really 10250
 java.lang.RuntimeException: here
 at com.android.server.AppOpsService.getOpsRawLocked(AppOpsService.java:1402)
 at com.android.server.AppOpsService.checkPackage(AppOpsService.java:1106)
 at com.android.internal.app.IAppOpsService$Stub.onTransact(IAppOpsService.java:169)
 at android.os.Binder.execTransact(Binder.java:682)
06-11 22:50:18.682 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Populating User
06-11 22:50:18.687 3788-4468/? W/StorageManager: getStorageLowBytes lowPercent : 5, lowBytes : 2913012121, maxLowBytes : 524288000
06-11 22:50:18.691 3788-4468/? W/StorageManager: getStorageLowBytes lowPercent : 5, lowBytes : 2913012121, maxLowBytes : 524288000
06-11 22:50:18.696 3788-4468/? W/AppOps: Bad call: specified package com.google.android.play.games under uid 10382 but it is really 10250
 java.lang.RuntimeException: here
 at com.android.server.AppOpsService.getOpsRawLocked(AppOpsService.java:1402)
 at com.android.server.AppOpsService.checkPackage(AppOpsService.java:1106)
 at com.android.internal.app.IAppOpsService$Stub.onTransact(IAppOpsService.java:169)
 at android.os.Binder.execTransact(Binder.java:682)
06-11 22:50:18.713 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Found User: [Player: 'PlayerID' (id g44786123847612328794)]
06-11 22:50:18.714 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Maybe finish for User
06-11 22:50:18.714 3788-4468/? W/StorageManager: getStorageLowBytes lowPercent : 5, lowBytes : 2913012121, maxLowBytes : 524288000
06-11 22:50:18.715 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Auth not finished. User=[Player: 'PlayerID' (id g44786123847612328794)] achievements=
06-11 22:50:18.719 3788-5348/? W/AppOps: Bad call: specified package com.google.android.play.games under uid 10382 but it is really 10250
 java.lang.RuntimeException: here
 at com.android.server.AppOpsService.getOpsRawLocked(AppOpsService.java:1402)
 at com.android.server.AppOpsService.checkPackage(AppOpsService.java:1106)
 at com.android.internal.app.IAppOpsService$Stub.onTransact(IAppOpsService.java:169)
 at android.os.Binder.execTransact(Binder.java:682)
06-11 22:50:18.720 3788-4468/? W/AppOps: Bad call: specified package com.google.android.play.games under uid 10382 but it is really 10250
 java.lang.RuntimeException: here
 at com.android.server.AppOpsService.getOpsRawLocked(AppOpsService.java:1402)
 at com.android.server.AppOpsService.checkPackage(AppOpsService.java:1106)
 at com.android.internal.app.IAppOpsService$Stub.onTransact(IAppOpsService.java:169)
 at android.os.Binder.execTransact(Binder.java:682)
06-11 22:50:18.748 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Entering internal callback for AchievementManager#InternalFetchAllCallback
06-11 22:50:18.749 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Populating Achievements, status = VALID
06-11 22:50:18.793 7899-7899/? W/Notification: Use of stream types is deprecated for operations other than volume control
 See the documentation of setSound() for what to use instead with android.media.AudioAttributes to qualify your playback use case
06-11 22:50:18.814 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Found 1 Achievements
06-11 22:50:18.815 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Maybe finish for Achievements
06-11 22:50:18.816 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Auth finished. Proceeding.
06-11 22:50:18.817 7610-7663/? I/Unity: [Play Games Plugin DLL] 06/11/18 22:50:18 +09:00 DEBUG: Invoking Callbacks: System.Action`2[System.Boolean,System.String]
06-11 22:50:18.820 7610-7663/? I/Unity: Gpgs authenticate success.

위의 로그에서 아래의 한줄을 발견할 수 있었습니다.

06-11 22:50:18.241 5112-8279/? W/Auth: [GetToken] GetToken failed with status code: NeedPermission

Permission이라는 힌트를 가지고 두가지 해결방법을 검색해 볼 수 있었습니다.

첫번째는 AndroidManifest.xml 파일에
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
권한을 추가해서 해결이 되었다는 내용이었습니다만 이걸로는 해결되지 않았습니다.

두번째는 config에 AddOauthScope를 추가해 보라는 내용이었고 이걸으로 해결할 수 있었습니다.
이 해결책을 보고 AddOauthScope 함수의 선언부를 보았더니 아래와 같은 주석이 달려 있었습니다.

/// <summary>
/// Requests an Oauth scope from the user.
/// </summary>
/// <remarks>
/// Not setting one will default to 'games_lite' and will not show a consent
/// dialog to the user. Valid examples are 'profile' and 'email'.
/// Full list: https://developers.google.com/identity/protocols/googlescopes
/// To exchange the auth code with an id_token (or user id) on your server,
/// you must add at least one scope.
/// </remarks>
/// <returns>The builder.</returns>
public Builder AddOauthScope(string scope)
{
    if (mScopes == null) mScopes = new List<string>();
    mScopes.Add(scope);
    return this;
}

아무것도 설정하지 않을경우 'games_lite' 라는 scope가 설정된다고 하는데... 주석에 달려 있는 링크를 따라가보니 games_lite라는 scope는 존재하지 않았습니다.

https://developers.google.com/identity/protocols/googlescopes

그래서 위 링크에 있는 scope에서 Google Play Game Service와 관련된 scope를 추가하여 초기화 코드를 아래와 같이 수정하였습니다.

// GPG를 Activate()하면 Social.localUser가 GPG의 계정 정보로 설정됨
// 안드로이드 빌더 초기화
PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
    .AddOauthScope("profile")
    .AddOauthScope("email")
    .AddOauthScope("https://www.googleapis.com/auth/games")
    .AddOauthScope("https://www.googleapis.com/auth/plus.login")
    .RequestServerAuthCode(false)
    .RequestIdToken()
    .RequestEmail()
    .Build();
PlayGamesPlatform.InitializeInstance(config);

// 구글 플레이 로그를 확인할려면 활성화
PlayGamesPlatform.DebugLogEnabled = true;

// 구글 플레이 활성화
PlayGamesPlatform.Activate();

이 코드를 통해서 해결하긴 했는데... 문제는 이 코드를 수정한 업데이트를 디바이스에 적용하고 즉시 수정되진 않고 또다른 에러가 발생하면서 로그인에 실패합니다.

이제는 Unity Log에서도 볼 수 있는 ERROR_NOT_AUTHORIZED 에러가 발생하게 됩니다. 이 경우에 캐싱된 로그인 정보를 강제로 SignOut 처리를 해준 후 다시 로그인을 시도하거나 게임을 삭제 후 다시 설치하여 실행하면 됩니다.

그러면 Google Play 로그인과 함께 권한을 물어보는 윈도우가 열리게 되고 허용을 선택하면 로그인에 성공하게 됩니다.

Document랑 예제 좀 탄탄하게 정리해주면 안되나...