From 69974d0c4fdcb59b695305a907c6e9faaa64a3f1 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Wed, 22 Jun 2022 16:36:16 +0800 Subject: [PATCH] Add test cases for highlight Preference click behavior On large screen Activity embedding devices, Settings homepage shows a highlighted Preference which is mapped to current right pane. For better UX, when users click again on a highlighted Preference, it should not launch SubSettings. Fix: 236275503 Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.dashboard.DashboardFeatureProviderImplTest Change-Id: I222c9b015fb090f359c3c9f4187823477920715b --- .../homepage/TopLevelHighlightMixin.java | 4 +- .../settings/homepage/TopLevelSettings.java | 8 ++ .../DashboardFeatureProviderImplTest.java | 78 +++++++++++++++++++ .../shadow/ShadowSplitController.java | 42 ++++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 tests/robotests/src/com/android/settings/testutils/shadow/ShadowSplitController.java diff --git a/src/com/android/settings/homepage/TopLevelHighlightMixin.java b/src/com/android/settings/homepage/TopLevelHighlightMixin.java index 4718443f8a4..9d727a51dd9 100644 --- a/src/com/android/settings/homepage/TopLevelHighlightMixin.java +++ b/src/com/android/settings/homepage/TopLevelHighlightMixin.java @@ -23,6 +23,7 @@ import android.os.Parcelable; import android.text.TextUtils; import android.util.Log; +import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceScreen; import androidx.recyclerview.widget.RecyclerView; @@ -140,7 +141,8 @@ public class TopLevelHighlightMixin implements Parcelable, DialogInterface.OnSho } } - String getHighlightPreferenceKey() { + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + public String getHighlightPreferenceKey() { return mCurrentKey; } diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java index 70530fc8cd3..b44512371af 100644 --- a/src/com/android/settings/homepage/TopLevelSettings.java +++ b/src/com/android/settings/homepage/TopLevelSettings.java @@ -30,6 +30,7 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.ViewGroup; +import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; @@ -72,6 +73,13 @@ public class TopLevelSettings extends DashboardFragment implements SplitLayoutLi setArguments(args); } + /** Dependency injection ctor only for testing. */ + @VisibleForTesting + public TopLevelSettings(TopLevelHighlightMixin highlightMixin) { + this(); + mHighlightMixin = highlightMixin; + } + @Override protected int getPreferenceScreenResId() { return R.xml.top_level_settings; diff --git a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java index f2b0acddbed..01f97074209 100644 --- a/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/dashboard/DashboardFeatureProviderImplTest.java @@ -65,7 +65,12 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; +import com.android.settings.homepage.TopLevelHighlightMixin; +import com.android.settings.homepage.TopLevelSettings; +import com.android.settings.search.SearchFeatureProviderImpl; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.shadow.ShadowActivityEmbeddingUtils; +import com.android.settings.testutils.shadow.ShadowSplitController; import com.android.settings.testutils.shadow.ShadowTileUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; @@ -542,6 +547,64 @@ public class DashboardFeatureProviderImplTest { .isEqualTo(MetricsEvent.SETTINGS_GESTURES); } + /** This test is for large screen devices Activity embedding. */ + @Test + @Config(shadows = {ShadowActivityEmbeddingUtils.class, ShadowSplitController.class}) + public void bindPreference_clickHighlightedPreference_shouldNotStartActivity() { + ShadowSplitController.setIsActivityEmbedded(true); + ShadowActivityEmbeddingUtils.setIsEmbeddingActivityEnabled(true); + mFeatureFactory.searchFeatureProvider = new SearchFeatureProviderImpl(); + + String clickPrefKey = "highlight_pref_key"; + String highlightMixinPrefKey = "highlight_pref_key"; + FragmentActivity activity = Robolectric.buildActivity(FragmentActivity.class).get(); + Preference preference = new Preference(RuntimeEnvironment.application); + Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); + mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); + mActivityInfo.metaData.putString("com.android.settings.intent.action", "TestAction"); + tile.userHandle = null; + + TopLevelSettings largeScreenTopLevelSettings = new TopLevelSettings( + new TestTopLevelHighlightMixin(highlightMixinPrefKey, true /* activityEmbedded */)); + largeScreenTopLevelSettings.setHighlightPreferenceKey(clickPrefKey); + + mImpl.bindPreferenceToTileAndGetObservers(activity, largeScreenTopLevelSettings, + mForceRoundedIcon, preference, tile, clickPrefKey, Preference.DEFAULT_ORDER); + preference.performClick(); + + ShadowActivity shadowActivity = Shadows.shadowOf(activity); + assertThat(shadowActivity.getNextStartedActivityForResult()).isEqualTo(null); + } + + /** This test is for large screen devices Activity embedding. */ + @Test + @Config(shadows = {ShadowActivityEmbeddingUtils.class, ShadowSplitController.class}) + public void bindPreference_clickNotHighlightedPreference_shouldStartActivity() { + ShadowSplitController.setIsActivityEmbedded(true); + ShadowActivityEmbeddingUtils.setIsEmbeddingActivityEnabled(true); + mFeatureFactory.searchFeatureProvider = new SearchFeatureProviderImpl(); + + String clickPrefKey = "not_highlight_pref_key"; + String highlightMixinPrefKey = "highlight_pref_key"; + FragmentActivity activity = Robolectric.buildActivity(FragmentActivity.class).get(); + Preference preference = new Preference(RuntimeEnvironment.application); + Tile tile = new ActivityTile(mActivityInfo, CategoryKey.CATEGORY_HOMEPAGE); + mActivityInfo.metaData.putString(META_DATA_PREFERENCE_KEYHINT, "key"); + mActivityInfo.metaData.putString("com.android.settings.intent.action", "TestAction"); + tile.userHandle = null; + + TopLevelSettings largeScreenTopLevelSettings = new TopLevelSettings( + new TestTopLevelHighlightMixin(highlightMixinPrefKey, true /* activityEmbedded */)); + largeScreenTopLevelSettings.setHighlightPreferenceKey(clickPrefKey); + + mImpl.bindPreferenceToTileAndGetObservers(activity, largeScreenTopLevelSettings, + mForceRoundedIcon, preference, tile, clickPrefKey, Preference.DEFAULT_ORDER); + preference.performClick(); + + Intent launchIntent = Shadows.shadowOf(activity).getNextStartedActivityForResult().intent; + assertThat(launchIntent.getAction()).isEqualTo("TestAction"); + } + @Test public void clickPreference_withUnresolvableIntent_shouldNotLaunchAnything() { ReflectionHelpers.setField( @@ -694,4 +757,19 @@ public class DashboardFeatureProviderImplTest { return "TestFragment"; } } + + private static class TestTopLevelHighlightMixin extends TopLevelHighlightMixin { + private final String mHighlightPreferenceKey; + + TestTopLevelHighlightMixin(String highlightPreferenceKey, + boolean activityEmbedded) { + super(activityEmbedded); + mHighlightPreferenceKey = highlightPreferenceKey; + } + + @Override + public String getHighlightPreferenceKey() { + return mHighlightPreferenceKey; + } + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSplitController.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSplitController.java new file mode 100644 index 00000000000..bbd92c9caa3 --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSplitController.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 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.testutils.shadow; + +import android.app.Activity; + +import androidx.window.embedding.SplitController; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +/** + * Shadow class for {@link SplitController} to test embedding activity features. + */ +@Implements(SplitController.class) +public class ShadowSplitController { + private static boolean sIsActivityEmbedded; + + @Implementation + protected static boolean isActivityEmbedded(Activity activity) { + return sIsActivityEmbedded; + } + + public static void setIsActivityEmbedded(boolean isActivityEmbedded) { + sIsActivityEmbedded = isActivityEmbedded; + } +} +