Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android.Gms.PlayGames.GetPlayersClient and PlayersClient API Missing from Xamarin.GooglePlayServices.Games.V2 #975

Open
stuartmilleruk opened this issue May 8, 2023 · 11 comments
Labels
missing-api Java types/members not available in binding

Comments

@stuartmilleruk
Copy link

stuartmilleruk commented May 8, 2023

Xamarin.Android Version (eg: 6.0): net7.0-android32

Operating System & Version (eg: Mac OSX 10.11): MacOS Ventura 13.1

Google Play Services Version

  • Xamarin.GooglePlayServices.Base : 118.1.0.2
  • Xamarin.GooglePlayServices.Games.V2 : 117.0.0.1

Describe your Issue

Some of the Google PlayGames V2 API appears to be missing in the nuget packages, which makes it tricky to support basic usage of the PlayGames V2 API. The main issue is that there doesn't appear to be any binding for the PlayersClient part of the API, which means there's no way of getting the players display name or any information about the currently signed in player.

My main use-case is : If a user changes their Google Play profile in the OS Settings, there doesn't seem to be a way to identify that the player that is now automatically signed in by the app with PlayGames.V2 is different or has changed... so there's no way for the app to, for example, invalidate any cached data that was in-use with a previous PlayGames user.

As an example, the Google PlayGames V2 docs show one usage that doesn't appear to be possible with Xamarin, because there's no getPlayersClient call available ( unlike, for example, the GetAchievementsClient() call which is exposed ). Having that API available would make my particular use case possible.

PlayGames.getPlayersClient(activity).getCurrentPlayer().addOnCompleteListener(mTask -> {
    // Get PlayerID with mTask.getResult().getPlayerId()
  }
);

( taken from : Play Games v2 Sign in Documentation )

Are there any plans to add this functionality, or is there a workaround that can be used to identify the user or extract this information? I'm not too familiar with the way Xamarin binds to the platform api's so haven't been able to add this functionality successfully myself yet.

@pekspro
Copy link

pekspro commented Sep 12, 2023

I'm also missing this.

@stuartmilleruk
Copy link
Author

@pekspro were you able to find a workaround for this? I'm now coming back around to this issue hoping there might have been a fix or a workaround, but there doesn't seem to have been any movement on it so far.

@jpobst If this is something we'd be able to add to the binding, then any information on how would be great. I'm not sure how the bindings are generated for the GooglePlayServicesComponent, but if it's just a case of inserting some metadata for the function somewhere and rebuilding, then it might be something I could do.

@pekspro
Copy link

pekspro commented Dec 27, 2023

@stuartmilleruk, thanks, no I did not found any workaround for this issue. A solution for this and #972 woule be highly appreciated :-)

@stuartmilleruk
Copy link
Author

I've recently come back onto this task as I didn't make any progress figuring out how to add new endpoints and noticed a new version of the GooglePlayServices bindings were released ( but still missing the bindings to get the current player to know who is signed in or if the user has changed whilst the app is suspended )

@pekspro Did you get any further or figure out a workaround?

@pekspro
Copy link

pekspro commented May 27, 2024

