Repo Created

This commit is contained in:
Fr4nz D13trich 2025-11-15 17:44:12 +01:00
parent eb305e2886
commit a8c22c65db
4784 changed files with 329907 additions and 2 deletions

View file

@ -0,0 +1,44 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply plugin: 'signing'
android {
namespace "com.google.android.gms.games"
compileSdkVersion androidCompileSdk
buildToolsVersion "$androidBuildVersionTools"
buildFeatures {
aidl = true
}
defaultConfig {
versionName version
minSdkVersion androidMinSdk
targetSdkVersion androidTargetSdk
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
apply from: '../gradle/publish-android.gradle'
description = 'microG implementation of play-services-games'
dependencies {
// Dependencies from play-services-games:23.1.0
api project(':play-services-base')
api project(':play-services-basement')
api project(':play-services-drive')
api project(':play-services-tasks')
annotationProcessor project(':safe-parcel-processor')
}

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ SPDX-FileCopyrightText: 2023 microG Project Team
~ SPDX-License-Identifier: Apache-2.0
-->
<manifest />

View file

@ -0,0 +1,3 @@
package com.google.android.gms.games;
parcelable PlayerEntity;

View file

@ -0,0 +1,9 @@
package com.google.android.gms.games.client;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.common.data.DataHolder;
interface IPlayGamesCallbacks {
void onData(in DataHolder dataHolder) = 1000;
void onStatus5028(in Status status) = 5027;
}

View file

@ -0,0 +1,14 @@
package com.google.android.gms.games.client;
import com.google.android.gms.games.client.IPlayGamesCallbacks;
import com.google.android.gms.games.client.PlayGamesConsistencyTokens;
interface IPlayGamesService {
void getGameCollection(IPlayGamesCallbacks callbacks, int maxResults, int gameCollectionType, boolean z, boolean forceReload) = 1000;
void loadGames(IPlayGamesCallbacks callbacks, String playerId, int maxResults, boolean z, boolean forceReload) = 1002;
PlayGamesConsistencyTokens getConsistencyTokens() = 5027;
void updateConsistencyTokens(in PlayGamesConsistencyTokens tokens) = 5028;
void fun5041(IPlayGamesCallbacks callbacks) = 5040;
}

View file

@ -0,0 +1,3 @@
package com.google.android.gms.games.client;
parcelable PlayGamesConsistencyTokens;

View file

@ -0,0 +1,52 @@
package com.google.android.gms.games.internal;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.common.data.DataHolder;
import com.google.android.gms.drive.Contents;
import com.google.android.gms.games.multiplayer.realtime.RealTimeMessage;
interface IGamesCallbacks {
/* @deprecated */ void onAuthTokenLoaded(int statusCode, String authToken) = 5000;
void onAchievementsLoaded(in DataHolder data) = 5001;
void onAchievementUpdated(int statusCode, String achievementId) = 5002;
void onLeaderboardsLoaded(in DataHolder data) = 5003;
void onLeaderboardScoresLoaded(in DataHolder leaderboard, in DataHolder scores) = 5004;
void onScoreSubmitted(in DataHolder data) = 5005;
void onPlayersLoaded(in DataHolder data) = 5006;
void onExtendedPlayersLoaded(in DataHolder data) = 5007;
/* @deprecated */ void onGamesLoaded(in DataHolder data) = 5008;
/* @deprecated */ void onExtendedGamesLoaded(in DataHolder data) = 5009;
/* @deprecated */ void onGameInstancesLoaded(in DataHolder data) = 5010;
/* @deprecated */ void onGameplayAclLoaded(in DataHolder data) = 5011;
/* @deprecated */ void onGameplayAclUpdated(int statusCode) = 5012;
/* @deprecated */ void onFAclLoaded(in DataHolder data) = 5013;
/* @deprecated */ void onFAclUpdated(int statusCode) = 5014;
void onSignOutComplete() = 5015;
/* @deprecated */ void onInvitationsLoaded(in DataHolder data) = 5016;
/* @deprecated */ void onRoomCreated(in DataHolder data) = 5017;
/* @deprecated */ void onJoinedRoom(in DataHolder data) = 5018;
/* @deprecated */ void onLeftRoom(int statusCode, String roomId) = 5019;
/* @deprecated */ void onRoomConnecting(in DataHolder data) = 5020;
/* @deprecated */ void onRoomAutoMatching(in DataHolder data) = 5021;
/* @deprecated */ void onRoomConnected(in DataHolder data) = 5022;
/* @deprecated */ void onConnectedToRoom(in DataHolder data) = 5023;
/* @deprecated */ void onDisconnectedFromRoom(in DataHolder data) = 5024;
/* @deprecated */ void onPeerInvitedToRoom(in DataHolder data, in String[] participantIds) = 5025;
/* @deprecated */ void onPeerJoinedRoom(in DataHolder data, in String[] participantIds) = 5026;
/* @deprecated */ void onPeerLeftRoom(in DataHolder data, in String[] participantIds) = 5027;
/* @deprecated */ void onPeerDeclined(in DataHolder data, in String[] participantIds) = 5028;
/* @deprecated */ void onPeerConnected(in DataHolder data, in String[] participantIds) = 5029;
/* @deprecated */ void onPeerDisconnected(in DataHolder data, in String[] participantIds) = 5030;
/* @deprecated */ void onRealTimeMessageReceived(in RealTimeMessage message) = 5031;
/* @deprecated */ void onMessageSent(int statusCode, int messageId, String recipientParticipantId) = 5032;
/* @deprecated */ void onGameMuteStatusChanged(int statusCode, String externalGameId, boolean isMuted) = 5033;
/* @deprecated */ void onNotifyAclLoaded(in DataHolder data) = 5034;
/* @deprecated */ void onNotifyAclUpdated(int statusCode) = 5035;
/* @deprecated */ void onInvitationReceived(in DataHolder data) = 5036;
/* @deprecated */ void onGameMuteStatusLoaded(in DataHolder data) = 5037;
/* @deprecated */ void onContactSettingsLoaded(in DataHolder data) = 5038;
/* @deprecated */ void onContactSettingsUpdated(int statusCode) = 5039;
void onResolveSnapshotHead(in DataHolder data, in Contents contents) = 12003;
void commitSnapshotResult(in DataHolder data) = 12004;
void onServerAuthCode(in Status status, String serverAuthCode) = 25002;
}

View file

@ -0,0 +1,4 @@
package com.google.android.gms.games.internal;
interface IGamesClient {
}

View file

@ -0,0 +1,120 @@
package com.google.android.gms.games.internal;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import com.google.android.gms.common.data.DataHolder;
import com.google.android.gms.drive.Contents;
import com.google.android.gms.games.PlayerEntity;
import com.google.android.gms.games.internal.IGamesCallbacks;
import com.google.android.gms.games.internal.IGamesClient;
import com.google.android.gms.games.snapshot.SnapshotMetadataChangeEntity;
interface IGamesService {
void clientDisconnecting(long clientId) = 5000;
void signOut(IGamesCallbacks callbacks) = 5001;
String getAppId() = 5002;
Bundle getConnectionHint() = 5003;
void showWelcomePopup(IBinder windowToken, in Bundle extras) = 5004;
void cancelPopups() = 5005;
String getCurrentAccountName() = 5006;
void loadGameplayAclInternal(IGamesCallbacks callbacks, String gameId) = 5007;
void updateGameplayAclInternal(IGamesCallbacks callbacks, String gameId, String aclData) = 5008;
void loadFAclInternal(IGamesCallbacks callbacks, String gameId) = 5009;
void updateFAclInternal(IGamesCallbacks callbacks, String gameId, boolean allCirclesVisible, in long[] circleIds) = 5010;
String getCurrentPlayerId() = 5011;
DataHolder getCurrentPlayer() = 5012;
void loadPlayer(IGamesCallbacks callbacks, String playerId) = 5013;
void loadInvitablePlayers(IGamesCallbacks callbacks, int pageSize, boolean expandCachedData, boolean forceReload) = 5014;
void submitScore(IGamesCallbacks callbacks, String leaderboardId, long score) = 5015;
void loadLeaderboards(IGamesCallbacks callbacks) = 5016;
void loadLeaderboard(IGamesCallbacks callbacks, String leaderboardId) = 5017;
void loadTopScores(IGamesCallbacks callbacks, String leaderboardId, int span, int leaderboardCollection, int maxResults, boolean forceReload) = 5018;
void loadPlayerCenteredScores(IGamesCallbacks callbacks, String leaderboardId, int span, int leaderboardCollection, int maxResults, boolean forceReload) = 5019;
void loadMoreScores(IGamesCallbacks callbacks, in Bundle previousheader, int maxResults, int pageDirection) = 5020;
void loadAchievements(IGamesCallbacks callbacks) = 5021;
void revealAchievement(IGamesCallbacks callbacks, String achievementId, IBinder windowToken, in Bundle extras) = 5022;
void unlockAchievement(IGamesCallbacks callbacks, String achievementId, IBinder windowToken, in Bundle extras) = 5023;
void incrementAchievement(IGamesCallbacks callbacks, String achievementId, int numSteps, IBinder windowToken, in Bundle extras) = 5024;
void loadGame(IGamesCallbacks callbacks) = 5025;
void loadInvitations(IGamesCallbacks callbacks) = 5026;
void declineInvitation(String invitationId, int invitationType) = 5027;
void dismissInvitation(String invitationId, int invitationType) = 5028;
void createRoom(IGamesCallbacks callbacks, IBinder processBinder, int variant, in String[] invitedPlayerIds, in Bundle autoMatchCriteria, boolean enableSockets, long clientId) = 5029;
void joinRoom(IGamesCallbacks callbacks, IBinder processBinder, String matchId, boolean enableSockets, long clientId) = 5030;
void leaveRoom(IGamesCallbacks callbacks, String matchId) = 5031;
int sendReliableMessage(IGamesCallbacks callbacks, in byte[] messageData, String matchId, String recipientParticipantId) = 5032;
int sendUnreliableMessage(in byte[] messageData, String matchId, in String[] recipientParticipantIds) = 5033;
String createSocketConnection(String participantId) = 5034;
void clearNotifications(int notificationTypes) = 5035;
void loadLeaderboardsFirstParty(IGamesCallbacks callbacks, String gameId) = 5036;
void loadLeaderboardFirstParty(IGamesCallbacks callbacks, String gameId, String leaderboardId) = 5037;
void loadTopScoresFirstParty(IGamesCallbacks callbacks, String gameId, String leaderboardId, int span, int leaderboardCollection, int maxResults, boolean forceReload) = 5038;
void loadPlayerCenteredScoresFirstParty(IGamesCallbacks callbacks, String gameId, String leaderboardId, int span, int leaderboardCollection, int maxResults, boolean forceReload) = 5039;
void loadAchievementsFirstParty(IGamesCallbacks callbacks, String playerId, String gameId) = 5040;
void loadGameFirstParty(IGamesCallbacks callbacks, String gameId) = 5041;
void loadGameInstancesFirstParty(IGamesCallbacks callbacks, String gameId) = 5042;
void loadGameCollectionFirstParty(IGamesCallbacks callbacks, int pageSize, int collectionType, boolean expandCachedData, boolean forceReload) = 5043;
void loadRecentlyPlayedGamesFirstParty(IGamesCallbacks callbacks, String externalPlayerId, int pageSize, boolean expandCachedData, boolean forceReload) = 5044;
void loadInvitablePlayersFirstParty(IGamesCallbacks callbacks, int pageSize, boolean expandCachedData, boolean forceReload) = 5045;
void loadRecentPlayersFirstParty(IGamesCallbacks callbacks) = 5046;
void loadCircledPlayersFirstParty(IGamesCallbacks callbacks, int pageSize, boolean expandCachedData, boolean forceReload) = 5047;
void loadSuggestedPlayersFirstParty(IGamesCallbacks callbacks) = 5048;
void dismissPlayerSuggestionFirstParty(String playerIdToDismiss) = 5049;
void declineInvitationFirstParty(String gameId, String invitationId, int invitationType) = 5050;
void loadInvitationsFirstParty(IGamesCallbacks callbacks, String gameId) = 5051;
int registerWaitingRoomListenerRestricted(IGamesCallbacks callbacks, String roomId) = 5052;
void setGameMuteStatusInternal(IGamesCallbacks callbacks, String gameId, boolean muted) = 5053;
void clearNotificationsFirstParty(String gameId, int notificationTypes) = 5054;
void loadNotifyAclInternal(IGamesCallbacks callbacks) = 5055;
void updateNotifyAclInternal(IGamesCallbacks callbacks, String aclData) = 5056;
void registerInvitationListener(IGamesCallbacks callbacks, long clientId) = 5057;
void unregisterInvitationListener(long clientId) = 5058;
int unregisterWaitingRoomListenerRestricted(String roomId) = 5059;
void isGameMutedInternal(IGamesCallbacks callbacks, String gameId) = 5060;
void loadContactSettingsInternal(IGamesCallbacks callbacks) = 5061;
void updateContactSettingsInternal(IGamesCallbacks callbacks, boolean enableMobileNotifications) = 5062;
String getSelectedAccountForGameFirstParty(String gamePackageName) = 5063;
void updateSelectedAccountForGameFirstParty(String gamePackageName, String accountName) = 5064;
Uri getGamesContentUriRestricted(String gameId) = 5065;
boolean shouldUseNewPlayerNotificationsFirstParty() = 5066;
void setUseNewPlayerNotificationsFirstParty(boolean newPlayerStyle) = 5067;
void searchForPlayersFirstParty(IGamesCallbacks callbacks, String query, int pageSize, boolean expandCachedData, boolean forceReload) = 5500;
DataHolder getCurrentGame() = 5501;
void loadAchievementsV2(IGamesCallbacks callbacks, boolean forceReload) = 6000;
void submitLeaderboardScore(IGamesCallbacks callbacks, String leaderboardId, long score, @nullable String scoreTag) = 7001;
void setAchievementSteps(IGamesCallbacks callbacks, String id, int numSteps, IBinder windowToken, in Bundle extras) = 7002;
Intent getAllLeaderboardsIntent() = 9002;
Intent getAchievementsIntent() = 9004;
Intent getPlayerSearchIntent() = 9009;
Intent getSelectSnapshotIntent(String title, boolean allowAddButton, boolean allowDelete, int maxSnapshots) = 12000;
void loadSnapshots(IGamesCallbacks callbacks, boolean forceReload) = 12001;
void commitSnapshot(IGamesCallbacks callbacks, String str, in SnapshotMetadataChangeEntity change, in Contents contents) = 12006;
void loadEvents(IGamesCallbacks callbacks, boolean forceReload) = 12015;
void incrementEvent(String eventId, int incrementAmount) = 12016;
void discardAndCloseSnapshot(in Contents contents) = 12018;
void loadEventsById(IGamesCallbacks callbacks, boolean forceReload, in String[] eventsIds) = 12030;
// void resolveSnapshotConflict(IGamesCallbacks callbacks, String conflictId, String snapshotId, in SnapshotMetadataChangeEntity metadata, in Contents contents) = 12032;
int getMaxDataSize() = 12034;
int getMaxCoverImageSize() = 12035;
void resolveSnapshotHead(IGamesCallbacks callbacks, String saveName, int i) = 15000;
void registerEventClient(IGamesClient callback, long l) = 15500;
Intent getCompareProfileIntentForPlayer(in PlayerEntity player) = 15502;
void loadPlayerStats(IGamesCallbacks callbacks, boolean forceReload) = 17000;
Intent getLeaderboardsScoresIntent(String leaderboardId, int timeSpan, int collection) = 18000;
Account getCurrentAccount() = 21000;
boolean isTelevision() = 22029;
Intent getCompareProfileIntentWithAlternativeNameHints(String otherPlayerId, String otherPlayerInGameName, String currentPlayerInGameName) = 25015;
void requestServerSideAccess(IGamesCallbacks callbacks, String serverClientId, boolean forceRefreshToken) = 27002;
}

View file

@ -0,0 +1,3 @@
package com.google.android.gms.games.internal.connect;
parcelable GamesSignInRequest;

View file

@ -0,0 +1,3 @@
package com.google.android.gms.games.internal.connect;
parcelable GamesSignInResponse;

View file

@ -0,0 +1,8 @@
package com.google.android.gms.games.internal.connect;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.games.internal.connect.GamesSignInResponse;
interface IGamesConnectCallbacks {
void onSignIn(in Status status, in GamesSignInResponse response) = 1;
}

View file

@ -0,0 +1,8 @@
package com.google.android.gms.games.internal.connect;
import com.google.android.gms.games.internal.connect.GamesSignInRequest;
import com.google.android.gms.games.internal.connect.IGamesConnectCallbacks;
interface IGamesConnectService {
void signIn(IGamesConnectCallbacks callback, in GamesSignInRequest request) = 1;
}

View file

@ -0,0 +1,3 @@
package com.google.android.gms.games.multiplayer.realtime;
parcelable RealTimeMessage;

View file

@ -0,0 +1,8 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.snapshot;
parcelable SnapshotMetadataChangeEntity;

View file

@ -0,0 +1,8 @@
/**
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.snapshot;
parcelable SnapshotMetadataEntity;

View file

@ -0,0 +1,40 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import org.microg.gms.common.Hide;
/**
* Class to return annotated data. Currently, the only annotation is whether the data is stale or not.
*/
public class AnnotatedData<T> {
private final T value;
private final boolean stale;
@Hide
public AnnotatedData(T value, boolean stale) {
this.value = value;
this.stale = stale;
}
/**
* Returns the data that is annotated by this class.
*/
public T get() {
return value;
}
/**
* Returns {@code true} if the data returned by {@link #get()} is stale. This usually indicates that there was a network error and data was
* returned from the local cache.
*/
public boolean isStale() {
return stale;
}
}

View file

@ -0,0 +1,23 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import android.os.Parcelable;
import com.google.android.gms.common.data.Freezable;
/**
* Data object representing the information related only to the signed in user.
*/
public interface CurrentPlayerInfo extends Freezable<CurrentPlayerInfo>, Parcelable {
/**
* Retrieves if the user has shared the friends list with the game. The possible output can be found in {@link Player.FriendsListVisibilityStatus}.
*/
@Player.FriendsListVisibilityStatus
int getFriendsListVisibilityStatus();
}

View file

@ -0,0 +1,46 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
import org.microg.gms.common.Hide;
import org.microg.safeparcel.AutoSafeParcelable;
@Hide
public class CurrentPlayerInfoEntity extends AutoSafeParcelable implements CurrentPlayerInfo {
@Field(1)
@Player.FriendsListVisibilityStatus
private int friendsListVisibilityStatus;
public CurrentPlayerInfoEntity() {
}
public CurrentPlayerInfoEntity(CurrentPlayerInfo copy) {
friendsListVisibilityStatus = copy.getFriendsListVisibilityStatus();
}
public CurrentPlayerInfoEntity(int friendsListVisibilityStatus) {
this.friendsListVisibilityStatus = friendsListVisibilityStatus;
}
@Override
@Player.FriendsListVisibilityStatus
public int getFriendsListVisibilityStatus() {
return friendsListVisibilityStatus;
}
@Override
public CurrentPlayerInfo freeze() {
return this;
}
@Override
public boolean isDataValid() {
return true;
}
public static final SafeParcelableCreatorAndWriter<CurrentPlayerInfoEntity> CREATOR = findCreator(CurrentPlayerInfoEntity.class);
}

View file

@ -0,0 +1,169 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import android.database.CharArrayBuffer;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.common.data.Freezable;
import com.google.android.gms.common.images.ImageManager;
import org.microg.gms.common.Hide;
/**
* Data interface for retrieving game information.
*/
public interface Game extends Freezable<Game> {
/**
* Indicates whether or not this game supports snapshots.
*
* @return Whether or not this game supports snapshots.
*/
boolean areSnapshotsEnabled();
/**
* Retrieves the number of achievements registered for this game.
*
* @return The number of achievements registered for this game.
*/
int getAchievementTotalCount();
/**
* Retrieves the application ID for this game.
*
* @return The application ID for this game.
*/
@NonNull
String getApplicationId();
/**
* Retrieves the description of this game.
*
* @return The description of this game.
*/
@NonNull
String getDescription();
/**
* Loads the description string into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
void getDescription(@NonNull CharArrayBuffer dataOut);
/**
* Retrieves the name of the developer of this game.
*
* @return The name of the developer of this game.
*/
@NonNull
String getDeveloperName();
/**
* Loads the developer name into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
void getDeveloperName(@NonNull CharArrayBuffer dataOut);
/**
* Retrieves the display name for this game.
*
* @return The display name for this game.
*/
@NonNull
String getDisplayName();
/**
* Loads the display name string into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
void getDisplayName(@NonNull CharArrayBuffer dataOut);
/**
* Retrieves an image URI that can be used to load the game's featured (banner) image from Google Play. Returns null if game has no featured image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return A URI that can be used to load the game's featured image, or null if the game has no featured image.
*/
@Nullable
Uri getFeaturedImageUri();
@Hide
@Deprecated
String getFeaturedImageUrl();
/**
* Retrieves an image URI that can be used to load the game's hi-res image. Returns null if game has no hi-res image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return A URI that can be used to load the game's hi-res image, or null if the game has no hi-res image.
*/
@Nullable
Uri getHiResImageUri();
@Hide
@Deprecated
String getHiResImageUrl();
/**
* Retrieves an image URI that can be used to load the game's icon. Returns null if game has no icon.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return A URI that can be used to load the game's icon, or null if the game has no icon.
*/
@Nullable
Uri getIconImageUri();
@Hide
@Deprecated
String getIconImageUrl();
/**
* Gets the number of leaderboards registered for this game.
*
* @return The number of leaderboards registered for this game.
*/
int getLeaderboardCount();
/**
* Retrieves the primary category of the game - this may be null.
*
* @return The primary category of the game.
*/
@Nullable
String getPrimaryCategory();
/**
* Retrieves the secondary category of the game - this may be null.
*
* @return The secondary category of the game, or null if not provided.
*/
@Nullable
String getSecondaryCategory();
/**
* Retrieves the theme color for this game. The theme color is used to configure the appearance of Play Games UIs.
*
* @return The color to use as an RGB hex triplet, e.g. "E0E0E0"
*/
@NonNull
String getThemeColor();
/**
* Indicates whether or not this game is marked as supporting gamepads.
*
* @return Whether or not this game declares gamepad support.
*/
boolean hasGamepadSupport();
}

View file

@ -0,0 +1,45 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games;
import org.microg.gms.common.Hide;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Hide
public class GameColumns {
public static final String EXTERNAL_GAME_ID = "external_game_id";
public static final String DISPLAY_NAME = "display_name";
public static final String PRIMARY_CATEGORY = "primary_category";
public static final String SECONDARY_CATEGORY = "secondary_category";
public static final String GAME_DESCRIPTION = "game_description";
public static final String DEVELOPER_NAME = "developer_name";
public static final String GAME_ICON_IMAGE_URI = "game_icon_image_uri";
public static final String GAME_ICON_IMAGE_URL = "game_icon_image_url";
public static final String GAME_HI_RES_IMAGE_URI = "game_hi_res_image_uri";
public static final String GAME_HI_RES_IMAGE_URL = "game_hi_res_image_url";
public static final String FEATURED_IMAGE_URI = "featured_image_uri";
public static final String FEATURED_IMAGE_URL = "featured_image_url";
public static final String PLAY_ENABLED_GAME = "play_enabled_game";
public static final String MUTED = "muted";
public static final String IDENTITY_SHARING_CONFIRMED = "identity_sharing_confirmed";
public static final String INSTALLED = "installed";
public static final String PACKAGE_NAME = "package_name";
public static final String ACHIEVEMENT_TOTAL_COUNT = "achievement_total_count";
public static final String LEADERBOARD_COUNT = "leaderboard_count";
public static final String REAL_TIME_SUPPORT = "real_time_support";
public static final String TURN_BASED_SUPPORT = "turn_based_support";
public static final String SNAPSHOTS_ENABLED = "snapshots_enabled";
public static final String THEME_COLOR = "theme_color";
public static final String GAMEPAD_SUPPORT = "gamepad_support";
public static final List<String> CURRENT_GAME_COLUMNS = Collections.unmodifiableList(Arrays.asList(
EXTERNAL_GAME_ID, DISPLAY_NAME, PRIMARY_CATEGORY, SECONDARY_CATEGORY, GAME_DESCRIPTION, DEVELOPER_NAME, GAME_ICON_IMAGE_URI, GAME_ICON_IMAGE_URL,
GAME_HI_RES_IMAGE_URI, GAME_HI_RES_IMAGE_URL, FEATURED_IMAGE_URI, FEATURED_IMAGE_URL, PLAY_ENABLED_GAME, MUTED, IDENTITY_SHARING_CONFIRMED, INSTALLED,
PACKAGE_NAME, ACHIEVEMENT_TOTAL_COUNT, LEADERBOARD_COUNT, REAL_TIME_SUPPORT, TURN_BASED_SUPPORT, SNAPSHOTS_ENABLED, THEME_COLOR, GAMEPAD_SUPPORT
));
}

View file

@ -0,0 +1,382 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import android.database.CharArrayBuffer;
import android.net.Uri;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.common.images.ImageManager;
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
import org.microg.gms.common.Hide;
/**
* Data object representing a set of Game data. This is immutable, and therefore safe to cache or store. Note, however, that the data it
* represents may grow stale.
* <p>
* This class exists solely to support parceling these objects and should not be used directly.
*/
@SafeParcelable.Class
public class GameEntity extends AbstractSafeParcelable implements Game {
@Field(value = 1, getterName = "getApplicationId")
private final String applicationId;
@Field(value = 2, getterName = "getDisplayName")
private final String displayName;
@Field(value = 3, getterName = "getPrimaryCategory")
private final String primaryCategory;
@Field(value = 4, getterName = "getSecondaryCategory")
private final String secondaryCategory;
@Field(value = 5, getterName = "getDescription")
private final String description;
@Field(value = 6, getterName = "getDeveloperName")
private final String developerName;
@Field(value = 7, getterName = "getIconImageUri")
private final Uri iconImageUri;
@Field(value = 8, getterName = "getHiResImageUri")
private final Uri hiResImageUri;
@Field(value = 9, getterName = "getFeaturedImageUri")
private final Uri featuredImageUri;
@Field(value = 10, getterName = "isPlayEnabledGame")
private final boolean isPlayEnabledGame;
@Field(value = 11, getterName = "isInstanceInstalled")
private final boolean isInstanceInstalled;
@Field(value = 12, getterName = "getInstancePackageName")
private final String instancePackageName;
@Field(value = 13, getterName = "getGameplayAclStatus")
private final int gameplayAclStatus;
@Field(value = 14, getterName = "getAchievementTotalCount")
private final int achievementTotalCount;
@Field(value = 15, getterName = "getLeaderboardCount")
private final int leaderboardCount;
@Field(value = 16, getterName = "isRealTimeMultiplayerEnabled")
private final boolean isRealTimeMultiplayerEnabled;
@Field(value = 17, getterName = "isTurnBasedMultiplayerEnabled")
private final boolean isTurnBasedMultiplayerEnabled;
@Field(value = 18, getterName = "getIconImageUrl")
private final String iconImageUrl;
@Field(value = 19, getterName = "getHiResImageUrl")
private final String hiResImageUrl;
@Field(value = 20, getterName = "getFeaturedImageUrl")
private final String featuredImageUrl;
@Field(value = 21, getterName = "isMuted")
private final boolean isMuted;
@Field(value = 22, getterName = "isIdentitySharingConfirmed")
private final boolean isIdentitySharingConfirmed;
@Field(value = 23, getterName = "areSnapshotsEnabled")
private final boolean areSnapshotsEnabled;
@Field(value = 24, getterName = "getThemeColor")
private final String getThemeColor;
@Field(value = 25, getterName = "hasGamepadSupport")
private final boolean hasGamepadSupport;
@Hide
@Constructor
public GameEntity(@Param(value = 1) String applicationId, @Param(value = 2) String displayName, @Param(value = 3) String primaryCategory, @Param(value = 4) String secondaryCategory, @Param(value = 5) String description, @Param(value = 6) String developerName, @Param(value = 7) Uri iconImageUri, @Param(value = 8) Uri hiResImageUri, @Param(value = 9) Uri featuredImageUri, @Param(value = 10) boolean isPlayEnabledGame, @Param(value = 11) boolean isInstanceInstalled, @Param(value = 12) String instancePackageName, @Param(value = 13) int gameplayAclStatus, @Param(value = 14) int achievementTotalCount, @Param(value = 15) int leaderboardCount, @Param(value = 16) boolean isRealTimeMultiplayerEnabled, @Param(value = 17) boolean isTurnBasedMultiplayerEnabled, @Param(value = 18) String iconImageUrl, @Param(value = 19) String hiResImageUrl, @Param(value = 20) String featuredImageUrl, @Param(value = 21) boolean isMuted, @Param(value = 22) boolean isIdentitySharingConfirmed, @Param(value = 23) boolean areSnapshotsEnabled, @Param(value = 24) String getThemeColor, @Param(value = 25) boolean hasGamepadSupport) {
this.applicationId = applicationId;
this.displayName = displayName;
this.primaryCategory = primaryCategory;
this.secondaryCategory = secondaryCategory;
this.description = description;
this.developerName = developerName;
this.iconImageUri = iconImageUri;
this.iconImageUrl = iconImageUrl;
this.hiResImageUri = hiResImageUri;
this.hiResImageUrl = hiResImageUrl;
this.featuredImageUri = featuredImageUri;
this.featuredImageUrl = featuredImageUrl;
this.isPlayEnabledGame = isPlayEnabledGame;
this.isInstanceInstalled = isInstanceInstalled;
this.instancePackageName = instancePackageName;
this.gameplayAclStatus = gameplayAclStatus;
this.achievementTotalCount = achievementTotalCount;
this.leaderboardCount = leaderboardCount;
this.isRealTimeMultiplayerEnabled = isRealTimeMultiplayerEnabled;
this.isTurnBasedMultiplayerEnabled = isTurnBasedMultiplayerEnabled;
this.isMuted = isMuted;
this.isIdentitySharingConfirmed = isIdentitySharingConfirmed;
this.areSnapshotsEnabled = areSnapshotsEnabled;
this.getThemeColor = getThemeColor;
this.hasGamepadSupport = hasGamepadSupport;
}
/**
* Indicates whether or not this game supports snapshots.
*
* @return Whether or not this game supports snapshots.
*/
@Override
public boolean areSnapshotsEnabled() {
return this.areSnapshotsEnabled;
}
@Override
public Game freeze() {
return this;
}
/**
* Retrieves the number of achievements registered for this game.
*
* @return The number of achievements registered for this game.
*/
@Override
public int getAchievementTotalCount() {
return this.achievementTotalCount;
}
/**
* Retrieves the application ID for this game.
*
* @return The application ID for this game.
*/
@Override
@NonNull
public String getApplicationId() {
return this.applicationId;
}
/**
* Retrieves the description of this game.
*
* @return The description of this game.
*/
@Override
@NonNull
public String getDescription() {
return this.description;
}
/**
* Loads the description string into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
@Override
public void getDescription(@NonNull CharArrayBuffer dataOut) {
copyStringToBuffer(this.description, dataOut);
}
/**
* Retrieves the name of the developer of this game.
*
* @return The name of the developer of this game.
*/
@Override
@NonNull
public String getDeveloperName() {
return this.developerName;
}
/**
* Loads the developer name into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
@Override
public void getDeveloperName(@NonNull CharArrayBuffer dataOut) {
copyStringToBuffer(this.developerName, dataOut);
}
/**
* Retrieves the display name for this game.
*
* @return The display name for this game.
*/
@Override
@NonNull
public String getDisplayName() {
return this.displayName;
}
/**
* Loads the display name string into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
@Override
public void getDisplayName(@NonNull CharArrayBuffer dataOut) {
copyStringToBuffer(this.displayName, dataOut);
}
/**
* Retrieves an image URI that can be used to load the game's featured (banner) image from Google Play. Returns null if game has no featured image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return A URI that can be used to load the game's featured image, or null if the game has no featured image.
*/
@Override
@Nullable
public Uri getFeaturedImageUri() {
return this.featuredImageUri;
}
@Override
@Hide
@Deprecated
public String getFeaturedImageUrl() {
return this.featuredImageUrl;
}
/**
* Retrieves an image URI that can be used to load the game's hi-res image. Returns null if game has no hi-res image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return A URI that can be used to load the game's hi-res image, or null if the game has no hi-res image.
*/
@Override
@Nullable
public Uri getHiResImageUri() {
return this.hiResImageUri;
}
@Override
@Hide
@Deprecated
public String getHiResImageUrl() {
return this.hiResImageUrl;
}
/**
* Retrieves an image URI that can be used to load the game's icon. Returns null if game has no icon.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return A URI that can be used to load the game's icon, or null if the game has no icon.
*/
@Override
public Uri getIconImageUri() {
return this.iconImageUri;
}
@Override
@Hide
@Deprecated
public String getIconImageUrl() {
return this.iconImageUrl;
}
/**
* Gets the number of leaderboards registered for this game.
*
* @return The number of leaderboards registered for this game.
*/
@Override
public int getLeaderboardCount() {
return this.leaderboardCount;
}
/**
* Retrieves the primary category of the game - this is may be null.
*
* @return The primary category of the game.
*/
@Override
@Nullable
public String getPrimaryCategory() {
return this.primaryCategory;
}
/**
* Retrieves the secondary category of the game - this may be null.
*
* @return The secondary category of the game, or null if not provided.
*/
@Override
@Nullable
public String getSecondaryCategory() {
return this.secondaryCategory;
}
/**
* Retrieves the theme color for this game. The theme color is used to configure the appearance of Play Games UIs.
*
* @return The color to use as an RGB hex triplet, e.g. "E0E0E0"
*/
@Override
@NonNull
public String getThemeColor() {
return this.getThemeColor;
}
/**
* Indicates whether or not this game is marked as supporting gamepads.
*
* @return Whether or not this game declares gamepad support.
*/
@Override
public boolean hasGamepadSupport() {
return this.hasGamepadSupport;
}
@Override
public boolean isDataValid() {
return true;
}
int getGameplayAclStatus() {
return gameplayAclStatus;
}
String getInstancePackageName() {
return this.instancePackageName;
}
boolean isMuted() {
return this.isMuted;
}
boolean isIdentitySharingConfirmed() {
return this.isIdentitySharingConfirmed;
}
boolean isPlayEnabledGame() {
return this.isPlayEnabledGame;
}
boolean isInstanceInstalled() {
return this.isInstanceInstalled;
}
@Hide
boolean isRealTimeMultiplayerEnabled() {
return this.isRealTimeMultiplayerEnabled;
}
@Hide
boolean isTurnBasedMultiplayerEnabled() {
return this.isTurnBasedMultiplayerEnabled;
}
private static void copyStringToBuffer(@Nullable String toCopy, @NonNull CharArrayBuffer dataOut) {
if (toCopy == null || toCopy.isEmpty()) {
dataOut.sizeCopied = 0;
return;
}
if (dataOut.data == null || dataOut.data.length < toCopy.length()) {
dataOut.data = toCopy.toCharArray();
} else {
toCopy.getChars(0, toCopy.length(), dataOut.data, 0);
}
dataOut.sizeCopied = toCopy.length();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<GameEntity> CREATOR = findCreator(GameEntity.class);
}

View file

@ -0,0 +1,89 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games;
import com.google.android.gms.common.api.Status;
public enum GamesStatusCodes {
ACHIEVEMENT_NOT_INCREMENTAL(3002, "Achievement not incremental"),
ACHIEVEMENT_UNKNOWN(3001, "Achievement unknown"),
ACHIEVEMENT_UNLOCKED(3003, "Achievement unlocked"),
ACHIEVEMENT_UNLOCK_FAILURE(3000, "Achievement unlock failure"),
APP_MISCONFIGURED(8, "App misconfigured"),
CLIENT_RECONNECT_REQUIRED(2, "Client reconnect required"),
GAME_NOT_FOUND(9, "Game not found"),
INTERNAL_ERROR(1, "Internal error"),
INTERRUPTED(14, "Interrupted"),
INVALID_REAL_TIME_ROOM_ID(7002, "Invalid real time room ID"),
LICENSE_CHECK_FAILED(7, "License check failed"),
MATCH_ERROR_ALREADY_REMATCHED(6505, "Match error already rematched"),
MATCH_ERROR_INACTIVE_MATCH(6501, "Match error inactive match"),
MATCH_ERROR_INVALID_MATCH_RESULTS(6504, "Match error invalid match results"),
MATCH_ERROR_INVALID_MATCH_STATE(6502, "Match error invalid match state"),
MATCH_ERROR_INVALID_PARTICIPANT_STATE(6500, "Match error invalid participant state"),
MATCH_ERROR_LOCALLY_MODIFIED(6507, "Match error locally modified"),
MATCH_ERROR_OUT_OF_DATE_VERSION(6503, "Match error out of date version"),
MATCH_NOT_FOUND(6506, "Match not found"),
MILESTONE_CLAIMED_PREVIOUSLY(8000, "Milestone claimed previously"),
MILESTONE_CLAIM_FAILED(8001, "Milestone claim failed"),
MULTIPLAYER_DISABLED(6003, "Multiplayer disabled"),
MULTIPLAYER_ERROR_CREATION_NOT_ALLOWED(6000, "Multiplayer error creation not allowed"),
MULTIPLAYER_ERROR_INVALID_MULTIPLAYER_TYPE(6002, "Multiplayer error invalid multiplayer type"),
MULTIPLAYER_ERROR_INVALID_OPERATION(6004, "Multiplayer error invalid operation"),
MULTIPLAYER_ERROR_NOT_TRUSTED_TESTER(6001, "Multiplayer error not trusted tester"),
NETWORK_ERROR_NO_DATA(4, "Network error no data"),
NETWORK_ERROR_OPERATION_DEFERRED(5, "Network error operation deferred"),
NETWORK_ERROR_OPERATION_FAILED(6, "Network error operation failed"),
NETWORK_ERROR_STALE_DATA(3, "Network error stale data"),
OK(0, "OK"),
OPERATION_IN_FLIGHT(7007, "Operation in flight"),
PARTICIPANT_NOT_CONNECTED(7003, "Participant not connected"),
QUEST_NOT_STARTED(8003, "Quest not started"),
QUEST_NO_LONGER_AVAILABLE(8002, "Quest no longer available"),
REAL_TIME_CONNECTION_FAILED(7000, "Real time connection failed"),
REAL_TIME_INACTIVE_ROOM(7005, "Real time inactive room"),
REAL_TIME_MESSAGE_SEND_FAILED(7001, "Real time message send failed"),
REAL_TIME_ROOM_NOT_JOINED(7004, "Real time room not joined"),
REQUEST_TOO_MANY_RECIPIENTS(2002, "Request too many recipients"),
REQUEST_UPDATE_PARTIAL_SUCCESS(2000, "Request update partial success"),
REQUEST_UPDATE_TOTAL_FAILURE(2001, "Request update total failure"),
SNAPSHOT_COMMIT_FAILED(4003, "Snapshot commit failed"),
SNAPSHOT_CONFLICT(4004, "Snapshot conflict"),
SNAPSHOT_CONFLICT_MISSING(4006, "Snapshot conflict missing"),
SNAPSHOT_CONTENTS_UNAVAILABLE(4002, "Snapshot contents unavailable"),
SNAPSHOT_CREATION_FAILED(4001, "Snapshot creation failed"),
SNAPSHOT_FOLDER_UNAVAILABLE(4005, "Snapshot folder unavailable"),
SNAPSHOT_NOT_FOUND(4000, "Snapshot not found"),
TIMEOUT(15, "Timeout"),
VIDEO_ALREADY_CAPTURING(9006, "Video already capturing"),
VIDEO_NOT_ACTIVE(9000, "Video not active"),
VIDEO_OUT_OF_DISK_SPACE(9009, "Video out of disk space"),
VIDEO_PERMISSION_ERROR(9002, "Video permission error"),
VIDEO_STORAGE_ERROR(9003, "Video storage error"),
VIDEO_UNEXPECTED_CAPTURE_ERROR(9004, "Video unexpected capture error"),
VIDEO_UNSUPPORTED(9001, "Video unsupported");
private final int code;
private final String description;
GamesStatusCodes(int code, String description) {
this.code = code;
this.description = description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
public static Status createStatus(GamesStatusCodes gamesStatusCodes) {
return new Status(gamesStatusCodes.code, gamesStatusCodes.description);
}
}

View file

@ -0,0 +1,202 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import android.database.CharArrayBuffer;
import android.net.Uri;
import android.os.Parcelable;
import androidx.annotation.IntDef;
import com.google.android.gms.common.data.Freezable;
import com.google.android.gms.common.images.ImageManager;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Data interface for retrieving player information.
*/
public interface Player extends Freezable<Player>, Parcelable {
/**
* Friends list visibility statuses.
*/
@IntDef({FriendsListVisibilityStatus.UNKNOWN, FriendsListVisibilityStatus.VISIBLE, FriendsListVisibilityStatus.REQUEST_REQUIRED, FriendsListVisibilityStatus.FEATURE_UNAVAILABLE})
@Retention(RetentionPolicy.SOURCE)
@interface FriendsListVisibilityStatus {
/**
* Constant indicating that currently it's unknown if the friends list is visible to the game, or whether the game can ask for
* access from the user. Use {@link PlayersClient#getCurrentPlayer(boolean)} to force reload the latest status.
*/
int UNKNOWN = 0;
/**
* Constant indicating that the friends list is currently visible to the game.
*/
int VISIBLE = 1;
/**
* Constant indicating that the friends list is not visible to the game, but the game can ask for access.
*/
int REQUEST_REQUIRED = 2;
/**
* Constant indicating that the friends list is currently unavailable for the game. You cannot request access at this time,
* either because the user has permanently declined or the friends feature is not available to them. In this state, any
* attempts to request access to the friends list will be unsuccessful.
*/
int FEATURE_UNAVAILABLE = 3;
}
/**
* Player friend statuses.
*/
@IntDef({PlayerFriendStatus.UNKNOWN, PlayerFriendStatus.NO_RELATIONSHIP, PlayerFriendStatus.FRIEND})
@Retention(RetentionPolicy.SOURCE)
@interface PlayerFriendStatus {
/**
* Constant indicating that the currently signed-in player's friend status with this player is unknown. This may happen if the
* user has not shared the friends list with the game.
*/
int UNKNOWN = -1;
/**
* Constant indicating that the currently signed-in player is not a friend of this player, and there are no pending invitations
* between them.
*/
int NO_RELATIONSHIP = 0;
/**
* Constant indicating that the currently signed-in player and this player are friends.
*/
int FRIEND = 4;
}
/**
* Constant indicating that the current XP total for a player is not known.
*/
long CURRENT_XP_UNKNOWN = -1;
/**
* Constant indicating that a timestamp for a player is not known.
*/
long TIMESTAMP_UNKNOWN = -1;
/**
* Retrieves the URI for loading this player's landscape banner image. Returns null if the player has no landscape banner image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return The image URI for the player's landscape banner image, or null if the player has none.
*/
Uri getBannerImageLandscapeUri();
/**
* Retrieves the URI for loading this player's portrait banner image. Returns null if the player has no portrait banner image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return The image URI for the player's portrait banner image, or null if the player has none.
*/
Uri getBannerImagePortraitUri();
/**
* Returns information only available for the signed-in user. The method will return {@code null} for other players.
*/
CurrentPlayerInfo getCurrentPlayerInfo();
/**
* Loads the player's display name into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
void getDisplayName(CharArrayBuffer dataOut);
/**
* Retrieves the display name for this player.
*
* @return The player's display name.
*/
String getDisplayName();
/**
* Retrieves the URI for loading this player's hi-res profile image. Returns null if the player has no profile image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return The image URI for the player's hi-res profile image, or null if the player has none.
*/
Uri getHiResImageUri();
/**
* Retrieves the URI for loading this player's icon-size profile image. Returns null if the player has no profile image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return The image URI for the player's icon-size profile image, or null if the player has none.
*/
Uri getIconImageUri();
/**
* Retrieves the timestamp at which this player last played a multiplayer game with the currently signed in user. If the
* timestamp is not found, this method returns {@link #TIMESTAMP_UNKNOWN}.
*
* @return The timestamp (in ms since epoch) at which the player last played a multiplayer game with the currently signed in user.
* @deprecated Real-time multiplayer and Turn-based multiplayer support is being shut down on March 31, 2020.
*/
@Deprecated
long getLastPlayedWithTimestamp();
/**
* Retrieves the player level associated information if any exists. If no level information exists for this player, this method will return {@code null}.
*
* @return The {@link PlayerLevelInfo} associated with this player, if any.
*/
PlayerLevelInfo getLevelInfo();
/**
* Retrieves the ID of this player.
*
* @return The player ID.
*/
String getPlayerId();
/**
* Returns relationship information of this player. If no relationship information exists for this player, this method will return {@code null}.
*/
PlayerRelationshipInfo getRelationshipInfo();
/**
* Retrieves the timestamp at which this player record was last updated locally.
*
* @return The timestamp (in ms since epoch) at which the player data was last updated locally.
*/
long getRetrievedTimestamp();
/**
* Retrieves the title of the player. This is based on the player's gameplay activity in apps using Google Play Games
* services. Note that not all players have titles, and that a player's title may change over time.
*
* @return The player's title, or {@code null} if this player has no title.
*/
String getTitle();
/**
* Loads the player's title into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
void getTitle(CharArrayBuffer dataOut);
/**
* Indicates whether this player has a hi-res profile image to display.
*
* @return Whether the player has a hi-res profile image to display.
*/
boolean hasHiResImage();
/**
* Indicates whether this player has an icon-size profile image to display.
*
* @return Whether the player has an icon-size profile image to display.
*/
boolean hasIconImage();
}

View file

@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import com.google.android.gms.common.data.AbstractDataBuffer;
import com.google.android.gms.common.data.DataHolder;
import org.microg.gms.common.Hide;
/**
* Data structure providing access to a list of players.
*/
public class PlayerBuffer extends AbstractDataBuffer<Player> {
@Hide
public PlayerBuffer(DataHolder dataHolder) {
super(dataHolder);
}
public Player get(int position) {
throw new UnsupportedOperationException();
//return new PlayerRef(dataHolder, position);
}
}

View file

@ -0,0 +1,80 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class PlayerColumns {
public static final String externalPlayerId = "external_player_id";
public static final String profileName = "profile_name";
public static final String profileIconImageId = "profile_icon_image_id";
public static final String profileIconImageUri = "profile_icon_image_uri";
public static final String profileIconImageUrl = "profile_icon_image_url";
public static final String profileHiResImageId = "profile_hi_res_image_id";
public static final String profileHiResImageUri = "profile_hi_res_image_uri";
public static final String profileHiResImageUrl = "profile_hi_res_image_url";
public static final String lastUpdated = "last_updated";
public static final String isInCircles = "is_in_circles";
public static final String playedWithTimestamp = "played_with_timestamp";
public static final String currentXpTotal = "current_xp_total";
public static final String currentLevel = "current_level";
public static final String currentLevelMinXp = "current_level_min_xp";
public static final String currentLevelMaxXp = "current_level_max_xp";
public static final String nextLevel = "next_level";
public static final String nextLevelMaxXp = "next_level_max_xp";
public static final String lastLevelUpTimestamp = "last_level_up_timestamp";
public static final String playerTitle = "player_title";
public static final String hasAllPublicAcls = "has_all_public_acls";
public static final String isProfileVisible = "is_profile_visible";
public static final String mostRecentExternalGameId = "most_recent_external_game_id";
public static final String mostRecentGameName = "most_recent_game_name";
public static final String mostRecentActivityTimestamp = "most_recent_activity_timestamp";
public static final String mostRecentGameIconId = "most_recent_game_icon_id";
public static final String mostRecentGameIconUri = "most_recent_game_icon_uri";
public static final String mostRecentGameHiResId = "most_recent_game_hi_res_id";
public static final String mostRecentGameHiResUri = "most_recent_game_hi_res_uri";
public static final String mostRecentGameFeaturedId = "most_recent_game_featured_id";
public static final String mostRecentGameFeaturedUri = "most_recent_game_featured_uri";
public static final String hasDebugAccess = "has_debug_access";
public static final String gamerTag = "gamer_tag";
public static final String realName = "real_name";
public static final String bannerImageLandscapeId = "banner_image_landscape_id";
public static final String bannerImageLandscapeUri = "banner_image_landscape_uri";
public static final String bannerImageLandscapeUrl = "banner_image_landscape_url";
public static final String bannerImagePortraitId = "banner_image_portrait_id";
public static final String bannerImagePortraitUri = "banner_image_portrait_uri";
public static final String bannerImagePortraitUrl = "banner_image_portrait_url";
public static final String gamerFriendStatus = "gamer_friend_status";
public static final String gamerFriendUpdateTimestamp = "gamer_friend_update_timestamp";
public static final String isMuted = "is_muted";
public static final String totalUnlockedAchievements = "total_unlocked_achievements";
public static final String playTogetherFriendStatus = "play_together_friend_status";
public static final String playTogetherNickname = "play_together_nickname";
public static final String playTogetherInvitationNickname = "play_together_invitation_nickname";
public static final String nicknameAbuseReportToken = "nickname_abuse_report_token";
public static final String friendsListVisibility = "friends_list_visibility";
public static final String alwaysAutoSignIn = "always_auto_sign_in";
public static final String profileCreationTimestamp = "profile_creation_timestamp";
public static final String gamePlayerId = "game_player_id";
public static final List<String> CURRENT_PLAYER_COLUMNS = Collections.unmodifiableList(Arrays.asList(
externalPlayerId,
profileIconImageId, profileHiResImageId, profileIconImageUri, profileIconImageUrl, profileHiResImageUri, profileHiResImageUrl,
profileName, lastUpdated, isInCircles, hasAllPublicAcls, hasDebugAccess, isProfileVisible,
currentXpTotal, currentLevel, currentLevelMinXp, currentLevelMaxXp, nextLevel, nextLevelMaxXp, lastLevelUpTimestamp,
playerTitle,
mostRecentExternalGameId, mostRecentGameName, mostRecentActivityTimestamp, mostRecentGameIconId, mostRecentGameIconUri, mostRecentGameHiResId, mostRecentGameHiResUri, mostRecentGameFeaturedId, mostRecentGameFeaturedUri,
gamerTag, realName,
bannerImageLandscapeId, bannerImageLandscapeUri, bannerImageLandscapeUrl, bannerImagePortraitId, bannerImagePortraitUri, bannerImagePortraitUrl,
totalUnlockedAchievements,
playTogetherFriendStatus, playTogetherNickname, playTogetherInvitationNickname,
profileCreationTimestamp, nicknameAbuseReportToken, friendsListVisibility, alwaysAutoSignIn,
gamerFriendStatus, gamerFriendUpdateTimestamp,
isMuted, gamePlayerId
));
}

View file

@ -0,0 +1,276 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import android.database.CharArrayBuffer;
import android.net.Uri;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
import com.google.android.gms.games.internal.player.MostRecentGameInfoEntity;
import org.microg.gms.common.Hide;
import org.microg.safeparcel.AutoSafeParcelable;
/**
* Data object representing a set of Player data. This is immutable, and therefore safe to cache or store. Note, however, that
* the data it represents may grow stale.
* <p>
* This class exists solely to support parceling these objects and should not be used directly.
*/
public class PlayerEntity extends AutoSafeParcelable implements Player {
@Field(1)
private String playerId;
@Field(2)
private String displayName;
@Field(3)
private Uri iconImageUri;
@Field(4)
private Uri hiResImageUri;
@Field(5)
private long retrievedTimestamp;
@Field(6)
private int isInCircles;
@Field(7)
private long lastPlayedWithTimestamp;
@Field(8)
private String iconImageUrl;
@Field(9)
private String hiResImageUrl;
@Field(14)
private String title;
@Field(15)
private MostRecentGameInfoEntity mostRecentGameInfo;
@Field(16)
private PlayerLevelInfo levelInfo;
@Field(18)
private boolean profileVisible;
@Field(19)
private boolean hasDebugAccess;
@Field(20)
private String gamerTag;
@Field(21)
private String name;
@Field(22)
private Uri bannerImageLandscapeUri;
@Field(23)
private String bannerImageLandscapeUrl;
@Field(24)
private Uri bannerImagePortraitUri;
@Field(25)
private String bannerImagePortraitUrl;
@Field(29)
private long totalUnlockedAchievement = -1;
@Field(33)
private PlayerRelationshipInfoEntity relationshipInfo;
@Field(35)
private CurrentPlayerInfoEntity currentPlayerInfo;
@Field(36)
private boolean alwaysAutoSignIn;
@Field(37)
private String gamePlayerId;
@Hide
public PlayerEntity() {
}
@Hide
public PlayerEntity(Player copy) {
bannerImageLandscapeUri = copy.getBannerImageLandscapeUri();
bannerImagePortraitUri = copy.getBannerImagePortraitUri();
currentPlayerInfo = new CurrentPlayerInfoEntity(copy.getCurrentPlayerInfo());
displayName = copy.getDisplayName();
hiResImageUri = copy.getHiResImageUri();
iconImageUri = copy.getIconImageUri();
lastPlayedWithTimestamp = copy.getLastPlayedWithTimestamp();
levelInfo = copy.getLevelInfo();
playerId = copy.getPlayerId();
relationshipInfo = new PlayerRelationshipInfoEntity(copy.getRelationshipInfo());
retrievedTimestamp = copy.getRetrievedTimestamp();
title = copy.getTitle();
}
@Hide
public PlayerEntity(String playerId, String displayName, Uri iconImageUri, Uri hiResImageUri, long retrievedTimestamp, int isInCircles, long lastPlayedWithTimestamp, String iconImageUrl, String hiResImageUrl, String title, MostRecentGameInfoEntity mostRecentGameInfo, PlayerLevelInfo levelInfo, boolean profileVisible, boolean hasDebugAccess, String gamerTag, String name, Uri bannerImageLandscapeUri, String bannerImageLandscapeUrl, Uri bannerImagePortraitUri, String bannerImagePortraitUrl, long totalUnlockedAchievement, PlayerRelationshipInfoEntity relationshipInfo, CurrentPlayerInfoEntity currentPlayerInfo, boolean alwaysAutoSignIn, String gamePlayerId) {
this.playerId = playerId;
this.displayName = displayName;
this.iconImageUri = iconImageUri;
this.hiResImageUri = hiResImageUri;
this.retrievedTimestamp = retrievedTimestamp;
this.isInCircles = isInCircles;
this.lastPlayedWithTimestamp = lastPlayedWithTimestamp;
this.iconImageUrl = iconImageUrl;
this.hiResImageUrl = hiResImageUrl;
this.title = title;
this.mostRecentGameInfo = mostRecentGameInfo;
this.levelInfo = levelInfo;
this.profileVisible = profileVisible;
this.hasDebugAccess = hasDebugAccess;
this.gamerTag = gamerTag;
this.name = name;
this.bannerImageLandscapeUri = bannerImageLandscapeUri;
this.bannerImageLandscapeUrl = bannerImageLandscapeUrl;
this.bannerImagePortraitUri = bannerImagePortraitUri;
this.bannerImagePortraitUrl = bannerImagePortraitUrl;
this.totalUnlockedAchievement = totalUnlockedAchievement;
this.relationshipInfo = relationshipInfo;
this.currentPlayerInfo = currentPlayerInfo;
this.alwaysAutoSignIn = alwaysAutoSignIn;
this.gamePlayerId = gamePlayerId;
}
@Override
public Uri getBannerImageLandscapeUri() {
return bannerImageLandscapeUri;
}
@Override
public Uri getBannerImagePortraitUri() {
return bannerImagePortraitUri;
}
@Override
public CurrentPlayerInfo getCurrentPlayerInfo() {
return currentPlayerInfo;
}
@Override
public void getDisplayName(CharArrayBuffer dataOut) {
throw new UnsupportedOperationException();
}
@Override
public String getDisplayName() {
return displayName;
}
@Override
public Uri getHiResImageUri() {
return hiResImageUri;
}
@Override
public Uri getIconImageUri() {
return iconImageUri;
}
@Override
public long getLastPlayedWithTimestamp() {
return lastPlayedWithTimestamp;
}
@Override
public PlayerLevelInfo getLevelInfo() {
return levelInfo;
}
@Override
public String getPlayerId() {
return playerId;
}
@Override
public PlayerRelationshipInfo getRelationshipInfo() {
return relationshipInfo;
}
@Override
public long getRetrievedTimestamp() {
return retrievedTimestamp;
}
@Override
public String getTitle() {
return title;
}
@Override
public void getTitle(CharArrayBuffer dataOut) {
throw new UnsupportedOperationException();
}
@Override
public boolean hasHiResImage() {
return hiResImageUri != null;
}
@Override
public boolean hasIconImage() {
return iconImageUri != null;
}
@Override
public boolean isDataValid() {
return true;
}
@Override
public Player freeze() {
return this;
}
@Hide
public String getGamerTag() {
return gamerTag;
}
@Hide
public String getName() {
return name;
}
@Hide
public String getIconImageUrl() {
return iconImageUrl;
}
@Hide
public String getHiResImageUrl() {
return hiResImageUrl;
}
@Hide
public String getBannerImageLandscapeUrl() {
return bannerImageLandscapeUrl;
}
@Hide
public String getBannerImagePortraitUrl() {
return bannerImagePortraitUrl;
}
@Hide
public int getIsInCircles() {
return isInCircles;
}
@Hide
public boolean isProfileVisible() {
return profileVisible;
}
@Hide
public boolean getHasDebugAccess() {
return hasDebugAccess;
}
@Hide
public long getTotalUnlockedAchievement() {
return totalUnlockedAchievement;
}
@Hide
public boolean isAlwaysAutoSignIn() {
return alwaysAutoSignIn;
}
@Hide
public MostRecentGameInfoEntity getMostRecentGameInfo() {
return mostRecentGameInfo;
}
public static final SafeParcelableCreatorAndWriter<PlayerEntity> CREATOR = findCreator(PlayerEntity.class);
}

View file

@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import android.os.Parcel;
import androidx.annotation.NonNull;
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
import org.microg.gms.common.Hide;
/**
* Data object representing a level a player can obtain in the metagame.
* <p>
* A {@code PlayerLevel} has three components: a numeric value, and a range of XP totals it represents. A player is considered a
* given level if they have <b>at least</b> {@link #getMinXp()} and <b>less than</b> {@link #getMaxXp()}.
*/
@SafeParcelable.Class
public class PlayerLevel extends AbstractSafeParcelable {
@Field(value = 1, getterName = "getLevelNumber")
private final int levelNumber;
@Field(value = 2, getterName = "getMinXp")
private final long minXp;
@Field(value = 3, getterName = "getMaxXp")
private final long maxXp;
@Constructor
@Hide
public PlayerLevel(@Param(1) int levelNumber, @Param(2) long minXp, @Param(3) long maxXp) {
this.levelNumber = levelNumber;
this.minXp = minXp;
this.maxXp = maxXp;
}
/**
* Returns the number for this level, e.g. "level 10".
* <p>
* This is the level that this object represents. For a player to be considered as being of this level, the value given by
* {@link PlayerLevelInfo#getCurrentXpTotal()} must fall in the range [{@link #getMinXp()}, {@link #getMaxXp()}).
*
* @return The level number for this level.
*/
public int getLevelNumber() {
return levelNumber;
}
/**
* @return The maximum XP value represented by this level, exclusive.
*/
public long getMaxXp() {
return maxXp;
}
/**
* @return The minimum XP value needed to attain this level, inclusive.
*/
public long getMinXp() {
return minXp;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<PlayerLevel> CREATOR = findCreator(PlayerLevel.class);
}

View file

@ -0,0 +1,87 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
import org.microg.gms.common.Hide;
import org.microg.safeparcel.AutoSafeParcelable;
/**
* Data object representing the current level information of a player in the metagame.
* <p>
* A {@code PlayerLevelInfo} has four components: the player's current XP, the timestamp of the player's last level-up, the
* player's current level, and the player's next level.
*/
public class PlayerLevelInfo extends AutoSafeParcelable {
@Field(1)
private long currentXpTotal;
@Field(2)
private long lastLevelUpTimestamp;
@Field(3)
private PlayerLevel currentLevel;
@Field(4)
private PlayerLevel nextLevel;
@Hide
public PlayerLevelInfo() {
}
@Hide
public PlayerLevelInfo(long currentXpTotal, long lastLevelUpTimestamp, PlayerLevel currentLevel, PlayerLevel nextLevel) {
this.currentXpTotal = currentXpTotal;
this.lastLevelUpTimestamp = lastLevelUpTimestamp;
this.currentLevel = currentLevel;
this.nextLevel = nextLevel;
}
/**
* Getter for the player's current level object. This object will be the same as the one returned from {@link #getNextLevel()} if the
* player reached the maximum level.
*
* @return The player's current level object.
* @see #isMaxLevel()
*/
public PlayerLevel getCurrentLevel() {
return currentLevel;
}
/**
* @return The player's current XP value.
*/
public long getCurrentXpTotal() {
return currentXpTotal;
}
/**
* @return The timestamp of the player's last level-up.
*/
public long getLastLevelUpTimestamp() {
return lastLevelUpTimestamp;
}
/**
* Getter for the player's next level object. This object will be the same as the one returned from {@link #getCurrentLevel()} if the
* player reached the maximum level.
*
* @return The player's next level object.
* @see #isMaxLevel()
*/
public PlayerLevel getNextLevel() {
return nextLevel;
}
/**
* @return {@code true} if the player reached the maximum level ({@link #getCurrentLevel()} is the same as {@link #getNextLevel()}.
*/
public boolean isMaxLevel() {
return currentLevel.equals(nextLevel);
}
public static final SafeParcelableCreatorAndWriter<PlayerLevelInfo> CREATOR = findCreator(PlayerLevelInfo.class);
}

View file

@ -0,0 +1,133 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games;
import android.database.CharArrayBuffer;
import android.net.Uri;
import android.os.Parcel;
import androidx.annotation.NonNull;
import com.google.android.gms.common.data.DataBufferRef;
import com.google.android.gms.common.data.DataHolder;
import org.microg.gms.common.Hide;
@Hide
public class PlayerRef extends DataBufferRef implements Player {
public PlayerRef(DataHolder dataHolder, int position) {
super(dataHolder, position);
}
private Uri toUri(String str) {
if (str == null) return null;
return Uri.parse(str);
}
@Override
public Uri getBannerImageLandscapeUri() {
return toUri(getString(PlayerColumns.bannerImageLandscapeUri));
}
@Override
public Uri getBannerImagePortraitUri() {
return toUri(getString(PlayerColumns.bannerImagePortraitUri));
}
@Override
public CurrentPlayerInfo getCurrentPlayerInfo() {
return null;
}
@Override
public void getDisplayName(CharArrayBuffer dataOut) {
copyToBuffer(PlayerColumns.profileName, dataOut);
}
@Override
public String getDisplayName() {
return getString(PlayerColumns.profileName);
}
@Override
public Uri getHiResImageUri() {
return toUri(getString(PlayerColumns.profileHiResImageUri));
}
@Override
public Uri getIconImageUri() {
return toUri(getString(PlayerColumns.profileIconImageUri));
}
@Override
public long getLastPlayedWithTimestamp() {
return getLong(PlayerColumns.playedWithTimestamp);
}
@Override
public PlayerLevelInfo getLevelInfo() {
return null;
}
@Override
public String getPlayerId() {
return getString(PlayerColumns.externalPlayerId);
}
@Override
public PlayerRelationshipInfo getRelationshipInfo() {
return null;
}
@Override
public long getRetrievedTimestamp() {
return getLong(PlayerColumns.lastUpdated);
}
@Override
public String getTitle() {
return getString(PlayerColumns.playerTitle);
}
@Override
public void getTitle(CharArrayBuffer dataOut) {
copyToBuffer(PlayerColumns.playerTitle, dataOut);
}
@Override
public boolean hasHiResImage() {
return hasColumn(PlayerColumns.profileHiResImageUri);
}
@Override
public boolean hasIconImage() {
return hasColumn(PlayerColumns.profileIconImageUri);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
new PlayerEntity(this).writeToParcel(dest, flags);
}
@Override
public Player freeze() {
return null;
}
public static final Creator<Player> CREATOR = new Creator<Player>() {
@Override
public Player createFromParcel(Parcel source) {
return PlayerEntity.CREATOR.createFromParcel(source);
}
@Override
public Player[] newArray(int size) {
return new Player[size];
}
};
}

View file

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import android.os.Parcelable;
import com.google.android.gms.common.data.Freezable;
/**
* Data object representing the relationship information of a player.
*/
public interface PlayerRelationshipInfo extends Freezable<PlayerRelationshipInfo>, Parcelable {
/**
* Retrieves this player's friend status relative to the currently signed-in player. The possible output can be found in
* {@link Player.PlayerFriendStatus}.
*/
@Player.PlayerFriendStatus
int getFriendStatus();
}

View file

@ -0,0 +1,67 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
import org.microg.gms.common.Hide;
import org.microg.safeparcel.AutoSafeParcelable;
@Hide
public class PlayerRelationshipInfoEntity extends AutoSafeParcelable implements PlayerRelationshipInfo {
@Field(1)
@Player.PlayerFriendStatus
private int friendStatus;
@Field(2)
private String nickname;
@Field(3)
private String invitationNickname;
@Field(4)
private String nicknameAbuseReportToken;
public PlayerRelationshipInfoEntity() {
}
public PlayerRelationshipInfoEntity(PlayerRelationshipInfo copy) {
friendStatus = copy.getFriendStatus();
}
public PlayerRelationshipInfoEntity(int friendStatus, String nickname, String invitationNickname, String nicknameAbuseReportToken) {
this.friendStatus = friendStatus;
this.nickname = nickname;
this.invitationNickname = invitationNickname;
this.nicknameAbuseReportToken = nicknameAbuseReportToken;
}
@Override
@Player.PlayerFriendStatus
public int getFriendStatus() {
return friendStatus;
}
@Override
public PlayerRelationshipInfo freeze() {
return this;
}
@Override
public boolean isDataValid() {
return true;
}
public String getNickname() {
return nickname;
}
public String getInvitationNickname() {
return invitationNickname;
}
public String getNicknameAbuseReportToken() {
return nicknameAbuseReportToken;
}
public static final SafeParcelableCreatorAndWriter<PlayerRelationshipInfoEntity> CREATOR = findCreator(PlayerRelationshipInfoEntity.class);
}

View file

@ -0,0 +1,18 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
/**
* Entry point for player functionality.
*
* @deprecated Use {@link PlayersClient} instead
*/
@Deprecated
public interface Players {
}

View file

@ -0,0 +1,68 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games;
import android.app.Activity;
import android.content.Intent;
import android.os.RemoteException;
import com.google.android.gms.tasks.Task;
/**
* A client to interact with Players.
*/
public interface PlayersClient {
/**
* Used by the Player Search UI to return a list of parceled Player objects. Retrieve with {@link Intent#getParcelableArrayListExtra(String)}.
*
* @see #getPlayerSearchIntent()
*/
String EXTRA_PLAYER_SEARCH_RESULTS = "player_search_results";
/**
* Returns a {@link Task} which asynchronously loads the current signed-in {@link Player}, if available.
* <p>
* The returned {@code Task} can fail with a {@link RemoteException}.
*
* @param forceReload If {@code true}, this call will clear any locally-cached data and attempt to fetch the latest data from the server. This would
* commonly be used for something like a user-initiated refresh. Normally, this should be set to {@code false} to gain advantages
* of data caching.
*/
Task<AnnotatedData<Player>> getCurrentPlayer(boolean forceReload);
/**
* Returns a {@link Task} which asynchronously loads the current signed-in {@link Player}, if available.
* <p>
* The returned {@code Task} can fail with a {@link RemoteException}.
*/
Task<Player> getCurrentPlayer();
/**
* Returns a {@link Task} which asynchronously loads the current signed-in player ID, if available.
* <p>
* The returned {@code Task} can fail with a {@link RemoteException}.
*/
Task<String> getCurrentPlayerId();
/**
* Returns a {@link Task} which asynchronously loads an {@link Intent} that will display a screen where the user can search for players.
* <p>
* Note that this must be invoked with {@link Activity#startActivityForResult(Intent, int)}, so that the identity of the
* calling package can be established.
* <p>
* If the user canceled, the result will be {@link Activity#RESULT_CANCELED}. If the user selected any players from the search
* results list, the result will be {@link Activity#RESULT_OK}, and the data intent will contain a list of parceled Player objects in
* {@link #EXTRA_PLAYER_SEARCH_RESULTS}.
* <p>
* Note that the current Player Search UI only allows a single selection, so the returned list of parceled Player objects will
* currently contain at most one Player.
* <p>
* The returned {@code Task} can fail with a {@link RemoteException}.
*/
Task<Intent> getPlayerSearchIntent();
}

View file

@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: 2022 microG Project Team
* SPDX-License-Identifier: CC-BY-4.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
/**
* Contains classes for loading and updating achievements.
*/
package com.google.android.gms.games.achievement;

View file

@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.client;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import org.microg.gms.utils.ToStringHelper;
public class PlayGamesConsistencyTokens implements Parcelable {
public final String oneupConsistencyToken;
public final String superGlueConsistencyToken;
public PlayGamesConsistencyTokens(String oneupConsistencyToken, String superGlueConsistencyToken) {
this.oneupConsistencyToken = oneupConsistencyToken;
this.superGlueConsistencyToken = superGlueConsistencyToken;
}
@NonNull
@Override
public String toString() {
return ToStringHelper.name("PlayGamesConsistencyTokens")
.field("oneupConsistencyToken", oneupConsistencyToken)
.field("superGlueConsistencyToken", superGlueConsistencyToken)
.end();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(oneupConsistencyToken);
dest.writeString(superGlueConsistencyToken);
}
public static final Creator<PlayGamesConsistencyTokens> CREATOR = new Creator<PlayGamesConsistencyTokens>() {
@Override
public PlayGamesConsistencyTokens createFromParcel(Parcel source) {
return new PlayGamesConsistencyTokens(source.readString(), source.readString());
}
@Override
public PlayGamesConsistencyTokens[] newArray(int size) {
return new PlayGamesConsistencyTokens[size];
}
};
}

View file

@ -0,0 +1,28 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.internal.connect;
import androidx.annotation.NonNull;
import org.microg.gms.utils.ToStringHelper;
import org.microg.safeparcel.AutoSafeParcelable;
public class GamesSignInRequest extends AutoSafeParcelable {
@Field(1)
public int signInType;
@Field(2)
public SignInResolutionResult previousStepResolutionResult;
@NonNull
@Override
public String toString() {
return ToStringHelper.name("GamesSignInRequest")
.field("signInType", signInType)
.field("previousStepResolutionResult", previousStepResolutionResult)
.end();
}
public static final Creator<GamesSignInRequest> CREATOR = findCreator(GamesSignInRequest.class);
}

View file

@ -0,0 +1,14 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.internal.connect;
import org.microg.safeparcel.AutoSafeParcelable;
public class GamesSignInResponse extends AutoSafeParcelable {
@Field(1)
public String gameRunToken;
public static final Creator<GamesSignInResponse> CREATOR = findCreator(GamesSignInResponse.class);
}

View file

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.internal.connect;
import android.content.Intent;
import androidx.annotation.NonNull;
import org.microg.gms.utils.ToStringHelper;
import org.microg.safeparcel.AutoSafeParcelable;
public class SignInResolutionResult extends AutoSafeParcelable {
@Field(1)
public Intent resultData;
@NonNull
@Override
public String toString() {
return ToStringHelper.name("SignInResolutionResult").field("resultData", resultData).end();
}
public static final Creator<SignInResolutionResult> CREATOR = findCreator(SignInResolutionResult.class);
}

View file

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.internal.player;
import android.net.Uri;
import android.os.Parcelable;
import com.google.android.gms.common.data.Freezable;
public interface MostRecentGameInfo extends Freezable<MostRecentGameInfo>, Parcelable {
long getActivityTimestampMillis();
Uri getGameFeaturedImageUri();
Uri getGameHiResImageUri();
Uri getGameIconImageUri();
String getGameId();
String getGameName();
}

View file

@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2023 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.internal.player;
import android.net.Uri;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
import org.microg.gms.common.Hide;
import org.microg.safeparcel.AutoSafeParcelable;
public class MostRecentGameInfoEntity extends AutoSafeParcelable implements MostRecentGameInfo {
@Field(1)
private String gameId;
@Field(2)
private String gameName;
@Field(3)
private long activityTimestampMillis;
@Field(4)
private Uri gameIconImageUri;
@Field(5)
private Uri gameHiResImageUri;
@Field(6)
private Uri gameFeaturedImageUri;
@Hide
public MostRecentGameInfoEntity() {
}
@Hide
public MostRecentGameInfoEntity(String gameId, String gameName, long activityTimestampMillis, Uri gameIconImageUri, Uri gameHiResImageUri, Uri gameFeaturedImageUri) {
this.gameId = gameId;
this.gameName = gameName;
this.activityTimestampMillis = activityTimestampMillis;
this.gameIconImageUri = gameIconImageUri;
this.gameHiResImageUri = gameHiResImageUri;
this.gameFeaturedImageUri = gameFeaturedImageUri;
}
@Override
public long getActivityTimestampMillis() {
return activityTimestampMillis;
}
@Override
public Uri getGameFeaturedImageUri() {
return gameFeaturedImageUri;
}
@Override
public Uri getGameHiResImageUri() {
return gameHiResImageUri;
}
@Override
public Uri getGameIconImageUri() {
return gameIconImageUri;
}
@Override
public String getGameId() {
return gameId;
}
@Override
public String getGameName() {
return gameName;
}
@Override
public boolean isDataValid() {
return true;
}
@Override
public MostRecentGameInfo freeze() {
return this;
}
public static final SafeParcelableCreatorAndWriter<MostRecentGameInfoEntity> CREATOR = findCreator(MostRecentGameInfoEntity.class);
}

View file

@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: 2022 microG Project Team
* SPDX-License-Identifier: CC-BY-4.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
/**
* Contains data classes for leaderboards.
*/
package com.google.android.gms.games.leaderboard;

View file

@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrightText: 2019 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.multiplayer.realtime;
import android.os.Parcel;
import android.os.Parcelable;
import org.microg.gms.common.Hide;
@Hide
public final class RealTimeMessage implements Parcelable {
public static final int RELIABLE = 1;
public static final int UNRELIABLE = 0;
private final String senderParticipantId;
private final byte[] messageData;
private final int reliable;
public RealTimeMessage(String senderParticipantId, byte[] messageData, int reliable) {
this.senderParticipantId = senderParticipantId;
this.messageData = messageData.clone();
this.reliable = reliable;
}
private RealTimeMessage(Parcel parcel) {
this(parcel.readString(), parcel.createByteArray(), parcel.readInt());
}
public static final Creator<RealTimeMessage> CREATOR = new Creator<RealTimeMessage>() {
@Override
public RealTimeMessage createFromParcel(Parcel in) {
return new RealTimeMessage(in);
}
@Override
public RealTimeMessage[] newArray(int size) {
return new RealTimeMessage[size];
}
};
public byte[] getMessageData() {
return this.messageData;
}
public String getSenderParticipantId() {
return this.senderParticipantId;
}
public boolean isReliable() {
return this.reliable == RELIABLE;
}
@Override
public void writeToParcel(Parcel parcel, int flag) {
parcel.writeString(this.senderParticipantId);
parcel.writeByteArray(this.messageData);
parcel.writeInt(this.reliable);
}
@Override
public int describeContents() {
return 0;
}
}

View file

@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: 2022 microG Project Team
* SPDX-License-Identifier: CC-BY-4.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
/**
* Contains the games client class.
*/
package com.google.android.gms.games;

View file

@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
*/
package com.google.android.gms.games.snapshot;
import org.microg.gms.common.Hide;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Hide
public class SnapshotColumns {
public static final String EXTERNAL_SNAPSHOT_ID = "external_snapshot_id";
public static final String COVER_ICON_IMAGE_URI = "cover_icon_image_uri";
public static final String COVER_ICON_IMAGE_URL = "cover_icon_image_url";
public static final String COVER_ICON_IMAGE_HEIGHT = "cover_icon_image_height";
public static final String COVER_ICON_IMAGE_WIDTH = "cover_icon_image_width";
public static final String UNIQUE_NAME = "unique_name";
public static final String TITLE = "title";
public static final String DESCRIPTION = "description";
public static final String LAST_MODIFIED_TIMESTAMP = "last_modified_timestamp";
public static final String DURATION = "duration";
public static final String PENDING_CHANGE_COUNT = "pending_change_count";
public static final String PROGRESS_VALUE = "progress_value";
public static final String DEVICE_NAME = "device_name";
public static final List<String> CURRENT_GAME_COLUMNS = Collections.unmodifiableList(Arrays.asList(
EXTERNAL_SNAPSHOT_ID, COVER_ICON_IMAGE_URI, COVER_ICON_IMAGE_URL, COVER_ICON_IMAGE_HEIGHT,
COVER_ICON_IMAGE_WIDTH, UNIQUE_NAME, TITLE, DESCRIPTION, LAST_MODIFIED_TIMESTAMP, DURATION,
PENDING_CHANGE_COUNT, PROGRESS_VALUE, DEVICE_NAME
));
}

View file

@ -0,0 +1,144 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games.snapshot;
import android.database.CharArrayBuffer;
import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.common.data.Freezable;
import com.google.android.gms.common.images.ImageManager;
import com.google.android.gms.games.Game;
import com.google.android.gms.games.Player;
import org.microg.gms.common.Hide;
/**
* Data interface for the metadata of a saved game.
*/
public interface SnapshotMetadata extends Freezable<SnapshotMetadata> {
/**
* Constant indicating that the played time of a snapshot is unknown.
*/
long PLAYED_TIME_UNKNOWN = -1;
/**
* Constant indicating that the progress value of a snapshot is unknown.
*/
long PROGRESS_VALUE_UNKNOWN = -1;
/**
* Retrieves the aspect ratio of the cover image for this snapshot, if any. This is the ratio of width to height, so a value > 1.0f indicates a
* landscape image while a value < 1.0f indicates a portrait image. If the snapshot has no cover image, this will return 0.0f.
*
* @return The aspect ratio of the cover image, or 0.0f if no image is present.
*/
float getCoverImageAspectRatio();
/**
* Retrieves an image URI that can be used to load the snapshot's cover image. Returns null if the snapshot has no cover image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return A URI that can be used to load this snapshot's cover image, if one is present.
*/
@Nullable
Uri getCoverImageUri();
@Hide
@Deprecated
String getCoverImageUrl();
/**
* Retrieves the description of this snapshot.
*
* @return The description of this snapshot.
*/
@NonNull
String getDescription();
/**
* Loads the snapshot description into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
void getDescription(@NonNull CharArrayBuffer dataOut);
/**
* Retrieves the name of the device that wrote this snapshot, if known.
*
* @return The name of the device that wrote this snapshot, or null if not known.
*/
@Nullable
String getDeviceName();
/**
* Retrieves the game associated with this snapshot.
*
* @return The associated game.
*/
@NonNull
Game getGame();
/**
* Retrieves the last time this snapshot was modified, in millis since epoch.
*
* @return The last modification time of this snapshot.
*/
long getLastModifiedTimestamp();
/**
* Retrieves the player that owns this snapshot.
*
* @return The owning player.
*/
@NonNull
Player getOwner();
/**
* Retrieves the played time of this snapshot in milliseconds. This value is specified during the update operation. If not known, returns
* {@link #PLAYED_TIME_UNKNOWN}.
*
* @return The played time of this snapshot in milliseconds, or {@link #PLAYED_TIME_UNKNOWN} if not known.
*/
long getPlayedTime();
/**
* Retrieves the progress value for this snapshot. Can be used to provide automatic conflict resolution (see
* {@link SnapshotsClient#RESOLUTION_POLICY_HIGHEST_PROGRESS}). If not known, returns {@link #PROGRESS_VALUE_UNKNOWN}.
*
* @return Progress value for this snapshot, or {@link #PROGRESS_VALUE_UNKNOWN} if not known.
*/
long getProgressValue();
/**
* Retrieves the ID of this snapshot.
*
* @return The ID of this snapshot.
*/
@NonNull
String getSnapshotId();
/**
* Retrieves the unique identifier of this snapshot. This value can be passed to {@link SnapshotsClient#open(SnapshotMetadata)} to open the
* snapshot for modification.
* <p>
* This name should be unique within the scope of the application.
*
* @return Unique identifier of this snapshot.
*/
@NonNull
String getUniqueName();
/**
* Indicates whether or not this snapshot has any changes pending that have not been uploaded to the server. Once all changes have been
* flushed to the server, this will return false.
*
* @return Whether or not this snapshot has any outstanding changes.
*/
boolean hasChangePending();
}

View file

@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games.snapshot;
import android.graphics.Bitmap;
import androidx.annotation.Nullable;
/**
* A collection of changes to apply to the metadata of a snapshot. Fields that are not set will retain their current values.
*/
public interface SnapshotMetadataChange {
/**
* Returns the new cover image to set for the snapshot.
*/
@Nullable
Bitmap getCoverImage();
/**
* Returns the new description to set for the snapshot.
*/
@Nullable
String getDescription();
/**
* Returns the new played time to set for the snapshot.
*/
@Nullable
Long getPlayedTimeMillis();
/**
* Returns the new progress value to set for the snapshot.
*/
@Nullable
Long getProgressValue();
}

View file

@ -0,0 +1,116 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games.snapshot;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.common.data.BitmapTeleporter;
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
import org.microg.gms.common.Hide;
@Hide
@SafeParcelable.Class
public class SnapshotMetadataChangeEntity extends AbstractSafeParcelable implements SnapshotMetadataChange {
@Field(value = 1, getterName = "getDescription")
@Nullable
private final String description;
@Field(value = 2, getterName = "getPlayedTimeMillis")
@Nullable
private final Long playedTimeMillis;
@Field(value = 4, getterName = "getCoverImageUri")
@Nullable
private final Uri coverImageUri;
@Field(value = 5, getterName = "getCoverImageTeleporter")
@Nullable
private final BitmapTeleporter coverImageTeleporter;
@Field(value = 6, getterName = "getProgressValue")
@Nullable
private final Long progressValue;
@Constructor
SnapshotMetadataChangeEntity(@Nullable @Param(value = 1) String description, @Nullable @Param(value = 2) Long playedTimeMillis, @Nullable @Param(value = 5) BitmapTeleporter coverImageTeleporter, @Nullable @Param(value = 4) Uri coverImageUri, @Nullable @Param(value = 6) Long progressValue) {
this.description = description;
this.playedTimeMillis = playedTimeMillis;
this.coverImageTeleporter = coverImageTeleporter;
this.coverImageUri = coverImageUri;
this.progressValue = progressValue;
}
/**
* Returns the new cover image to set for the snapshot.
*/
@Override
@Nullable
public Bitmap getCoverImage() {
return this.coverImageTeleporter == null ? null : this.coverImageTeleporter.createTargetBitmap();
}
@Nullable
public BitmapTeleporter getCoverImageTeleporter() {
return this.coverImageTeleporter;
}
@Nullable
Uri getCoverImageUri() {
return coverImageUri;
}
/**
* Returns the new description to set for the snapshot.
*/
@Override
@Nullable
public String getDescription() {
return this.description;
}
/**
* Returns the new played time to set for the snapshot.
*/
@Override
@Nullable
public Long getPlayedTimeMillis() {
return this.playedTimeMillis;
}
/**
* Returns the new progress value to set for the snapshot.
*/
@Override
@Nullable
public Long getProgressValue() {
return this.progressValue;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
public static final SafeParcelableCreatorAndWriter<SnapshotMetadataChangeEntity> CREATOR = findCreator(SnapshotMetadataChangeEntity.class);
@Override
public String toString() {
return "SnapshotMetadataChangeEntity{" +
"description='" + description + '\'' +
", playedTimeMillis=" + playedTimeMillis +
", coverImageUri=" + coverImageUri +
", coverImageTeleporter=" + coverImageTeleporter +
", progressValue=" + progressValue +
'}';
}
}

View file

@ -0,0 +1,265 @@
/*
* SPDX-FileCopyrightText: 2024 microG Project Team
* SPDX-License-Identifier: Apache-2.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
package com.google.android.gms.games.snapshot;
import android.database.CharArrayBuffer;
import android.net.Uri;
import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.common.images.ImageManager;
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
import com.google.android.gms.games.GameEntity;
import com.google.android.gms.games.PlayerEntity;
import org.microg.gms.common.Hide;
@SafeParcelable.Class
public class SnapshotMetadataEntity extends AbstractSafeParcelable implements SnapshotMetadata {
@Field(value = 1, getterName = "getGame")
private final GameEntity game;
@Field(value = 2, getterName = "getOwner")
private final PlayerEntity player;
@Field(value = 3, getterName = "getSnapshotId")
private final String snapshotId;
@Field(value = 5, getterName = "getCoverImageUri")
@Nullable
private final Uri coverImageUri;
@Field(value = 6, getterName = "getCoverImageUrl")
@Nullable
private final String coverImageUrl;
@Field(value = 7, getterName = "getTitle")
private final String title;
@Field(value = 8, getterName = "getDescription")
private final String description;
@Field(value = 9, getterName = "getLastModifiedTimestamp")
private final long lastModifiedTimestamp;
@Field(value = 10, getterName = "getPlayedTime")
private final long playedTime;
@Field(value = 11, getterName = "getCoverImageAspectRatio")
private final float coverImageAspectRatio;
@Field(value = 12, getterName = "getUniqueName")
private final String uniqueName;
@Field(value = 13, getterName = "hasChangePending")
private final boolean hasChangePending;
@Field(value = 14, getterName = "getProgressValue")
private final long progressValue;
@Field(value = 15, getterName = "getDeviceName")
@Nullable
private final String deviceName;
@Hide
@Constructor
public SnapshotMetadataEntity(@Param(value = 1) GameEntity gameEntity, @Param(value = 2) PlayerEntity playerEntity, @Param(value = 3) String snapshotId, @Param(value = 5) @Nullable Uri coverImageUri,@Param(value = 6) @Nullable String coverImageUrl, @Param(value = 7) String title, @Param(value = 8) String description, @Param(value = 9) long lastModifiedTimestamp, @Param(value = 10) long playedTime, @Param(value = 11) float coverImageAspectRatio, @Param(value = 12) String uniqueName, @Param(value = 13) boolean hasChangePending, @Param(value = 14) long progressValue, @Param(value = 15) @Nullable String deviceName) {
this.game = gameEntity;
this.player = playerEntity;
this.snapshotId = snapshotId;
this.coverImageUri = coverImageUri;
this.coverImageUrl = coverImageUrl;
this.coverImageAspectRatio = coverImageAspectRatio;
this.title = title;
this.description = description;
this.lastModifiedTimestamp = lastModifiedTimestamp;
this.playedTime = playedTime;
this.uniqueName = uniqueName;
this.hasChangePending = hasChangePending;
this.progressValue = progressValue;
this.deviceName = deviceName;
}
@Override
public SnapshotMetadata freeze() {
return this;
}
/**
* Retrieves the aspect ratio of the cover image for this snapshot, if any. This is the ratio of width to height, so a value > 1.0f indicates a
* landscape image while a value < 1.0f indicates a portrait image. If the snapshot has no cover image, this will return 0.0f.
*
* @return The aspect ratio of the cover image, or 0.0f if no image is present.
*/
@Override
public float getCoverImageAspectRatio() {
return this.coverImageAspectRatio;
}
/**
* Retrieves an image URI that can be used to load the snapshot's cover image. Returns null if the snapshot has no cover image.
* <p>
* To retrieve the Image from the {@link Uri}, use {@link ImageManager}.
*
* @return A URI that can be used to load this snapshot's cover image, if one is present.
*/
@Override
@Nullable
public Uri getCoverImageUri() {
return this.coverImageUri;
}
@Override
@Nullable
public String getCoverImageUrl() {
return this.coverImageUrl;
}
/**
* Retrieves the description of this snapshot.
*
* @return The description of this snapshot.
*/
@Override
@NonNull
public String getDescription() {
return this.description;
}
/**
* Loads the snapshot description into the given {@link CharArrayBuffer}.
*
* @param dataOut The buffer to load the data into.
*/
@Override
public void getDescription(@NonNull CharArrayBuffer dataOut) {
copyStringToBuffer(this.description, dataOut);
}
/**
* Retrieves the name of the device that wrote this snapshot, if known.
*
* @return The name of the device that wrote this snapshot, or null if not known.
*/
@Override
@Nullable
public String getDeviceName() {
return this.deviceName;
}
/**
* Retrieves the game associated with this snapshot.
*
* @return The associated game.
*/
@Override
@NonNull
public GameEntity getGame() {
return this.game;
}
/**
* Retrieves the last time this snapshot was modified, in millis since epoch.
*
* @return The last modification time of this snapshot.
*/
@Override
public long getLastModifiedTimestamp() {
return this.lastModifiedTimestamp;
}
/**
* Retrieves the player that owns this snapshot.
*
* @return The owning player.
*/
@Override
@NonNull
public PlayerEntity getOwner() {
return this.player;
}
/**
* Retrieves the played time of this snapshot in milliseconds. This value is specified during the update operation. If not known, returns
* {@link #PLAYED_TIME_UNKNOWN}.
*
* @return The played time of this snapshot in milliseconds, or {@link #PLAYED_TIME_UNKNOWN} if not known.
*/
@Override
public long getPlayedTime() {
return this.playedTime;
}
/**
* Retrieves the progress value for this snapshot. Can be used to provide automatic conflict resolution (see
* {@link SnapshotsClient#RESOLUTION_POLICY_HIGHEST_PROGRESS}). If not known, returns {@link #PROGRESS_VALUE_UNKNOWN}.
*
* @return Progress value for this snapshot, or {@link #PROGRESS_VALUE_UNKNOWN} if not known.
*/
@Override
public long getProgressValue() {
return this.progressValue;
}
/**
* Retrieves the ID of this snapshot.
*
* @return The ID of this snapshot.
*/
@Override
@NonNull
public String getSnapshotId() {
return this.snapshotId;
}
/**
* Retrieves the unique identifier of this snapshot. This value can be passed to {@link SnapshotsClient#open(SnapshotMetadata)} to open the
* snapshot for modification.
* <p>
* This name should be unique within the scope of the application.
*
* @return Unique identifier of this snapshot.
*/
@Override
@NonNull
public String getUniqueName() {
return this.uniqueName;
}
/**
* Indicates whether or not this snapshot has any changes pending that have not been uploaded to the server. Once all changes have been
* flushed to the server, this will return false.
*
* @return Whether or not this snapshot has any outstanding changes.
*/
@Override
public boolean hasChangePending() {
return this.hasChangePending;
}
String getTitle() {
return this.title;
}
@Override
public boolean isDataValid() {
return true;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
CREATOR.writeToParcel(this, dest, flags);
}
private static void copyStringToBuffer(@Nullable String toCopy, @NonNull CharArrayBuffer dataOut) {
if (toCopy == null || toCopy.isEmpty()) {
dataOut.sizeCopied = 0;
return;
}
if (dataOut.data == null || dataOut.data.length < toCopy.length()) {
dataOut.data = toCopy.toCharArray();
} else {
toCopy.getChars(0, toCopy.length(), dataOut.data, 0);
}
dataOut.sizeCopied = toCopy.length();
}
public static final SafeParcelableCreatorAndWriter<SnapshotMetadataEntity> CREATOR = findCreator(SnapshotMetadataEntity.class);
}

View file

@ -0,0 +1,11 @@
/*
* SPDX-FileCopyrightText: 2022 microG Project Team
* SPDX-License-Identifier: CC-BY-4.0
* Notice: Portions of this file are reproduced from work created and shared by Google and used
* according to terms described in the Creative Commons 4.0 Attribution License.
* See https://developers.google.com/readme/policies for details.
*/
/**
* Contains data classes for snapshot functionality.
*/
package com.google.android.gms.games.snapshot;