Loading src/com/android/settings/SettingsActivity.java +4 −75 Original line number Diff line number Diff line Loading @@ -16,16 +16,12 @@ package com.android.settings; 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_INTENT_URI; import static com.android.settings.activityembedding.EmbeddedDeepLinkUtils.tryStartMultiPaneDeepLink; import static com.android.settings.applications.appinfo.AppButtonsPreferenceController.KEY_REMOVE_TASK_WHEN_FINISHING; import android.app.ActionBar; import android.app.ActivityManager; import android.app.settings.SettingsEnums; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading @@ -35,7 +31,6 @@ import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.drawable.Icon; Loading Loading @@ -67,7 +62,6 @@ import com.android.settings.core.SettingsBaseActivity; import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.gateway.SettingsGateway; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.homepage.DeepLinkHomepageActivityInternal; import com.android.settings.homepage.SettingsHomepageActivity; import com.android.settings.homepage.TopLevelSettings; import com.android.settings.overlay.FeatureFactory; Loading Loading @@ -278,7 +272,8 @@ public class SettingsActivity extends SettingsBaseActivity getMetaData(); final Intent intent = getIntent(); if (shouldShowTwoPaneDeepLink(intent) && tryStartTwoPaneDeepLink(intent)) { if (shouldShowMultiPaneDeepLink(intent) && tryStartMultiPaneDeepLink(this, intent, mHighlightMenuKey)) { finish(); super.onCreate(savedState); return; Loading Loading @@ -415,73 +410,7 @@ public class SettingsActivity extends SettingsBaseActivity intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false); } /** * Returns the deep link trampoline intent for large screen devices. */ public static Intent getTrampolineIntent(Intent intent, String highlightMenuKey) { final Intent detailIntent = new Intent(intent); // Guard against the arbitrary Intent injection. if (detailIntent.getSelector() != null) { detailIntent.setSelector(null); } // It's a deep link intent, SettingsHomepageActivity will set SplitPairRule and start it. final Intent trampolineIntent = new Intent(ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY) .setPackage(Utils.SETTINGS_PACKAGE_NAME) .replaceExtras(detailIntent); // Relay detail intent data to prevent failure of Intent#ParseUri. // If Intent#getData() is not null, Intent#toUri will return an Uri which has the scheme of // Intent#getData() and it may not be the scheme of an Intent. trampolineIntent.putExtra( SettingsHomepageActivity.EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA, detailIntent.getData()); detailIntent.setData(null); trampolineIntent.putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI, detailIntent.toUri(Intent.URI_INTENT_SCHEME)); trampolineIntent.putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey); trampolineIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); return trampolineIntent; } private boolean tryStartTwoPaneDeepLink(Intent intent) { intent.putExtra(EXTRA_INITIAL_CALLING_PACKAGE, PasswordUtils.getCallingAppPackageName( getActivityToken())); final Intent trampolineIntent; if (intent.getBooleanExtra(EXTRA_IS_FROM_SLICE, false)) { // Get menu key for slice deep link case. final String highlightMenuKey = intent.getStringExtra( EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY); if (!TextUtils.isEmpty(highlightMenuKey)) { mHighlightMenuKey = highlightMenuKey; } trampolineIntent = getTrampolineIntent(intent, mHighlightMenuKey); trampolineIntent.setClass(this, DeepLinkHomepageActivityInternal.class); } else { trampolineIntent = getTrampolineIntent(intent, mHighlightMenuKey); } try { final UserManager um = getSystemService(UserManager.class); final UserInfo userInfo = um.getUserInfo(getUser().getIdentifier()); if (userInfo.isManagedProfile()) { trampolineIntent.setClass(this, DeepLinkHomepageActivityInternal.class) .putExtra(EXTRA_USER_HANDLE, getUser()); startActivityAsUser(trampolineIntent, um.getProfileParent(userInfo.id).getUserHandle()); } else { startActivity(trampolineIntent); } } catch (ActivityNotFoundException e) { Log.e(LOG_TAG, "Deep link homepage is not available to show 2-pane UI"); return false; } return true; } private boolean shouldShowTwoPaneDeepLink(Intent intent) { private boolean shouldShowMultiPaneDeepLink(Intent intent) { if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this)) { return false; } Loading src/com/android/settings/SettingsActivityUtil.kt +12 −11 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import com.android.settings.applications.appinfo.WriteSettingsDetails import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureDetails import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureSettings import com.android.settings.spa.SpaActivity.Companion.startSpaActivity import com.android.settings.spa.SpaActivity.Companion.startSpaActivityForApp import com.android.settings.spa.SpaAppBridgeActivity.Companion.getDestinationForApp import com.android.settings.spa.app.specialaccess.AlarmsAndRemindersAppListProvider import com.android.settings.spa.app.specialaccess.AllFilesAccessAppListProvider import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListProvider Loading Loading @@ -72,17 +72,18 @@ object SettingsActivityUtil { @JvmStatic fun Context.launchSpaActivity(fragmentName: String, intent: Intent): Boolean { if (!FeatureFlagUtils.isEnabled(this, FeatureFlagUtils.SETTINGS_ENABLE_SPA)) { return false } FRAGMENT_TO_SPA_DESTINATION_MAP[fragmentName]?.let { destination -> if (FeatureFlagUtils.isEnabled(this, FeatureFlagUtils.SETTINGS_ENABLE_SPA)) { getDestination(fragmentName, intent)?.let { destination -> startSpaActivity(destination) return true } FRAGMENT_TO_SPA_APP_DESTINATION_PREFIX_MAP[fragmentName]?.let { appDestinationPrefix -> startSpaActivityForApp(appDestinationPrefix, intent) return true } return false } private fun getDestination(fragmentName: String, intent: Intent): String? = FRAGMENT_TO_SPA_DESTINATION_MAP[fragmentName] ?: FRAGMENT_TO_SPA_APP_DESTINATION_PREFIX_MAP[fragmentName]?.let { destinationPrefix -> getDestinationForApp(destinationPrefix, intent) } } src/com/android/settings/activityembedding/EmbeddedDeepLinkUtils.kt 0 → 100644 +113 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.activityembedding import android.app.Activity import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent import android.provider.Settings import android.util.Log import com.android.settings.SettingsActivity import com.android.settings.Utils import com.android.settings.homepage.DeepLinkHomepageActivityInternal import com.android.settings.homepage.SettingsHomepageActivity import com.android.settings.password.PasswordUtils import com.android.settingslib.spaprivileged.framework.common.userManager object EmbeddedDeepLinkUtils { private const val TAG = "EmbeddedDeepLinkUtils" @JvmStatic fun Activity.tryStartMultiPaneDeepLink( intent: Intent, highlightMenuKey: String? = null, ): Boolean { intent.putExtra( SettingsActivity.EXTRA_INITIAL_CALLING_PACKAGE, PasswordUtils.getCallingAppPackageName(activityToken), ) val trampolineIntent: Intent if (intent.getBooleanExtra(SettingsActivity.EXTRA_IS_FROM_SLICE, false)) { // Get menu key for slice deep link case. var sliceHighlightMenuKey: String? = intent.getStringExtra( Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY ) if (sliceHighlightMenuKey.isNullOrEmpty()) { sliceHighlightMenuKey = highlightMenuKey } trampolineIntent = getTrampolineIntent(intent, sliceHighlightMenuKey) trampolineIntent.setClass(this, DeepLinkHomepageActivityInternal::class.java) } else { trampolineIntent = getTrampolineIntent(intent, highlightMenuKey) } return startTrampolineIntent(trampolineIntent) } /** * Returns the deep link trampoline intent for large screen devices. */ @JvmStatic fun getTrampolineIntent(intent: Intent, highlightMenuKey: String?): Intent { val detailIntent = Intent(intent) // Guard against the arbitrary Intent injection. if (detailIntent.selector != null) { detailIntent.setSelector(null) } // It's a deep link intent, SettingsHomepageActivity will set SplitPairRule and start it. return Intent(Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY).apply { setPackage(Utils.SETTINGS_PACKAGE_NAME) replaceExtras(detailIntent) // Relay detail intent data to prevent failure of Intent#ParseUri. // If Intent#getData() is not null, Intent#toUri will return an Uri which has the scheme // of Intent#getData() and it may not be the scheme of an Intent. putExtra( SettingsHomepageActivity.EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA, detailIntent.data ) detailIntent.setData(null) putExtra( Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI, detailIntent.toUri(Intent.URI_INTENT_SCHEME) ) putExtra( Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey ) addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT) } } private fun Context.startTrampolineIntent(trampolineIntent: Intent): Boolean = try { val userInfo = userManager.getUserInfo(user.identifier) if (userInfo.isManagedProfile) { trampolineIntent.setClass(this, DeepLinkHomepageActivityInternal::class.java) .putExtra(SettingsActivity.EXTRA_USER_HANDLE, user) startActivityAsUser( trampolineIntent, userManager.getProfileParent(userInfo.id).userHandle ) } else { startActivity(trampolineIntent) } true } catch (e: ActivityNotFoundException) { Log.e(TAG, "Deep link homepage is not available to show 2-pane UI") false } } src/com/android/settings/search/SearchResultTrampoline.java +3 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,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_TAB; import static com.android.settings.activityembedding.EmbeddedDeepLinkUtils.getTrampolineIntent; import android.app.Activity; import android.content.ComponentName; Loading Loading @@ -107,7 +108,7 @@ public class SearchResultTrampoline extends Activity { startActivity(intent); } else if (isSettingsIntelligence(callingActivity)) { if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SETTINGS_SEARCH_ALWAYS_EXPAND)) { startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey) startActivity(getTrampolineIntent(intent, highlightMenuKey) .setClass(this, DeepLinkHomepageActivityInternal.class) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)); Loading @@ -130,7 +131,7 @@ public class SearchResultTrampoline extends Activity { } } else { // Two-pane case startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey) startActivity(getTrampolineIntent(intent, highlightMenuKey) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } Loading src/com/android/settings/spa/SpaActivity.kt +2 −27 Original line number Diff line number Diff line Loading @@ -16,18 +16,14 @@ package com.android.settings.spa import android.app.ActivityManager import android.content.Context import android.content.Intent import android.os.RemoteException import android.os.UserHandle import android.util.Log import androidx.annotation.VisibleForTesting import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider import com.android.settingslib.spa.framework.BrowseActivity import com.android.settingslib.spa.framework.common.SettingsPage import com.android.settingslib.spa.framework.util.SESSION_BROWSE import com.android.settingslib.spa.framework.util.SESSION_EXTERNAL import com.android.settingslib.spa.framework.util.appendSpaParams import com.google.android.setupcompat.util.WizardManagerHelper Loading @@ -44,7 +40,7 @@ class SpaActivity : BrowseActivity() { @VisibleForTesting fun Context.isSuwAndPageBlocked(name: String): Boolean = if (name in SuwBlockedPages && !WizardManagerHelper.isDeviceProvisioned(this)) { Log.w(TAG, "$name blocked before SUW completed."); Log.w(TAG, "$name blocked before SUW completed.") true } else { false Loading @@ -54,29 +50,8 @@ class SpaActivity : BrowseActivity() { fun Context.startSpaActivity(destination: String) { val intent = Intent(this, SpaActivity::class.java) .appendSpaParams(destination = destination) if (isLaunchedFromInternal()) { intent.appendSpaParams(sessionName = SESSION_BROWSE) } else { intent.appendSpaParams(sessionName = SESSION_EXTERNAL) } .appendSpaParams(sessionName = SESSION_BROWSE) startActivity(intent) } @JvmStatic fun Context.startSpaActivityForApp(destinationPrefix: String, intent: Intent): Boolean { val packageName = intent.data?.schemeSpecificPart ?: return false startSpaActivity("$destinationPrefix/$packageName/${UserHandle.myUserId()}") return true } fun Context.isLaunchedFromInternal(): Boolean { var pkg: String? = null try { pkg = ActivityManager.getService().getLaunchedFromPackage(getActivityToken()) } catch (e: RemoteException) { Log.v(TAG, "Could not talk to activity manager.", e) } return applicationContext.packageName == pkg } } } Loading
src/com/android/settings/SettingsActivity.java +4 −75 Original line number Diff line number Diff line Loading @@ -16,16 +16,12 @@ package com.android.settings; 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_INTENT_URI; import static com.android.settings.activityembedding.EmbeddedDeepLinkUtils.tryStartMultiPaneDeepLink; import static com.android.settings.applications.appinfo.AppButtonsPreferenceController.KEY_REMOVE_TASK_WHEN_FINISHING; import android.app.ActionBar; import android.app.ActivityManager; import android.app.settings.SettingsEnums; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; Loading @@ -35,7 +31,6 @@ import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.graphics.drawable.Icon; Loading Loading @@ -67,7 +62,6 @@ import com.android.settings.core.SettingsBaseActivity; import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.gateway.SettingsGateway; import com.android.settings.dashboard.DashboardFeatureProvider; import com.android.settings.homepage.DeepLinkHomepageActivityInternal; import com.android.settings.homepage.SettingsHomepageActivity; import com.android.settings.homepage.TopLevelSettings; import com.android.settings.overlay.FeatureFactory; Loading Loading @@ -278,7 +272,8 @@ public class SettingsActivity extends SettingsBaseActivity getMetaData(); final Intent intent = getIntent(); if (shouldShowTwoPaneDeepLink(intent) && tryStartTwoPaneDeepLink(intent)) { if (shouldShowMultiPaneDeepLink(intent) && tryStartMultiPaneDeepLink(this, intent, mHighlightMenuKey)) { finish(); super.onCreate(savedState); return; Loading Loading @@ -415,73 +410,7 @@ public class SettingsActivity extends SettingsBaseActivity intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false); } /** * Returns the deep link trampoline intent for large screen devices. */ public static Intent getTrampolineIntent(Intent intent, String highlightMenuKey) { final Intent detailIntent = new Intent(intent); // Guard against the arbitrary Intent injection. if (detailIntent.getSelector() != null) { detailIntent.setSelector(null); } // It's a deep link intent, SettingsHomepageActivity will set SplitPairRule and start it. final Intent trampolineIntent = new Intent(ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY) .setPackage(Utils.SETTINGS_PACKAGE_NAME) .replaceExtras(detailIntent); // Relay detail intent data to prevent failure of Intent#ParseUri. // If Intent#getData() is not null, Intent#toUri will return an Uri which has the scheme of // Intent#getData() and it may not be the scheme of an Intent. trampolineIntent.putExtra( SettingsHomepageActivity.EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA, detailIntent.getData()); detailIntent.setData(null); trampolineIntent.putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI, detailIntent.toUri(Intent.URI_INTENT_SCHEME)); trampolineIntent.putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey); trampolineIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); return trampolineIntent; } private boolean tryStartTwoPaneDeepLink(Intent intent) { intent.putExtra(EXTRA_INITIAL_CALLING_PACKAGE, PasswordUtils.getCallingAppPackageName( getActivityToken())); final Intent trampolineIntent; if (intent.getBooleanExtra(EXTRA_IS_FROM_SLICE, false)) { // Get menu key for slice deep link case. final String highlightMenuKey = intent.getStringExtra( EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY); if (!TextUtils.isEmpty(highlightMenuKey)) { mHighlightMenuKey = highlightMenuKey; } trampolineIntent = getTrampolineIntent(intent, mHighlightMenuKey); trampolineIntent.setClass(this, DeepLinkHomepageActivityInternal.class); } else { trampolineIntent = getTrampolineIntent(intent, mHighlightMenuKey); } try { final UserManager um = getSystemService(UserManager.class); final UserInfo userInfo = um.getUserInfo(getUser().getIdentifier()); if (userInfo.isManagedProfile()) { trampolineIntent.setClass(this, DeepLinkHomepageActivityInternal.class) .putExtra(EXTRA_USER_HANDLE, getUser()); startActivityAsUser(trampolineIntent, um.getProfileParent(userInfo.id).getUserHandle()); } else { startActivity(trampolineIntent); } } catch (ActivityNotFoundException e) { Log.e(LOG_TAG, "Deep link homepage is not available to show 2-pane UI"); return false; } return true; } private boolean shouldShowTwoPaneDeepLink(Intent intent) { private boolean shouldShowMultiPaneDeepLink(Intent intent) { if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this)) { return false; } Loading
src/com/android/settings/SettingsActivityUtil.kt +12 −11 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import com.android.settings.applications.appinfo.WriteSettingsDetails import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureDetails import com.android.settings.applications.specialaccess.pictureinpicture.PictureInPictureSettings import com.android.settings.spa.SpaActivity.Companion.startSpaActivity import com.android.settings.spa.SpaActivity.Companion.startSpaActivityForApp import com.android.settings.spa.SpaAppBridgeActivity.Companion.getDestinationForApp import com.android.settings.spa.app.specialaccess.AlarmsAndRemindersAppListProvider import com.android.settings.spa.app.specialaccess.AllFilesAccessAppListProvider import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListProvider Loading Loading @@ -72,17 +72,18 @@ object SettingsActivityUtil { @JvmStatic fun Context.launchSpaActivity(fragmentName: String, intent: Intent): Boolean { if (!FeatureFlagUtils.isEnabled(this, FeatureFlagUtils.SETTINGS_ENABLE_SPA)) { return false } FRAGMENT_TO_SPA_DESTINATION_MAP[fragmentName]?.let { destination -> if (FeatureFlagUtils.isEnabled(this, FeatureFlagUtils.SETTINGS_ENABLE_SPA)) { getDestination(fragmentName, intent)?.let { destination -> startSpaActivity(destination) return true } FRAGMENT_TO_SPA_APP_DESTINATION_PREFIX_MAP[fragmentName]?.let { appDestinationPrefix -> startSpaActivityForApp(appDestinationPrefix, intent) return true } return false } private fun getDestination(fragmentName: String, intent: Intent): String? = FRAGMENT_TO_SPA_DESTINATION_MAP[fragmentName] ?: FRAGMENT_TO_SPA_APP_DESTINATION_PREFIX_MAP[fragmentName]?.let { destinationPrefix -> getDestinationForApp(destinationPrefix, intent) } }
src/com/android/settings/activityembedding/EmbeddedDeepLinkUtils.kt 0 → 100644 +113 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.activityembedding import android.app.Activity import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent import android.provider.Settings import android.util.Log import com.android.settings.SettingsActivity import com.android.settings.Utils import com.android.settings.homepage.DeepLinkHomepageActivityInternal import com.android.settings.homepage.SettingsHomepageActivity import com.android.settings.password.PasswordUtils import com.android.settingslib.spaprivileged.framework.common.userManager object EmbeddedDeepLinkUtils { private const val TAG = "EmbeddedDeepLinkUtils" @JvmStatic fun Activity.tryStartMultiPaneDeepLink( intent: Intent, highlightMenuKey: String? = null, ): Boolean { intent.putExtra( SettingsActivity.EXTRA_INITIAL_CALLING_PACKAGE, PasswordUtils.getCallingAppPackageName(activityToken), ) val trampolineIntent: Intent if (intent.getBooleanExtra(SettingsActivity.EXTRA_IS_FROM_SLICE, false)) { // Get menu key for slice deep link case. var sliceHighlightMenuKey: String? = intent.getStringExtra( Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY ) if (sliceHighlightMenuKey.isNullOrEmpty()) { sliceHighlightMenuKey = highlightMenuKey } trampolineIntent = getTrampolineIntent(intent, sliceHighlightMenuKey) trampolineIntent.setClass(this, DeepLinkHomepageActivityInternal::class.java) } else { trampolineIntent = getTrampolineIntent(intent, highlightMenuKey) } return startTrampolineIntent(trampolineIntent) } /** * Returns the deep link trampoline intent for large screen devices. */ @JvmStatic fun getTrampolineIntent(intent: Intent, highlightMenuKey: String?): Intent { val detailIntent = Intent(intent) // Guard against the arbitrary Intent injection. if (detailIntent.selector != null) { detailIntent.setSelector(null) } // It's a deep link intent, SettingsHomepageActivity will set SplitPairRule and start it. return Intent(Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY).apply { setPackage(Utils.SETTINGS_PACKAGE_NAME) replaceExtras(detailIntent) // Relay detail intent data to prevent failure of Intent#ParseUri. // If Intent#getData() is not null, Intent#toUri will return an Uri which has the scheme // of Intent#getData() and it may not be the scheme of an Intent. putExtra( SettingsHomepageActivity.EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA, detailIntent.data ) detailIntent.setData(null) putExtra( Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI, detailIntent.toUri(Intent.URI_INTENT_SCHEME) ) putExtra( Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, highlightMenuKey ) addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT) } } private fun Context.startTrampolineIntent(trampolineIntent: Intent): Boolean = try { val userInfo = userManager.getUserInfo(user.identifier) if (userInfo.isManagedProfile) { trampolineIntent.setClass(this, DeepLinkHomepageActivityInternal::class.java) .putExtra(SettingsActivity.EXTRA_USER_HANDLE, user) startActivityAsUser( trampolineIntent, userManager.getProfileParent(userInfo.id).userHandle ) } else { startActivity(trampolineIntent) } true } catch (e: ActivityNotFoundException) { Log.e(TAG, "Deep link homepage is not available to show 2-pane UI") false } }
src/com/android/settings/search/SearchResultTrampoline.java +3 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,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_TAB; import static com.android.settings.activityembedding.EmbeddedDeepLinkUtils.getTrampolineIntent; import android.app.Activity; import android.content.ComponentName; Loading Loading @@ -107,7 +108,7 @@ public class SearchResultTrampoline extends Activity { startActivity(intent); } else if (isSettingsIntelligence(callingActivity)) { if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SETTINGS_SEARCH_ALWAYS_EXPAND)) { startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey) startActivity(getTrampolineIntent(intent, highlightMenuKey) .setClass(this, DeepLinkHomepageActivityInternal.class) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)); Loading @@ -130,7 +131,7 @@ public class SearchResultTrampoline extends Activity { } } else { // Two-pane case startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey) startActivity(getTrampolineIntent(intent, highlightMenuKey) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } Loading
src/com/android/settings/spa/SpaActivity.kt +2 −27 Original line number Diff line number Diff line Loading @@ -16,18 +16,14 @@ package com.android.settings.spa import android.app.ActivityManager import android.content.Context import android.content.Intent import android.os.RemoteException import android.os.UserHandle import android.util.Log import androidx.annotation.VisibleForTesting import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider import com.android.settingslib.spa.framework.BrowseActivity import com.android.settingslib.spa.framework.common.SettingsPage import com.android.settingslib.spa.framework.util.SESSION_BROWSE import com.android.settingslib.spa.framework.util.SESSION_EXTERNAL import com.android.settingslib.spa.framework.util.appendSpaParams import com.google.android.setupcompat.util.WizardManagerHelper Loading @@ -44,7 +40,7 @@ class SpaActivity : BrowseActivity() { @VisibleForTesting fun Context.isSuwAndPageBlocked(name: String): Boolean = if (name in SuwBlockedPages && !WizardManagerHelper.isDeviceProvisioned(this)) { Log.w(TAG, "$name blocked before SUW completed."); Log.w(TAG, "$name blocked before SUW completed.") true } else { false Loading @@ -54,29 +50,8 @@ class SpaActivity : BrowseActivity() { fun Context.startSpaActivity(destination: String) { val intent = Intent(this, SpaActivity::class.java) .appendSpaParams(destination = destination) if (isLaunchedFromInternal()) { intent.appendSpaParams(sessionName = SESSION_BROWSE) } else { intent.appendSpaParams(sessionName = SESSION_EXTERNAL) } .appendSpaParams(sessionName = SESSION_BROWSE) startActivity(intent) } @JvmStatic fun Context.startSpaActivityForApp(destinationPrefix: String, intent: Intent): Boolean { val packageName = intent.data?.schemeSpecificPart ?: return false startSpaActivity("$destinationPrefix/$packageName/${UserHandle.myUserId()}") return true } fun Context.isLaunchedFromInternal(): Boolean { var pkg: String? = null try { pkg = ActivityManager.getService().getLaunchedFromPackage(getActivityToken()) } catch (e: RemoteException) { Log.v(TAG, "Could not talk to activity manager.", e) } return applicationContext.packageName == pkg } } }