@stuartmilleruk, no, I'm still stuck on this. Also, the new version doesn't compile with .NET 8 for some reason :-(

@stuartmilleruk
Copy link
Author

@moljac I saw there was some progress with the other related task with the PlayGames.V2 bug @ #972

Do you know if the fix that's planned for that one will also fix this one and what the pull request was?

If not ( or even if it does ) ... I don't supposed you know of a workaround to get access the the PlayGames.V2 PlayerID? I pretty much just need access to that alone and I'm happy to use a workaround if there's a way of directly patching into the PlayGames.getPlayersClient().getCurrentPlayer().getPlayerID() call.

Just a bit stuck knowing where to start as I've not done any C# -> Java binding, or if there's some sort of Reflection API available in .NET C# for directly calling the Java platform APIs ( even if a bit hacky ).

@stuartmilleruk
Copy link
Author

stuartmilleruk commented Aug 11, 2024

So I started building and figuring out the bindings to see if I could make some progress with this, but not making a lot of progress mainly because I'm trying to figure out how the whole binding system works with Xamarin and I'm far from an expert ( games consoles, I'm an expert ... Xamarin Android, not so much yet! )

so far, I think the issue is related to these warnings when building the bindings ( i.e. dotnet cake -t=binderate followed by dotnet cake -t=nuget )

warning BG8801: Invalid parameter type 'com.google.android.gms.games.Player' for member 'Android.Gms.Games.IPlayersClient.GetCompareProfileIntent (Android.Gms.Games.IPlayer)'.
warning BG8503: Invalidating 'Android.Gms.Games.IPlayersClient' and all its nested types because some of its methods were invalid.
warning BG8701: Invalid return type 'com.google.android.gms.games.PlayersClient' for member 'Android.Gms.Games.PlayGames.GetPlayersClient (android.app.Activity)'.
warning BG8102: Class 'Android.Gms.Games.PlayerRef' has unknown base type 'com.google.android.gms.games.zzo'
warning BG8102: Class 'Android.Gms.Games.GameRef' has unknown base type 'com.google.android.gms.games.zzo'

I've got a hunch it all starts with that com.google.android.gms.games.zzo reference, but haven't figured out where it needs to be added or fixed up.

Looking in

play-services-basement/Transforms/Metdata.xml

I can see a line that says

<remove-node path="/api/package/class[contains(@name, 'zz') and @name != 'Api.zza' and @name != 'zzf' and @name != 'zzc' and @name != 'zzd' and @name != 'zza' and @name != 'zzg' and @name != 'zzb' and @name != 'zzp' and @name != 'zzbgl' and @name != 'zzs']" />

.. so I tried adding it there, but no change.

@moljac if you've got any tips on where to start and what I'm looking for, then that'd be awesome and would save me digging around. I'm happy to have a go at at least fixing up the PlayersClient bit ( as mentioned in previous post, I just need the getPlayersId() call to help me towards adhering to the google continuity requirements https://developer.android.com/games/playgames/continuity-requirements as well as the original issue of tracking when a user has changed ), but if I can figure out more then I'll obviously share back.

@stuartmilleruk
Copy link
Author

stuartmilleruk commented Aug 18, 2024

Continued trying to find my way around the binding system and I think I might have made some progress ( although it's slow without any docs! ).

Story so far..

Right now, I'm aiming to try to remove this error:

api.xml(406,6): Warning BG8503 : Invalidating 'Android.Gms.Games.IPlayer' and all its nested types because some of its methods were invalid.
Xamarin.Android.Bindings.Core.targets(99,5): Warning BG8503 : Invalidating 'Android.Gms.Games.IPlayer' and all its nested types because some of its methods were invalid.

With the thinking being that if I can solve that one, then maybe it will fix the errors related to com.google.android.gms.games.player being invalid like this one:

api.xml(606,10): Warning BG8801 : Invalid parameter type 'com.google.android.gms.games.Player' for member 'Android.Gms.Games.IPlayersClient.GetCompareProfileIntent (Android.Gms.Games.IPlayer)'.
Xamarin.Android.Bindings.Core.targets(99,5): Warning BG8801 : Invalid parameter type 'com.google.android.gms.games.Player' for member 'Android.Gms.Games.IPlayersClient.GetCompareProfileIntent (Android.Gms.Games.IPlayer)'.

Above the "Invalidating.." error, there were lots of errors referencing zzo,zzh and zza classes that were missing and after adding:

 <attr path="/api/package[@name='com.google.android.gms.games.internal.player']/class[@name='zza']" name="obfuscated">false</attr>
 <attr path="/api/package[@name='com.google.android.gms.games']/class[@name='zzo']" name="obfuscated">false</attr>
 <attr path="/api/package[@name='com.google.android.gms.games.internal']/class[@name='zzh']" name="obfuscated">false</attr>

to the Metadata.xml file of the play-services-games-v2 bindings I was able to get it down to this one error that was above that "Invaliding..." error line:

api.xml(435,8): Warning BG8700 : Unknown return type 'com.google.android.gms.games.internal.player.zza' for member 'Android.Gms.Games.IPlayer.Zzc ()'.
Xamarin.Android.Bindings.Core.targets(99,5): Warning BG8700 : Unknown return type 'com.google.android.gms.games.internal.player.zza' for member 'Android.Gms.Games.IPlayer.Zzc ()'.

And this is where I'm stuck.

I'm thinking that if I can just remove the bindings for that IPlayer::Zzc member, then maybe that'll be enough for now and I don't think I need it or most of this stuff. Looking in the api.xml file that's generated I can see this bit of binding

<interface abstract="true" deprecated="not deprecated" final="false" name="Player" static="false" visibility="public" jni-signature="Lcom/google/android/gms/games/Player;">
<method abstract="true" deprecated="not deprecated" final="false" name="zzc" jni-signature="()Lcom/google/android/gms/games/internal/player/zza;" bridge="false" native="false" return="com.google.android.gms.games.internal.player.zza" jni-return="Lcom/google/android/gms/games/internal/player/zza;" static="false" synchronized="false" synthetic="false" visibility="public" />

which i think is the line that it's got a problem with.

I can see you can put tags into the metadata.xml for the bindings, but I'm not sure how if or how I'd make a line that would strip that Zzc() method out.

I found this link

https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/troubleshooting-bindings/#Problem_Missing_C_types_in_generated_output in issue xamarin/GooglePlayServicesComponents#206

but the link is dead. I found an old version from back in 2018, though, but it didn't really get me any further.

Does anyone know if there's a way to strip this out? Or if there are any docs for any of this stuff?

@pekspro
Copy link

pekspro commented Aug 18, 2024

@stuartmilleruk, I have no useful information, and don't have any time to do any contribution. I just wanted to say I'm very, very impressed by your ambition 🙂.

@stuartmilleruk
Copy link
Author

stuartmilleruk commented Aug 18, 2024

@pekspro thanks :)

I've just figured out if I also add:

<remove-node path="/api/package[@name='com.google.android.gms.games']/interface[@name='Player']/method[contains(@name, 'zzc')]" />
<remove-node path="/api/package[@name='com.google.android.gms.games']/class[@name='PlayerEntity']/method[contains(@name, 'zzc')]" />
<remove-node path="/api/package[@name='com.google.android.gms.games']/class[@name='PlayerRef']/method[contains(@name, 'zzc')]" />

It stops the binding generator from removing the IPlayer and Player interfaces and generates the bindings for them ( or that's what I think it's done! ).

So I'm now into the .cs compilation phase of the bindings, but with lots and lots of errors which I'm now working through.

I'll update here again when I make some more progress. Currently I have no idea if any of this is actually going to work, of course or if I'm going on a wild goose chase.

@stuartmilleruk
Copy link
Author

Quick update... I've got the PlayerClient bindings to compile and work! I'm now able to get the PlayerId in my android app :)

Unfortunately, I've run out of time for today, but next week I'll prep a pull request with my changes in. It's going to be a bit complicated as I'm a few revisions behind ( I'm on commit 3b0d874 ) so it's going to take me a bit of time to clean things up and update.

@pekspro my changes also appear to have all the interfaces bound for the SnapshotClient too. But, I've barely tested the PlayersClient so have no idea if they work .. this is all very bleeding edge as of around 10 minutes ago.

If there's a quicker way to get the changes over that can make integration a bit faster, then let me know. I'm happy to just attach the changed files/diffs if it will speed up the process ( I'll be the first to admit, I'm more of a Perforce user than a git user so I've got to remember how to actually do a pull request on github again )

@jpobst jpobst transferred this issue from xamarin/GooglePlayServicesComponents Sep 23, 2024
@jpobst jpobst added the missing-api Java types/members not available in binding label Sep 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
missing-api Java types/members not available in binding
Projects
None yet
Development

No branches or pull requests

3 participants