From 83a71ca8fd8d8d81b370929f1102742bcce21a7d Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Fri, 14 May 2021 19:34:37 +0000 Subject: [PATCH] Add Game settings support. Add Game settings page under Apps so that users can access game related features and toggle settings. Bug: b/185822999 Test: make ROBOTEST_FILTER=GameSettingsPreferenceControllerTest RunSettingsRoboTests Change-Id: I923ba70536b7f68b5330a508b8dabf27e33f4c55 --- res/values/strings.xml | 5 ++ res/xml/apps.xml | 8 +++ .../GameSettingsFeatureProvider.java | 34 ++++++++++ .../GameSettingsFeatureProviderImpl.java | 35 ++++++++++ .../GameSettingsPreferenceController.java | 60 +++++++++++++++++ .../settings/overlay/FeatureFactory.java | 6 ++ .../settings/overlay/FeatureFactoryImpl.java | 11 ++++ .../GameSettingsPreferenceControllerTest.java | 65 +++++++++++++++++++ .../testutils/FakeFeatureFactory.java | 8 +++ .../testutils/FakeFeatureFactory.java | 8 +++ 10 files changed, 240 insertions(+) create mode 100644 src/com/android/settings/applications/GameSettingsFeatureProvider.java create mode 100644 src/com/android/settings/applications/GameSettingsFeatureProviderImpl.java create mode 100644 src/com/android/settings/applications/GameSettingsPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/applications/GameSettingsPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index e530ab990a9..eec245c7aa9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -13292,4 +13292,9 @@ Microphone access For all apps and services + + + Game settings + + Turn on Game Dashboard shortcut, etc diff --git a/res/xml/apps.xml b/res/xml/apps.xml index 68b5c9a9617..a7d823b918d 100644 --- a/res/xml/apps.xml +++ b/res/xml/apps.xml @@ -62,6 +62,14 @@ + + + diff --git a/src/com/android/settings/applications/GameSettingsFeatureProvider.java b/src/com/android/settings/applications/GameSettingsFeatureProvider.java new file mode 100644 index 00000000000..ac2d6bddbe5 --- /dev/null +++ b/src/com/android/settings/applications/GameSettingsFeatureProvider.java @@ -0,0 +1,34 @@ +/* + * 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.settings.applications; + +import android.content.Context; + +/** + * Provider for Game Settings related feature. + */ +public interface GameSettingsFeatureProvider { + /** + * Returns true if the feature is supported. + */ + boolean isSupported(Context context); + + /** + * Launch GameSettings + */ + void launchGameSettings(Context context); +} diff --git a/src/com/android/settings/applications/GameSettingsFeatureProviderImpl.java b/src/com/android/settings/applications/GameSettingsFeatureProviderImpl.java new file mode 100644 index 00000000000..67212e7da8b --- /dev/null +++ b/src/com/android/settings/applications/GameSettingsFeatureProviderImpl.java @@ -0,0 +1,35 @@ +/* + * 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.settings.applications; + +import android.content.Context; + +/** + * Provider implementation for Game Settings related features. + */ +public class GameSettingsFeatureProviderImpl implements + GameSettingsFeatureProvider { + @Override + public boolean isSupported(Context context) { + return false; + } + + @Override + public void launchGameSettings(Context context) { + return; + } +} diff --git a/src/com/android/settings/applications/GameSettingsPreferenceController.java b/src/com/android/settings/applications/GameSettingsPreferenceController.java new file mode 100644 index 00000000000..67c1bb1fea1 --- /dev/null +++ b/src/com/android/settings/applications/GameSettingsPreferenceController.java @@ -0,0 +1,60 @@ +/* + * 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.settings.applications; + +import android.content.Context; +import android.text.TextUtils; + +import androidx.preference.Preference; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.overlay.FeatureFactory; + +/** Contains logic that deals with showing Game Settings in app settings. */ +public class GameSettingsPreferenceController extends BasePreferenceController { + + @VisibleForTesting + final GameSettingsFeatureProvider mGameSettingsFeatureProvider; + + public GameSettingsPreferenceController(Context context, String key) { + super(context, key); + mGameSettingsFeatureProvider = + FeatureFactory.getFactory(context).getGameSettingsFeatureProvider(); + } + + GameSettingsPreferenceController(Context context, String key, + GameSettingsFeatureProvider gameSettingsFeatureProvider) { + super(context, key); + mGameSettingsFeatureProvider = gameSettingsFeatureProvider; + } + + @Override + public int getAvailabilityStatus() { + return mGameSettingsFeatureProvider.isSupported(mContext) + ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (TextUtils.equals(getPreferenceKey(), preference.getKey())) { + mGameSettingsFeatureProvider.launchGameSettings(mContext); + return true; + } + return super.handlePreferenceTreeClick(preference); + } +} diff --git a/src/com/android/settings/overlay/FeatureFactory.java b/src/com/android/settings/overlay/FeatureFactory.java index e7b23b9ab4b..58f80fce225 100644 --- a/src/com/android/settings/overlay/FeatureFactory.java +++ b/src/com/android/settings/overlay/FeatureFactory.java @@ -25,6 +25,7 @@ import androidx.annotation.Nullable; import com.android.settings.R; import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider; +import com.android.settings.applications.GameSettingsFeatureProvider; import com.android.settings.applications.appinfo.ExtraAppInfoFeatureProvider; import com.android.settings.aware.AwareFeatureProvider; import com.android.settings.biometrics.face.FaceFeatureProvider; @@ -168,6 +169,11 @@ public abstract class FeatureFactory { */ public abstract SecuritySettingsFeatureProvider getSecuritySettingsFeatureProvider(); + /** + * Retrieve implementation for Game Settings feature. + */ + public abstract GameSettingsFeatureProvider getGameSettingsFeatureProvider(); + public static final class FactoryNotFoundException extends RuntimeException { public FactoryNotFoundException(Throwable throwable) { super("Unable to create factory. Did you misconfigure Proguard?", throwable); diff --git a/src/com/android/settings/overlay/FeatureFactoryImpl.java b/src/com/android/settings/overlay/FeatureFactoryImpl.java index 00f9a0e6b63..13b7b604de1 100644 --- a/src/com/android/settings/overlay/FeatureFactoryImpl.java +++ b/src/com/android/settings/overlay/FeatureFactoryImpl.java @@ -29,6 +29,8 @@ import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.accounts.AccountFeatureProviderImpl; import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.applications.ApplicationFeatureProviderImpl; +import com.android.settings.applications.GameSettingsFeatureProvider; +import com.android.settings.applications.GameSettingsFeatureProviderImpl; import com.android.settings.applications.appinfo.ExtraAppInfoFeatureProvider; import com.android.settings.applications.appinfo.ExtraAppInfoFeatureProviderImpl; import com.android.settings.aware.AwareFeatureProvider; @@ -103,6 +105,7 @@ public class FeatureFactoryImpl extends FeatureFactory { private WifiTrackerLibProvider mWifiTrackerLibProvider; private ExtraAppInfoFeatureProvider mExtraAppInfoFeatureProvider; private SecuritySettingsFeatureProvider mSecuritySettingsFeatureProvider; + private GameSettingsFeatureProvider mGameSettingsFeatureProvider; @Override public SupportFeatureProvider getSupportFeatureProvider(Context context) { @@ -324,4 +327,12 @@ public class FeatureFactoryImpl extends FeatureFactory { } return mSecuritySettingsFeatureProvider; } + + @Override + public GameSettingsFeatureProvider getGameSettingsFeatureProvider() { + if (mGameSettingsFeatureProvider == null) { + mGameSettingsFeatureProvider = new GameSettingsFeatureProviderImpl(); + } + return mGameSettingsFeatureProvider; + } } diff --git a/tests/robotests/src/com/android/settings/applications/GameSettingsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/GameSettingsPreferenceControllerTest.java new file mode 100644 index 00000000000..fa4fce82202 --- /dev/null +++ b/tests/robotests/src/com/android/settings/applications/GameSettingsPreferenceControllerTest.java @@ -0,0 +1,65 @@ +/* + * 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.settings.applications; + +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.content.Context; + +import com.android.settings.testutils.FakeFeatureFactory; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class GameSettingsPreferenceControllerTest { + + private GameSettingsPreferenceController mController; + private GameSettingsFeatureProvider mProvider; + private Context mContext; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + + mProvider = FakeFeatureFactory.setupForTest().getGameSettingsFeatureProvider(); + mController = new GameSettingsPreferenceController(mContext, "test_key", mProvider); + } + + @Test + public void getAvailabilityStatus_GameSettingsFeatureEnabled_shouldReturnAVAILABLE() { + when(mProvider.isSupported(mContext)).thenReturn(true); + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void getAvailabilityStatus_GameSettingsFeatureDisabled_shouldReturnUNSUPPORTED_ON_DEVICE() { + when(mProvider.isSupported(mContext)).thenReturn(false); + assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); + } +} diff --git a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java index b7e6ffd1309..4c4b922763d 100644 --- a/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/robotests/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -23,6 +23,7 @@ import android.content.Context; import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider; +import com.android.settings.applications.GameSettingsFeatureProvider; import com.android.settings.applications.appinfo.ExtraAppInfoFeatureProvider; import com.android.settings.aware.AwareFeatureProvider; import com.android.settings.biometrics.face.FaceFeatureProvider; @@ -85,6 +86,7 @@ public class FakeFeatureFactory extends FeatureFactory { public WifiTrackerLibProvider wifiTrackerLibProvider; public ExtraAppInfoFeatureProvider extraAppInfoFeatureProvider; public SecuritySettingsFeatureProvider securitySettingsFeatureProvider; + public GameSettingsFeatureProvider gameSettingsFeatureProvider; /** * Call this in {@code @Before} method of the test class to use fake factory. @@ -133,6 +135,7 @@ public class FakeFeatureFactory extends FeatureFactory { wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class); extraAppInfoFeatureProvider = mock(ExtraAppInfoFeatureProvider.class); securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class); + gameSettingsFeatureProvider = mock(GameSettingsFeatureProvider.class); } @Override @@ -264,4 +267,9 @@ public class FakeFeatureFactory extends FeatureFactory { public SecuritySettingsFeatureProvider getSecuritySettingsFeatureProvider() { return securitySettingsFeatureProvider; } + + @Override + public GameSettingsFeatureProvider getGameSettingsFeatureProvider() { + return gameSettingsFeatureProvider; + } } diff --git a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java index b6f330b7c85..1e74d927109 100644 --- a/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java +++ b/tests/unit/src/com/android/settings/testutils/FakeFeatureFactory.java @@ -21,6 +21,7 @@ import android.content.Context; import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider; +import com.android.settings.applications.GameSettingsFeatureProvider; import com.android.settings.applications.appinfo.ExtraAppInfoFeatureProvider; import com.android.settings.aware.AwareFeatureProvider; import com.android.settings.biometrics.face.FaceFeatureProvider; @@ -80,6 +81,7 @@ public class FakeFeatureFactory extends FeatureFactory { public WifiTrackerLibProvider wifiTrackerLibProvider; public ExtraAppInfoFeatureProvider extraAppInfoFeatureProvider; public SecuritySettingsFeatureProvider securitySettingsFeatureProvider; + public GameSettingsFeatureProvider gameSettingsFeatureProvider; /** * Call this in {@code @Before} method of the test class to use fake factory. @@ -119,6 +121,7 @@ public class FakeFeatureFactory extends FeatureFactory { wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class); extraAppInfoFeatureProvider = mock(ExtraAppInfoFeatureProvider.class); securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class); + gameSettingsFeatureProvider = mock(GameSettingsFeatureProvider.class); } @Override @@ -250,4 +253,9 @@ public class FakeFeatureFactory extends FeatureFactory { public SecuritySettingsFeatureProvider getSecuritySettingsFeatureProvider() { return securitySettingsFeatureProvider; } + + @Override + public GameSettingsFeatureProvider getGameSettingsFeatureProvider() { + return gameSettingsFeatureProvider; + } }