From 0f5e540c2d551db59492c38930f562a587ca2754 Mon Sep 17 00:00:00 2001 From: shannonchen Date: Fri, 11 Feb 2022 21:43:11 +0000 Subject: [PATCH] Reevaluate game service when provider changes The goal is to have the system server be responsive to changes in the game service provider package and reevaluate the GameService and GameSessionService accordingly. So, for example, if the GameService component is disabled and then becomes enabled, the system server should detect that and bind to the newly enabled GameService. This is a likely real-world scenario if a game service provider uses a server-side flag to enable or disable the GameService component after install time. This change also fixes an issue where GameService#disconnect() would never be called because the service connector was always unbound before the posted disconnect() call could complete. Bug: 217215722 Test: atest CtsGameServiceTestCases GameServiceControllerTest GameServiceProviderSelectorImplTest Change-Id: I5d0a603b98f341b956ea6abe82930fa13f4f7d0e Merged-In: I5d0a603b98f341b956ea6abe82930fa13f4f7d0e --- .../server/app/GameManagerService.java | 11 +- .../server/app/GameServiceConfiguration.java | 154 ++++++++++++++++++ .../server/app/GameServiceController.java | 98 +++++++++-- .../app/GameServiceProviderConfiguration.java | 94 ----------- .../GameServiceProviderInstanceFactory.java | 5 +- ...ameServiceProviderInstanceFactoryImpl.java | 13 +- .../app/GameServiceProviderInstanceImpl.java | 10 +- .../app/GameServiceProviderSelector.java | 4 +- .../app/GameServiceProviderSelectorImpl.java | 19 ++- .../server/app/GameServiceControllerTest.java | 133 +++++++++++---- .../GameServiceProviderSelectorImplTest.java | 109 +++++++------ 11 files changed, 436 insertions(+), 214 deletions(-) create mode 100644 services/core/java/com/android/server/app/GameServiceConfiguration.java delete mode 100644 services/core/java/com/android/server/app/GameServiceProviderConfiguration.java diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java index 9ba9d78591ddd..b813bc48118a5 100644 --- a/services/core/java/com/android/server/app/GameManagerService.java +++ b/services/core/java/com/android/server/app/GameManagerService.java @@ -159,7 +159,7 @@ public final class GameManagerService extends IGameManagerService.Stub { mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_GAME_SERVICE)) { mGameServiceController = new GameServiceController( - BackgroundThread.getExecutor(), + context, BackgroundThread.getExecutor(), new GameServiceProviderSelectorImpl( context.getResources(), context.getPackageManager()), @@ -376,9 +376,10 @@ public final class GameManagerService extends IGameManagerService.Stub { /** * Called by games to communicate the current state to the platform. + * * @param packageName The client package name. - * @param gameState An object set to the current state. - * @param userId The user associated with this state. + * @param gameState An object set to the current state. + * @param userId The user associated with this state. */ public void setGameState(String packageName, @NonNull GameState gameState, @UserIdInt int userId) { @@ -1373,7 +1374,7 @@ public final class GameManagerService extends IGameManagerService.Stub { * @hide */ @VisibleForTesting - void updateConfigsForUser(@UserIdInt int userId, String ...packageNames) { + void updateConfigsForUser(@UserIdInt int userId, String... packageNames) { try { synchronized (mDeviceConfigLock) { for (final String packageName : packageNames) { @@ -1442,7 +1443,7 @@ public final class GameManagerService extends IGameManagerService.Stub { final List packages = mPackageManager.getInstalledPackagesAsUser(0, userId); return packages.stream().filter(e -> e.applicationInfo != null && e.applicationInfo.category - == ApplicationInfo.CATEGORY_GAME) + == ApplicationInfo.CATEGORY_GAME) .map(e -> e.packageName) .toArray(String[]::new); } diff --git a/services/core/java/com/android/server/app/GameServiceConfiguration.java b/services/core/java/com/android/server/app/GameServiceConfiguration.java new file mode 100644 index 0000000000000..1f31a87e157f0 --- /dev/null +++ b/services/core/java/com/android/server/app/GameServiceConfiguration.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.app; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.content.ComponentName; +import android.os.UserHandle; +import android.text.TextUtils; + +import java.util.Objects; + +/** + * Representation of a {@link android.service.games.GameService} provider configuration. + */ +final class GameServiceConfiguration { + private final String mPackageName; + @Nullable + private final GameServiceComponentConfiguration mGameServiceComponentConfiguration; + + GameServiceConfiguration( + @NonNull String packageName, + @Nullable GameServiceComponentConfiguration gameServiceComponentConfiguration) { + Objects.requireNonNull(packageName); + + mPackageName = packageName; + mGameServiceComponentConfiguration = gameServiceComponentConfiguration; + } + + @NonNull + public String getPackageName() { + return mPackageName; + } + + @Nullable + public GameServiceComponentConfiguration getGameServiceComponentConfiguration() { + return mGameServiceComponentConfiguration; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof GameServiceConfiguration)) { + return false; + } + + GameServiceConfiguration that = (GameServiceConfiguration) o; + return TextUtils.equals(mPackageName, that.mPackageName) + && Objects.equals(mGameServiceComponentConfiguration, + that.mGameServiceComponentConfiguration); + } + + @Override + public int hashCode() { + return Objects.hash(mPackageName, mGameServiceComponentConfiguration); + } + + @Override + public String toString() { + return "GameServiceConfiguration{" + + "packageName=" + + mPackageName + + ", gameServiceComponentConfiguration=" + + mGameServiceComponentConfiguration + + '}'; + } + + static final class GameServiceComponentConfiguration { + private final UserHandle mUserHandle; + private final ComponentName mGameServiceComponentName; + private final ComponentName mGameSessionServiceComponentName; + + GameServiceComponentConfiguration( + @NonNull UserHandle userHandle, @NonNull ComponentName gameServiceComponentName, + @NonNull ComponentName gameSessionServiceComponentName) { + Objects.requireNonNull(userHandle); + Objects.requireNonNull(gameServiceComponentName); + Objects.requireNonNull(gameSessionServiceComponentName); + + mUserHandle = userHandle; + mGameServiceComponentName = gameServiceComponentName; + mGameSessionServiceComponentName = gameSessionServiceComponentName; + } + + @NonNull + public UserHandle getUserHandle() { + return mUserHandle; + } + + @NonNull + public ComponentName getGameServiceComponentName() { + return mGameServiceComponentName; + } + + @NonNull + public ComponentName getGameSessionServiceComponentName() { + return mGameSessionServiceComponentName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof GameServiceComponentConfiguration)) { + return false; + } + + GameServiceComponentConfiguration that = + (GameServiceComponentConfiguration) o; + return mUserHandle.equals(that.mUserHandle) && mGameServiceComponentName.equals( + that.mGameServiceComponentName) + && mGameSessionServiceComponentName.equals( + that.mGameSessionServiceComponentName); + } + + @Override + public int hashCode() { + return Objects.hash(mUserHandle, + mGameServiceComponentName, + mGameSessionServiceComponentName); + } + + @Override + public String toString() { + return "GameServiceComponentConfiguration{" + + "userHandle=" + + mUserHandle + + ", gameServiceComponentName=" + + mGameServiceComponentName + + ", gameSessionServiceComponentName=" + + mGameSessionServiceComponentName + + "}"; + } + } +} diff --git a/services/core/java/com/android/server/app/GameServiceController.java b/services/core/java/com/android/server/app/GameServiceController.java index 397439a356f8b..db1ca97df888d 100644 --- a/services/core/java/com/android/server/app/GameServiceController.java +++ b/services/core/java/com/android/server/app/GameServiceController.java @@ -19,10 +19,17 @@ package com.android.server.app; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.WorkerThread; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.PatternMatcher; +import android.text.TextUtils; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.server.SystemService; +import com.android.server.app.GameServiceConfiguration.GameServiceComponentConfiguration; import java.util.Objects; import java.util.concurrent.Executor; @@ -36,8 +43,8 @@ import java.util.concurrent.Executor; final class GameServiceController { private static final String TAG = "GameServiceController"; - private final Object mLock = new Object(); + private final Context mContext; private final Executor mBackgroundExecutor; private final GameServiceProviderSelector mGameServiceProviderSelector; private final GameServiceProviderInstanceFactory mGameServiceProviderInstanceFactory; @@ -46,18 +53,24 @@ final class GameServiceController { @Nullable private volatile String mGameServiceProviderOverride; @Nullable + private BroadcastReceiver mGameServicePackageChangedReceiver; + @Nullable private volatile SystemService.TargetUser mCurrentForegroundUser; @GuardedBy("mLock") @Nullable - private volatile GameServiceProviderConfiguration mActiveGameServiceProviderConfiguration; + private volatile GameServiceComponentConfiguration mActiveGameServiceComponentConfiguration; @GuardedBy("mLock") @Nullable private volatile GameServiceProviderInstance mGameServiceProviderInstance; + @GuardedBy("mLock") + @Nullable + private volatile String mActiveGameServiceProviderPackage; GameServiceController( - @NonNull Executor backgroundExecutor, + @NonNull Context context, @NonNull Executor backgroundExecutor, @NonNull GameServiceProviderSelector gameServiceProviderSelector, @NonNull GameServiceProviderInstanceFactory gameServiceProviderInstanceFactory) { + mContext = context; mGameServiceProviderInstanceFactory = gameServiceProviderInstanceFactory; mBackgroundExecutor = backgroundExecutor; mGameServiceProviderSelector = gameServiceProviderSelector; @@ -139,35 +152,92 @@ final class GameServiceController { } synchronized (mLock) { - GameServiceProviderConfiguration selectedGameServiceProviderConfiguration = + final GameServiceConfiguration selectedGameServiceConfiguration = mGameServiceProviderSelector.get(mCurrentForegroundUser, mGameServiceProviderOverride); + final String gameServicePackage = + selectedGameServiceConfiguration == null ? null : + selectedGameServiceConfiguration.getPackageName(); + final GameServiceComponentConfiguration gameServiceComponentConfiguration = + selectedGameServiceConfiguration == null ? null + : selectedGameServiceConfiguration + .getGameServiceComponentConfiguration(); - boolean didActiveGameServiceProviderChanged = - !Objects.equals(selectedGameServiceProviderConfiguration, - mActiveGameServiceProviderConfiguration); - if (!didActiveGameServiceProviderChanged) { + evaluateGameServiceProviderPackageChangedListenerLocked(gameServicePackage); + + boolean didActiveGameServiceProviderChange = + !Objects.equals(gameServiceComponentConfiguration, + mActiveGameServiceComponentConfiguration); + if (!didActiveGameServiceProviderChange) { return; } if (mGameServiceProviderInstance != null) { Slog.i(TAG, "Stopping Game Service provider: " - + mActiveGameServiceProviderConfiguration); + + mActiveGameServiceComponentConfiguration); mGameServiceProviderInstance.stop(); + mGameServiceProviderInstance = null; } - mActiveGameServiceProviderConfiguration = selectedGameServiceProviderConfiguration; - - if (mActiveGameServiceProviderConfiguration == null) { + mActiveGameServiceComponentConfiguration = gameServiceComponentConfiguration; + if (mActiveGameServiceComponentConfiguration == null) { return; } Slog.i(TAG, - "Starting Game Service provider: " + mActiveGameServiceProviderConfiguration); + "Starting Game Service provider: " + mActiveGameServiceComponentConfiguration); mGameServiceProviderInstance = mGameServiceProviderInstanceFactory.create( - mActiveGameServiceProviderConfiguration); + mActiveGameServiceComponentConfiguration); mGameServiceProviderInstance.start(); } } + + @GuardedBy("mLock") + private void evaluateGameServiceProviderPackageChangedListenerLocked( + @Nullable String gameServicePackage) { + if (TextUtils.equals(mActiveGameServiceProviderPackage, gameServicePackage)) { + return; + } + + if (mGameServicePackageChangedReceiver != null) { + mContext.unregisterReceiver(mGameServicePackageChangedReceiver); + mGameServicePackageChangedReceiver = null; + } + + mActiveGameServiceProviderPackage = gameServicePackage; + + if (TextUtils.isEmpty(mActiveGameServiceProviderPackage)) { + return; + } + + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); + intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); + intentFilter.addDataScheme("package"); + intentFilter.addDataSchemeSpecificPart(gameServicePackage, PatternMatcher.PATTERN_LITERAL); + mGameServicePackageChangedReceiver = new PackageChangedBroadcastReceiver( + gameServicePackage); + mContext.registerReceiver( + mGameServicePackageChangedReceiver, + intentFilter); + } + + private final class PackageChangedBroadcastReceiver extends BroadcastReceiver { + private final String mPackageName; + + PackageChangedBroadcastReceiver(String packageName) { + mPackageName = packageName; + } + + @Override + public void onReceive(Context context, Intent intent) { + if (!TextUtils.equals(intent.getData().getSchemeSpecificPart(), mPackageName)) { + return; + } + mBackgroundExecutor.execute( + GameServiceController.this::evaluateActiveGameServiceProvider); + } + } } diff --git a/services/core/java/com/android/server/app/GameServiceProviderConfiguration.java b/services/core/java/com/android/server/app/GameServiceProviderConfiguration.java deleted file mode 100644 index 7c8f251f35fed..0000000000000 --- a/services/core/java/com/android/server/app/GameServiceProviderConfiguration.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.app; - -import android.annotation.NonNull; -import android.content.ComponentName; -import android.os.UserHandle; - -import java.util.Objects; - -/** - * Representation of a {@link android.service.games.GameService} provider configuration. - */ -final class GameServiceProviderConfiguration { - private final UserHandle mUserHandle; - private final ComponentName mGameServiceComponentName; - private final ComponentName mGameSessionServiceComponentName; - - GameServiceProviderConfiguration( - @NonNull UserHandle userHandle, - @NonNull ComponentName gameServiceComponentName, - @NonNull ComponentName gameSessionServiceComponentName) { - Objects.requireNonNull(userHandle); - Objects.requireNonNull(gameServiceComponentName); - Objects.requireNonNull(gameSessionServiceComponentName); - - this.mUserHandle = userHandle; - this.mGameServiceComponentName = gameServiceComponentName; - this.mGameSessionServiceComponentName = gameSessionServiceComponentName; - } - - @NonNull - public UserHandle getUserHandle() { - return mUserHandle; - } - - @NonNull - public ComponentName getGameServiceComponentName() { - return mGameServiceComponentName; - } - - @NonNull - public ComponentName getGameSessionServiceComponentName() { - return mGameSessionServiceComponentName; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (!(o instanceof GameServiceProviderConfiguration)) { - return false; - } - - GameServiceProviderConfiguration that = (GameServiceProviderConfiguration) o; - return mUserHandle.equals(that.mUserHandle) - && mGameServiceComponentName.equals(that.mGameServiceComponentName) - && mGameSessionServiceComponentName.equals(that.mGameSessionServiceComponentName); - } - - @Override - public int hashCode() { - return Objects.hash(mUserHandle, mGameServiceComponentName, - mGameSessionServiceComponentName); - } - - @Override - public String toString() { - return "GameServiceProviderConfiguration{" - + "mUserHandle=" - + mUserHandle - + ", gameServiceComponentName=" - + mGameServiceComponentName - + ", gameSessionServiceComponentName=" - + mGameSessionServiceComponentName - + '}'; - } -} diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactory.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactory.java index 7640cc555446f..7dfaec0fc7ab8 100644 --- a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactory.java +++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactory.java @@ -18,12 +18,13 @@ package com.android.server.app; import android.annotation.NonNull; +import com.android.server.app.GameServiceConfiguration.GameServiceComponentConfiguration; + /** * Factory for creating {@link GameServiceProviderInstance}. */ interface GameServiceProviderInstanceFactory { @NonNull - GameServiceProviderInstance create(@NonNull - GameServiceProviderConfiguration gameServiceProviderConfiguration); + GameServiceProviderInstance create(@NonNull GameServiceComponentConfiguration configuration); } diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java index 73278e4710626..0abab6aafe736 100644 --- a/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java +++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceFactoryImpl.java @@ -30,6 +30,7 @@ import android.service.games.IGameSessionService; import com.android.internal.infra.ServiceConnector; import com.android.internal.os.BackgroundThread; import com.android.server.LocalServices; +import com.android.server.app.GameServiceConfiguration.GameServiceComponentConfiguration; import com.android.server.wm.WindowManagerInternal; import com.android.server.wm.WindowManagerService; @@ -43,9 +44,9 @@ final class GameServiceProviderInstanceFactoryImpl implements GameServiceProvide @NonNull @Override public GameServiceProviderInstance create( - @NonNull GameServiceProviderConfiguration gameServiceProviderConfiguration) { + @NonNull GameServiceComponentConfiguration configuration) { return new GameServiceProviderInstanceImpl( - gameServiceProviderConfiguration.getUserHandle(), + configuration.getUserHandle(), BackgroundThread.getExecutor(), mContext, new GameClassifierImpl(mContext.getPackageManager()), @@ -53,8 +54,8 @@ final class GameServiceProviderInstanceFactoryImpl implements GameServiceProvide ActivityTaskManager.getService(), (WindowManagerService) ServiceManager.getService(Context.WINDOW_SERVICE), LocalServices.getService(WindowManagerInternal.class), - new GameServiceConnector(mContext, gameServiceProviderConfiguration), - new GameSessionServiceConnector(mContext, gameServiceProviderConfiguration)); + new GameServiceConnector(mContext, configuration), + new GameSessionServiceConnector(mContext, configuration)); } private static final class GameServiceConnector extends ServiceConnector.Impl { @@ -63,7 +64,7 @@ final class GameServiceProviderInstanceFactoryImpl implements GameServiceProvide GameServiceConnector( @NonNull Context context, - @NonNull GameServiceProviderConfiguration configuration) { + @NonNull GameServiceComponentConfiguration configuration) { super(context, new Intent(GameService.ACTION_GAME_SERVICE) .setComponent(configuration.getGameServiceComponentName()), BINDING_FLAGS, configuration.getUserHandle().getIdentifier(), @@ -86,7 +87,7 @@ final class GameServiceProviderInstanceFactoryImpl implements GameServiceProvide GameSessionServiceConnector( @NonNull Context context, - @NonNull GameServiceProviderConfiguration configuration) { + @NonNull GameServiceComponentConfiguration configuration) { super(context, new Intent(GameSessionService.ACTION_GAME_SESSION_SERVICE) .setComponent(configuration.getGameSessionServiceComponentName()), BINDING_FLAGS, configuration.getUserHandle().getIdentifier(), diff --git a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java index 4eba77168b8e5..e8d9dadcb17af 100644 --- a/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java +++ b/services/core/java/com/android/server/app/GameServiceProviderInstanceImpl.java @@ -244,11 +244,11 @@ final class GameServiceProviderInstanceImpl implements GameServiceProviderInstan // TODO(b/204503192): It is possible that the game service is disconnected. In this // case we should avoid rebinding just to shut it down again. - AndroidFuture unusedPostDisconnectedFuture = - mGameServiceConnector.post(gameService -> { - gameService.disconnected(); - }); - mGameServiceConnector.unbind(); + mGameServiceConnector.post(gameService -> { + gameService.disconnected(); + }).whenComplete((result, t) -> { + mGameServiceConnector.unbind(); + }); mGameSessionServiceConnector.unbind(); } diff --git a/services/core/java/com/android/server/app/GameServiceProviderSelector.java b/services/core/java/com/android/server/app/GameServiceProviderSelector.java index 0f55b9ff31f44..d125f214751b6 100644 --- a/services/core/java/com/android/server/app/GameServiceProviderSelector.java +++ b/services/core/java/com/android/server/app/GameServiceProviderSelector.java @@ -26,10 +26,10 @@ import com.android.server.SystemService; interface GameServiceProviderSelector { /** - * Returns the {@link GameServiceProviderConfiguration} associated with the selected Game + * Returns the {@link GameServiceConfiguration} associated with the selected Game * Service provider for the given user or {@code null} if none should be used. */ @Nullable - GameServiceProviderConfiguration get(@Nullable SystemService.TargetUser user, + GameServiceConfiguration get(@Nullable SystemService.TargetUser user, @Nullable String packageNameOverride); } diff --git a/services/core/java/com/android/server/app/GameServiceProviderSelectorImpl.java b/services/core/java/com/android/server/app/GameServiceProviderSelectorImpl.java index c1ad6685fbbbe..fc8530874a6ff 100644 --- a/services/core/java/com/android/server/app/GameServiceProviderSelectorImpl.java +++ b/services/core/java/com/android/server/app/GameServiceProviderSelectorImpl.java @@ -34,6 +34,7 @@ import android.util.Slog; import android.util.Xml; import com.android.server.SystemService; +import com.android.server.app.GameServiceConfiguration.GameServiceComponentConfiguration; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -57,7 +58,7 @@ final class GameServiceProviderSelectorImpl implements GameServiceProviderSelect @Override @Nullable - public GameServiceProviderConfiguration get(@Nullable SystemService.TargetUser user, + public GameServiceConfiguration get(@Nullable SystemService.TargetUser user, @Nullable String packageNameOverride) { if (user == null) { return null; @@ -98,10 +99,10 @@ final class GameServiceProviderSelectorImpl implements GameServiceProviderSelect if (gameServiceResolveInfos == null || gameServiceResolveInfos.isEmpty()) { Slog.w(TAG, "No available game service found for user id: " + userId); - return null; + return new GameServiceConfiguration(gameServicePackage, null); } - GameServiceProviderConfiguration selectedProvider = null; + GameServiceConfiguration selectedProvider = null; for (ResolveInfo resolveInfo : gameServiceResolveInfos) { if (resolveInfo.serviceInfo == null) { continue; @@ -115,16 +116,18 @@ final class GameServiceProviderSelectorImpl implements GameServiceProviderSelect } selectedProvider = - new GameServiceProviderConfiguration( - new UserHandle(userId), - gameServiceServiceInfo.getComponentName(), - gameSessionServiceComponentName); + new GameServiceConfiguration( + gameServicePackage, + new GameServiceComponentConfiguration( + new UserHandle(userId), + gameServiceServiceInfo.getComponentName(), + gameSessionServiceComponentName)); break; } if (selectedProvider == null) { Slog.w(TAG, "No valid game service found for user id: " + userId); - return null; + return new GameServiceConfiguration(gameServicePackage, null); } return selectedProvider; diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java index 1c480eef96a1a..03eff2a1831b2 100644 --- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java @@ -20,13 +20,18 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSess import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import android.content.BroadcastReceiver; import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; import android.content.pm.UserInfo; +import android.net.Uri; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; @@ -35,11 +40,13 @@ import androidx.test.runner.AndroidJUnit4; import com.android.internal.util.ConcurrentUtils; import com.android.server.SystemService; +import com.android.server.app.GameServiceConfiguration.GameServiceComponentConfiguration; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.Mockito; @@ -61,10 +68,14 @@ public final class GameServiceControllerTest { new ComponentName(PROVIDER_A_PACKAGE_NAME, "com.provider.a.ServiceA"); private static final ComponentName PROVIDER_A_SERVICE_B = new ComponentName(PROVIDER_A_PACKAGE_NAME, "com.provider.a.ServiceB"); + private static final ComponentName PROVIDER_A_SERVICE_C = + new ComponentName(PROVIDER_A_PACKAGE_NAME, "com.provider.a.ServiceC"); private MockitoSession mMockingSession; private GameServiceController mGameServiceManager; @Mock + private Context mMockContext; + @Mock private GameServiceProviderSelector mMockGameServiceProviderSelector; @Mock private GameServiceProviderInstanceFactory mMockGameServiceProviderInstanceFactory; @@ -77,7 +88,7 @@ public final class GameServiceControllerTest { .startMocking(); mGameServiceManager = new GameServiceController( - ConcurrentUtils.DIRECT_EXECUTOR, + mMockContext, ConcurrentUtils.DIRECT_EXECUTOR, mMockGameServiceProviderSelector, mMockGameServiceProviderInstanceFactory); } @@ -96,25 +107,30 @@ public final class GameServiceControllerTest { @Test public void notifyUserStarted_createsAndStartsNewInstance() { - GameServiceProviderConfiguration configurationA = - new GameServiceProviderConfiguration(USER_HANDLE_10, PROVIDER_A_SERVICE_A, - PROVIDER_A_SERVICE_B); + GameServiceConfiguration configurationA = + new GameServiceConfiguration(PROVIDER_A_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + PROVIDER_A_SERVICE_A, + PROVIDER_A_SERVICE_B)); FakeGameServiceProviderInstance instanceA = seedConfigurationForUser(USER_10, configurationA); mGameServiceManager.onBootComplete(); mGameServiceManager.notifyUserStarted(USER_10); - verify(mMockGameServiceProviderInstanceFactory).create(configurationA); + verify(mMockGameServiceProviderInstanceFactory).create( + configurationA.getGameServiceComponentConfiguration()); verifyNoMoreInteractions(mMockGameServiceProviderInstanceFactory); assertThat(instanceA.getIsRunning()).isTrue(); } @Test public void notifyUserStarted_sameUser_doesNotCreateNewInstance() { - GameServiceProviderConfiguration configurationA = - new GameServiceProviderConfiguration(USER_HANDLE_10, PROVIDER_A_SERVICE_A, - PROVIDER_A_SERVICE_B); + GameServiceConfiguration configurationA = + new GameServiceConfiguration(PROVIDER_A_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + PROVIDER_A_SERVICE_A, + PROVIDER_A_SERVICE_B)); FakeGameServiceProviderInstance instanceA = seedConfigurationForUser(USER_10, configurationA); @@ -122,16 +138,19 @@ public final class GameServiceControllerTest { mGameServiceManager.notifyUserStarted(USER_10); mGameServiceManager.notifyUserStarted(USER_10); - verify(mMockGameServiceProviderInstanceFactory).create(configurationA); + verify(mMockGameServiceProviderInstanceFactory).create( + configurationA.getGameServiceComponentConfiguration()); verifyNoMoreInteractions(mMockGameServiceProviderInstanceFactory); assertThat(instanceA.getIsRunning()).isTrue(); } @Test public void notifyUserUnlocking_noForegroundUser_ignores() { - GameServiceProviderConfiguration configurationA = - new GameServiceProviderConfiguration(USER_HANDLE_10, PROVIDER_A_SERVICE_A, - PROVIDER_A_SERVICE_B); + GameServiceConfiguration configurationA = + new GameServiceConfiguration(PROVIDER_A_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + PROVIDER_A_SERVICE_A, + PROVIDER_A_SERVICE_B)); FakeGameServiceProviderInstance instanceA = seedConfigurationForUser(USER_10, configurationA); @@ -144,9 +163,11 @@ public final class GameServiceControllerTest { @Test public void notifyUserUnlocking_sameAsForegroundUser_evaluatesProvider() { - GameServiceProviderConfiguration configurationA = - new GameServiceProviderConfiguration(USER_HANDLE_10, PROVIDER_A_SERVICE_A, - PROVIDER_A_SERVICE_B); + GameServiceConfiguration configurationA = + new GameServiceConfiguration(PROVIDER_A_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + PROVIDER_A_SERVICE_A, + PROVIDER_A_SERVICE_B)); seedNoConfigurationForUser(USER_10); mGameServiceManager.onBootComplete(); @@ -155,16 +176,19 @@ public final class GameServiceControllerTest { seedConfigurationForUser(USER_10, configurationA); mGameServiceManager.notifyUserUnlocking(USER_10); - verify(mMockGameServiceProviderInstanceFactory).create(configurationA); + verify(mMockGameServiceProviderInstanceFactory).create( + configurationA.getGameServiceComponentConfiguration()); verifyNoMoreInteractions(mMockGameServiceProviderInstanceFactory); assertThat(instanceA.getIsRunning()).isTrue(); } @Test public void notifyUserUnlocking_differentFromForegroundUser_ignores() { - GameServiceProviderConfiguration configurationA = - new GameServiceProviderConfiguration(USER_HANDLE_10, PROVIDER_A_SERVICE_A, - PROVIDER_A_SERVICE_B); + GameServiceConfiguration configurationA = + new GameServiceConfiguration(PROVIDER_A_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + PROVIDER_A_SERVICE_A, + PROVIDER_A_SERVICE_B)); seedNoConfigurationForUser(USER_10); mGameServiceManager.onBootComplete(); @@ -180,14 +204,18 @@ public final class GameServiceControllerTest { @Test public void notifyNewForegroundUser_differentUser_stopsPreviousInstanceAndThenStartsNewInstance() { - GameServiceProviderConfiguration configurationA = - new GameServiceProviderConfiguration(USER_HANDLE_10, PROVIDER_A_SERVICE_A, - PROVIDER_A_SERVICE_B); + GameServiceConfiguration configurationA = + new GameServiceConfiguration(PROVIDER_A_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + PROVIDER_A_SERVICE_A, + PROVIDER_A_SERVICE_B)); FakeGameServiceProviderInstance instanceA = seedConfigurationForUser(USER_10, configurationA); - GameServiceProviderConfiguration configurationB = - new GameServiceProviderConfiguration(USER_HANDLE_11, PROVIDER_A_SERVICE_A, - PROVIDER_A_SERVICE_B); + GameServiceConfiguration configurationB = + new GameServiceConfiguration(PROVIDER_A_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_11, + PROVIDER_A_SERVICE_A, + PROVIDER_A_SERVICE_B)); FakeGameServiceProviderInstance instanceB = seedConfigurationForUser(USER_11, configurationB); InOrder instancesInOrder = Mockito.inOrder(instanceA, instanceB); @@ -196,8 +224,50 @@ public final class GameServiceControllerTest { mGameServiceManager.notifyUserStarted(USER_10); mGameServiceManager.notifyNewForegroundUser(USER_11); - verify(mMockGameServiceProviderInstanceFactory).create(configurationA); - verify(mMockGameServiceProviderInstanceFactory).create(configurationB); + verify(mMockGameServiceProviderInstanceFactory).create( + configurationA.getGameServiceComponentConfiguration()); + verify(mMockGameServiceProviderInstanceFactory).create( + configurationB.getGameServiceComponentConfiguration()); + instancesInOrder.verify(instanceA).start(); + instancesInOrder.verify(instanceA).stop(); + instancesInOrder.verify(instanceB).start(); + verifyNoMoreInteractions(mMockGameServiceProviderInstanceFactory); + assertThat(instanceA.getIsRunning()).isFalse(); + assertThat(instanceB.getIsRunning()).isTrue(); + } + + @Test + public void packageChanges_reevaluatesGameServiceProvider() { + GameServiceConfiguration configurationA = + new GameServiceConfiguration(PROVIDER_A_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + PROVIDER_A_SERVICE_A, + PROVIDER_A_SERVICE_B)); + FakeGameServiceProviderInstance instanceA = + seedConfigurationForUser(USER_10, configurationA); + + mGameServiceManager.onBootComplete(); + mGameServiceManager.notifyUserStarted(USER_10); + ArgumentCaptor broadcastReceiverArgumentCaptor = + ArgumentCaptor.forClass(BroadcastReceiver.class); + verify(mMockContext).registerReceiver(broadcastReceiverArgumentCaptor.capture(), any()); + + GameServiceConfiguration configurationB = + new GameServiceConfiguration(PROVIDER_A_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + PROVIDER_A_SERVICE_A, + PROVIDER_A_SERVICE_C)); + FakeGameServiceProviderInstance instanceB = + seedConfigurationForUser(USER_10, configurationA); + Intent intent = new Intent(); + intent.setData(Uri.parse("package:" + PROVIDER_A_PACKAGE_NAME)); + broadcastReceiverArgumentCaptor.getValue().onReceive(mMockContext, intent); + + InOrder instancesInOrder = Mockito.inOrder(instanceA, instanceB); + verify(mMockGameServiceProviderInstanceFactory).create( + configurationA.getGameServiceComponentConfiguration()); + verify(mMockGameServiceProviderInstanceFactory).create( + configurationB.getGameServiceComponentConfiguration()); instancesInOrder.verify(instanceA).start(); instancesInOrder.verify(instanceA).stop(); instancesInOrder.verify(instanceB).start(); @@ -207,15 +277,16 @@ public final class GameServiceControllerTest { } private void seedNoConfigurationForUser(SystemService.TargetUser user) { - when(mMockGameServiceProviderSelector.get(user, "")).thenReturn(null); + when(mMockGameServiceProviderSelector.get(user, null)).thenReturn(null); } private FakeGameServiceProviderInstance seedConfigurationForUser(SystemService.TargetUser user, - GameServiceProviderConfiguration configuration) { - when(mMockGameServiceProviderSelector.get(user, "")).thenReturn(configuration); + GameServiceConfiguration configuration) { + when(mMockGameServiceProviderSelector.get(user, null)).thenReturn(configuration); FakeGameServiceProviderInstance instanceForConfiguration = spy(new FakeGameServiceProviderInstance()); - when(mMockGameServiceProviderInstanceFactory.create(configuration)) + when(mMockGameServiceProviderInstanceFactory.create( + configuration.getGameServiceComponentConfiguration())) .thenReturn(instanceForConfiguration); return instanceForConfiguration; diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderSelectorImplTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderSelectorImplTest.java index 23a6a49856f7d..cf9ba1e2638f0 100644 --- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderSelectorImplTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderSelectorImplTest.java @@ -18,6 +18,7 @@ package com.android.server.app; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.google.common.truth.Truth.assertThat; @@ -26,7 +27,6 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.ComponentName; @@ -49,6 +49,7 @@ import androidx.test.platform.app.InstrumentationRegistry; import androidx.test.runner.AndroidJUnit4; import com.android.server.SystemService; +import com.android.server.app.GameServiceConfiguration.GameServiceComponentConfiguration; import com.google.common.collect.ImmutableList; @@ -137,10 +138,10 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_valid.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(null, null); - assertThat(gameServiceProviderConfiguration).isNull(); + assertThat(gameServiceConfiguration).isNull(); } @Test @@ -154,15 +155,16 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_valid.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(managedTargetUser(USER_HANDLE_10), null); - assertThat(gameServiceProviderConfiguration).isNull(); + assertThat(gameServiceConfiguration).isNull(); } @Test public void get_noSystemGameService_returnsNull() throws Exception { + seedSystemGameServicePackageName(""); seedGameServiceResolveInfos(GAME_SERVICE_PACKAGE_NAME, USER_HANDLE_10, resolveInfo(GAME_SERVICE_SERVICE_INFO)); seedServiceServiceInfo(GAME_SESSION_SERVICE_COMPONENT); @@ -170,14 +172,14 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_valid.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(eligibleTargetUser(USER_HANDLE_10), null); - assertThat(gameServiceProviderConfiguration).isNull(); + assertThat(gameServiceConfiguration).isNull(); } @Test - public void get_noGameServiceProvidersAvailable_returnsNull() + public void get_noGameServiceProvidersAvailable_returnsGameServicePackageName() throws Exception { seedSystemGameServicePackageName(GAME_SERVICE_PACKAGE_NAME); seedGameServiceResolveInfos(GAME_SERVICE_PACKAGE_NAME, USER_HANDLE_10); @@ -186,28 +188,30 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_valid.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(eligibleTargetUser(USER_HANDLE_10), null); - assertThat(gameServiceProviderConfiguration).isNull(); + assertThat(gameServiceConfiguration).isEqualTo( + new GameServiceConfiguration(GAME_SERVICE_PACKAGE_NAME, null)); } @Test - public void get_gameServiceProviderHasNoMetaData_returnsNull() + public void get_gameServiceProviderHasNoMetaData_returnsGameServicePackageName() throws Exception { seedSystemGameServicePackageName(GAME_SERVICE_PACKAGE_NAME); seedGameServiceResolveInfos(GAME_SERVICE_PACKAGE_NAME, USER_HANDLE_10, resolveInfo(GAME_SERVICE_SERVICE_INFO_WITHOUT_META_DATA)); seedServiceServiceInfo(GAME_SESSION_SERVICE_COMPONENT); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(eligibleTargetUser(USER_HANDLE_10), null); - assertThat(gameServiceProviderConfiguration).isNull(); + assertThat(gameServiceConfiguration).isEqualTo( + new GameServiceConfiguration(GAME_SERVICE_PACKAGE_NAME, null)); } @Test - public void get_gameSessionServiceDoesNotExist_returnsNull() + public void get_gameSessionServiceDoesNotExist_returnsGameServicePackageName() throws Exception { seedSystemGameServicePackageName(GAME_SERVICE_PACKAGE_NAME); seedGameServiceResolveInfos(GAME_SERVICE_PACKAGE_NAME, USER_HANDLE_10, @@ -217,14 +221,15 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_valid.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(eligibleTargetUser(USER_HANDLE_10), null); - assertThat(gameServiceProviderConfiguration).isNull(); + assertThat(gameServiceConfiguration).isEqualTo( + new GameServiceConfiguration(GAME_SERVICE_PACKAGE_NAME, null)); } @Test - public void get_metaDataWrongFirstTag_returnsNull() throws Exception { + public void get_metaDataWrongFirstTag_returnsGameServicePackageName() throws Exception { seedSystemGameServicePackageName(GAME_SERVICE_PACKAGE_NAME); seedGameServiceResolveInfos(GAME_SERVICE_PACKAGE_NAME, USER_HANDLE_10, resolveInfo(GAME_SERVICE_SERVICE_INFO)); @@ -233,10 +238,11 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_wrong_first_tag.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(eligibleTargetUser(USER_HANDLE_10), null); - assertThat(gameServiceProviderConfiguration).isNull(); + assertThat(gameServiceConfiguration).isEqualTo( + new GameServiceConfiguration(GAME_SERVICE_PACKAGE_NAME, null)); } @Test @@ -250,15 +256,17 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_valid.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(eligibleTargetUser(USER_HANDLE_10), null); - GameServiceProviderConfiguration expectedGameServiceProviderConfiguration = - new GameServiceProviderConfiguration(USER_HANDLE_10, - GAME_SERVICE_COMPONENT, - GAME_SESSION_SERVICE_COMPONENT); - assertThat(gameServiceProviderConfiguration).isEqualTo( - expectedGameServiceProviderConfiguration); + GameServiceConfiguration expectedGameServiceConfiguration = + new GameServiceConfiguration( + GAME_SERVICE_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + GAME_SERVICE_COMPONENT, + GAME_SESSION_SERVICE_COMPONENT)); + assertThat(gameServiceConfiguration).isEqualTo( + expectedGameServiceConfiguration); } @Test @@ -276,15 +284,17 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_valid.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(eligibleTargetUser(USER_HANDLE_10), null); - GameServiceProviderConfiguration expectedGameServiceProviderConfiguration = - new GameServiceProviderConfiguration(USER_HANDLE_10, - GAME_SERVICE_B_COMPONENT, - GAME_SESSION_SERVICE_COMPONENT); - assertThat(gameServiceProviderConfiguration).isEqualTo( - expectedGameServiceProviderConfiguration); + GameServiceConfiguration expectedGameServiceConfiguration = + new GameServiceConfiguration( + GAME_SERVICE_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + GAME_SERVICE_B_COMPONENT, + GAME_SESSION_SERVICE_COMPONENT)); + assertThat(gameServiceConfiguration).isEqualTo( + expectedGameServiceConfiguration); } @Test @@ -299,15 +309,17 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_valid.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(eligibleTargetUser(USER_HANDLE_10), null); - GameServiceProviderConfiguration expectedGameServiceProviderConfiguration = - new GameServiceProviderConfiguration(USER_HANDLE_10, - GAME_SERVICE_COMPONENT, - GAME_SESSION_SERVICE_COMPONENT); - assertThat(gameServiceProviderConfiguration).isEqualTo( - expectedGameServiceProviderConfiguration); + GameServiceConfiguration expectedGameServiceConfiguration = + new GameServiceConfiguration( + GAME_SERVICE_PACKAGE_NAME, + new GameServiceComponentConfiguration(USER_HANDLE_10, + GAME_SERVICE_COMPONENT, + GAME_SESSION_SERVICE_COMPONENT)); + assertThat(gameServiceConfiguration).isEqualTo( + expectedGameServiceConfiguration); } @Test @@ -322,16 +334,19 @@ public final class GameServiceProviderSelectorImplTest { GAME_SERVICE_META_DATA_RES_ID, "res/xml/game_service_metadata_valid.xml"); - GameServiceProviderConfiguration gameServiceProviderConfiguration = + GameServiceConfiguration gameServiceConfiguration = mGameServiceProviderSelector.get(eligibleTargetUser(USER_HANDLE_10), GAME_SERVICE_PACKAGE_NAME); - GameServiceProviderConfiguration expectedGameServiceProviderConfiguration = - new GameServiceProviderConfiguration(USER_HANDLE_10, - GAME_SERVICE_COMPONENT, - GAME_SESSION_SERVICE_COMPONENT); - assertThat(gameServiceProviderConfiguration).isEqualTo( - expectedGameServiceProviderConfiguration); + GameServiceConfiguration expectedGameServiceConfiguration = + new GameServiceConfiguration( + GAME_SERVICE_PACKAGE_NAME, + new GameServiceComponentConfiguration( + USER_HANDLE_10, + GAME_SERVICE_COMPONENT, + GAME_SESSION_SERVICE_COMPONENT)); + assertThat(gameServiceConfiguration).isEqualTo( + expectedGameServiceConfiguration); } private void seedSystemGameServicePackageName(String gameServicePackageName) {