Merge "Settings: Start search result deep link in same task" into main

This commit is contained in:
Treehugger Robot
2025-03-19 01:02:31 -07:00
committed by Android (Google) Code Review
5 changed files with 114 additions and 6 deletions

View File

@@ -162,6 +162,12 @@ public class SettingsActivity extends SettingsBaseActivity
public static final String EXTRA_SHOW_FRAGMENT_TAB = public static final String EXTRA_SHOW_FRAGMENT_TAB =
":settings:show_fragment_tab"; ":settings:show_fragment_tab";
/**
* Whether the settings homepage activity is initiated from a search result deeplink.
*/
public static final String EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH =
":settings:is_deeplink_home_started_from_search";
public static final String META_DATA_KEY_FRAGMENT_CLASS = public static final String META_DATA_KEY_FRAGMENT_CLASS =
"com.android.settings.FRAGMENT_CLASS"; "com.android.settings.FRAGMENT_CLASS";

View File

@@ -24,7 +24,9 @@ import android.content.pm.UserInfo
import android.provider.Settings import android.provider.Settings
import android.util.Log import android.util.Log
import com.android.settings.SettingsActivity import com.android.settings.SettingsActivity
import com.android.settings.SettingsActivity.EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH
import com.android.settings.Utils import com.android.settings.Utils
import com.android.settings.flags.Flags
import com.android.settings.homepage.DeepLinkHomepageActivityInternal import com.android.settings.homepage.DeepLinkHomepageActivityInternal
import com.android.settings.homepage.SettingsHomepageActivity import com.android.settings.homepage.SettingsHomepageActivity
import com.android.settings.password.PasswordUtils import com.android.settings.password.PasswordUtils
@@ -94,6 +96,28 @@ object EmbeddedDeepLinkUtils {
} }
} }
/**
* Returns the deep link trampoline intent for settings search results for large screen devices.
*/
@JvmStatic
fun getTrampolineIntentForSearchResult(
context: Context,
intent: Intent,
highlightMenuKey: String?
): Intent {
return getTrampolineIntent(intent, highlightMenuKey).apply {
if (Flags.settingsSearchResultDeepLinkInSameTask()) {
// Ensure the deep link intent does not include FLAG_ACTIVITY_NEW_TASK which
// causes the search result deep link to open in a separate window.
removeFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
putExtra(EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH, true)
} else {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
}
setClass(context, DeepLinkHomepageActivityInternal::class.java)
}
}
/** /**
* Returns whether the user is a sub profile. * Returns whether the user is a sub profile.

View File

@@ -20,6 +20,7 @@ import static android.provider.Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY
import static android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY; import static android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY;
import static android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI; import static android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI;
import static com.android.settings.SettingsActivity.EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH;
import static com.android.settings.SettingsActivity.EXTRA_USER_HANDLE; import static com.android.settings.SettingsActivity.EXTRA_USER_HANDLE;
import android.animation.LayoutTransition; import android.animation.LayoutTransition;
@@ -232,7 +233,9 @@ public class SettingsHomepageActivity extends FragmentActivity implements
} }
} }
if (!isTaskRoot) { final boolean isDeepLinkStartedFromSearch = getIntent().getBooleanExtra(
EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH, false /* defaultValue */);
if (!isTaskRoot && !isDeepLinkStartedFromSearch) {
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
Log.i(TAG, "Activity has been started, finishing"); Log.i(TAG, "Activity has been started, finishing");
} else { } else {

View File

@@ -19,6 +19,7 @@ package com.android.settings.search;
import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS; import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS;
import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_TAB; import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_TAB;
import static com.android.settings.activityembedding.EmbeddedDeepLinkUtils.getTrampolineIntent; import static com.android.settings.activityembedding.EmbeddedDeepLinkUtils.getTrampolineIntent;
import static com.android.settings.activityembedding.EmbeddedDeepLinkUtils.getTrampolineIntentForSearchResult;
import android.app.Activity; import android.app.Activity;
import android.content.Intent; import android.content.Intent;
@@ -35,7 +36,6 @@ import com.android.settings.SubSettings;
import com.android.settings.activityembedding.ActivityEmbeddingRulesController; import com.android.settings.activityembedding.ActivityEmbeddingRulesController;
import com.android.settings.activityembedding.ActivityEmbeddingUtils; import com.android.settings.activityembedding.ActivityEmbeddingUtils;
import com.android.settings.core.FeatureFlags; import com.android.settings.core.FeatureFlags;
import com.android.settings.homepage.DeepLinkHomepageActivityInternal;
import com.android.settings.homepage.SettingsHomepageActivity; import com.android.settings.homepage.SettingsHomepageActivity;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
@@ -107,10 +107,7 @@ public class SearchResultTrampoline extends Activity {
startActivity(intent); startActivity(intent);
} else if (isSettingsIntelligence(callerPackage)) { } else if (isSettingsIntelligence(callerPackage)) {
if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SETTINGS_SEARCH_ALWAYS_EXPAND)) { if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SETTINGS_SEARCH_ALWAYS_EXPAND)) {
startActivity(getTrampolineIntent(intent, highlightMenuKey) startActivity(getTrampolineIntentForSearchResult(this, intent, highlightMenuKey));
.setClass(this, DeepLinkHomepageActivityInternal.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS));
} else { } else {
// Register SplitPairRule for SubSettings, set clearTop false to prevent unexpected // Register SplitPairRule for SubSettings, set clearTop false to prevent unexpected
// back navigation behavior. // back navigation behavior.

View File

@@ -19,16 +19,26 @@ package com.android.settings.activityembedding
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.provider.Settings import android.provider.Settings
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.SettingsActivity.EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH
import com.android.settings.activityembedding.EmbeddedDeepLinkUtils.getTrampolineIntent import com.android.settings.activityembedding.EmbeddedDeepLinkUtils.getTrampolineIntent
import com.android.settings.activityembedding.EmbeddedDeepLinkUtils.getTrampolineIntentForSearchResult
import com.android.settings.flags.Flags
import com.android.settings.homepage.DeepLinkHomepageActivityInternal
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class EmbeddedDeepLinkUtilsTest { class EmbeddedDeepLinkUtilsTest {
@get:Rule
val setFlagsRule = SetFlagsRule()
private val context: Context = ApplicationProvider.getApplicationContext() private val context: Context = ApplicationProvider.getApplicationContext()
@@ -58,4 +68,72 @@ class EmbeddedDeepLinkUtilsTest {
val parsedIntent = Intent.parseUri(intentUriString, Intent.URI_INTENT_SCHEME) val parsedIntent = Intent.parseUri(intentUriString, Intent.URI_INTENT_SCHEME)
assertThat(parsedIntent.action).isEqualTo(intent.action) assertThat(parsedIntent.action).isEqualTo(intent.action)
} }
@Test
fun getTrampolineIntent_shouldNotHaveNewTaskFlag() {
val intent = Intent("com.android.settings.SEARCH_RESULT_TRAMPOLINE")
val resultIntent = getTrampolineIntent(intent, "menu_key")
val hasNewTaskFlag = (resultIntent.flags and Intent.FLAG_ACTIVITY_NEW_TASK) != 0
assertThat(hasNewTaskFlag).isFalse()
}
@Test
fun getTrampolineIntentForSearchResult_shouldHaveDeepLinkHomepageClass() {
val intent = Intent("com.android.settings.SEARCH_RESULT_TRAMPOLINE")
val resultIntent = getTrampolineIntentForSearchResult(context, intent, "menu_key")
val className = resultIntent.getComponent()!!.className
assertThat(className).isEqualTo(DeepLinkHomepageActivityInternal::class.java.name)
}
@Test
@DisableFlags(Flags.FLAG_SETTINGS_SEARCH_RESULT_DEEP_LINK_IN_SAME_TASK)
fun getTrampolineIntentForSearchResult_shouldHaveNewTaskFlag() {
val intent = Intent("com.android.settings.SEARCH_RESULT_TRAMPOLINE")
val resultIntent = getTrampolineIntentForSearchResult(context, intent, "menu_key")
val hasNewTaskFlag = (resultIntent.flags and Intent.FLAG_ACTIVITY_NEW_TASK) != 0
assertThat(hasNewTaskFlag).isTrue()
}
@Test
@EnableFlags(Flags.FLAG_SETTINGS_SEARCH_RESULT_DEEP_LINK_IN_SAME_TASK)
fun getTrampolineIntentForSearchResult_shouldNotHaveNewTaskFlag() {
val intent = Intent("com.android.settings.SEARCH_RESULT_TRAMPOLINE")
val resultIntent = getTrampolineIntentForSearchResult(context, intent, "menu_key")
val hasNewTaskFlag = (resultIntent.flags and Intent.FLAG_ACTIVITY_NEW_TASK) != 0
assertThat(hasNewTaskFlag).isFalse()
}
@Test
@DisableFlags(Flags.FLAG_SETTINGS_SEARCH_RESULT_DEEP_LINK_IN_SAME_TASK)
fun getTrampolineIntentForSearchResult_shouldNotHaveExtraStartedFromSearch() {
val intent = Intent("com.android.settings.SEARCH_RESULT_TRAMPOLINE")
val resultIntent = getTrampolineIntentForSearchResult(context, intent, "menu_key")
assertThat(resultIntent.hasExtra(EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH)).isFalse()
assertThat(
resultIntent.getBooleanExtra(EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH, false)
).isFalse()
}
@Test
@EnableFlags(Flags.FLAG_SETTINGS_SEARCH_RESULT_DEEP_LINK_IN_SAME_TASK)
fun getTrampolineIntentForSearchResult_shouldHaveExtraStartedFromSearch() {
val intent = Intent("com.android.settings.SEARCH_RESULT_TRAMPOLINE")
val resultIntent = getTrampolineIntentForSearchResult(context, intent, "menu_key")
assertThat(resultIntent.hasExtra(EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH)).isTrue()
assertThat(
resultIntent.getBooleanExtra(EXTRA_IS_DEEPLINK_HOME_STARTED_FROM_SEARCH, false)
).isTrue()
}
} }