From a63e9c625dcf9bb8a97684af3428dc0e7040cd48 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Tue, 28 Sep 2021 20:39:15 +0800 Subject: [PATCH] [Large screen] Make slice deep linking to Settings show in 2-pane - add a standalone home activity for slice deep link. - add EXTRA_IS_FROM_SLICE to control the slice deep link flow. - Intent#parseUri fails if the intent data schema is set. Add EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA to relay the data schema. Bug: 201397123 Test: manual, robotest 1. Say 'Enable NFC'/'Enable Bluetooth'to Google assistant. 2. Click the the NFC/BT Slice. Change-Id: Ia3216956328c32b2109cb2d70ad1105327661f26 --- AndroidManifest.xml | 50 ++++++++++++++----- .../android/settings/SettingsActivity.java | 50 ++++++++++++++++--- .../ActivityEmbeddingRulesController.java | 7 +-- .../homepage/SettingsHomepageActivity.java | 15 +++++- .../SliceDeepLinkHomepageActivity.java | 27 ++++++++++ .../settings/slices/SliceBuilderUtils.java | 5 +- 6 files changed, 126 insertions(+), 28 deletions(-) create mode 100644 src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 8fedf92b345..af7de00008a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -129,7 +129,6 @@ - - - - - - - - - - + + @@ -234,6 +230,20 @@ android:value="true" /> + + + + + + + + + + + @@ -2535,6 +2545,8 @@ + @@ -2560,6 +2572,8 @@ + @@ -2574,6 +2588,8 @@ + + + + + 0: Personal tab. @@ -363,15 +374,34 @@ public class SettingsActivity extends SettingsBaseActivity return false; } + final Intent detailIntent = new Intent(intent); // It's a deep link intent, SettingsHomepageActivity will set SplitPairRule and start it. - final Intent trampolineIntent = - new Intent(android.provider.Settings.ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY); - trampolineIntent.replaceExtras(intent); + final Intent trampolineIntent = new Intent(ACTION_SETTINGS_EMBED_DEEP_LINK_ACTIVITY); + + trampolineIntent.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( - android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI, - intent.toUri(Intent.URI_INTENT_SCHEME)); - trampolineIntent.putExtra( - android.provider.Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, + 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)); + + if (detailIntent.getBooleanExtra(EXTRA_IS_FROM_SLICE, false)) { + trampolineIntent.setClass(this, SliceDeepLinkHomepageActivity.class); + // Get menu key for slice deep link case. + final String highlightMenuKey = detailIntent.getStringExtra( + EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY); + if (!TextUtils.isEmpty(highlightMenuKey)) { + mHighlightMenuKey = highlightMenuKey; + } + } + + trampolineIntent.putExtra(EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY, mHighlightMenuKey); trampolineIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); startActivity(trampolineIntent); @@ -391,6 +421,12 @@ public class SettingsActivity extends SettingsBaseActivity return false; } + if (intent.getBooleanExtra(EXTRA_IS_FROM_SLICE, false)) { + // Slice deep link starts the Intent using SubSettingLauncher. Returns true to show + // 2-pane deep link. + return true; + } + if (isSubSettings(intent)) { return false; } diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java index d57c0c28d59..c3ad5de95ad 100644 --- a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java +++ b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java @@ -41,7 +41,7 @@ import java.util.Set; /** A class to initialize split rules for activity embedding. */ public class ActivityEmbeddingRulesController { - private static final String TAG = "ActivityEmbeddingCtrl "; + private static final String TAG = "ActivityEmbeddingCtrl"; private final Context mContext; private final SplitController mSplitController; @@ -119,11 +119,6 @@ public class ActivityEmbeddingRulesController { null /* intentAction */)); } - private void addActivityFilter(Set activityFilters, Intent intent) { - activityFilters.add(new ActivityFilter(new ComponentName("*" /* pkg */, "*" /* cls */), - intent.getAction())); - } - private void addActivityFilter(Set activityFilters, ComponentName componentName) { activityFilters.add(new ActivityFilter(componentName, null /* intentAction */)); diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java index a2a6d3cb1ec..b3e32965753 100644 --- a/src/com/android/settings/homepage/SettingsHomepageActivity.java +++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java @@ -61,9 +61,15 @@ public class SettingsHomepageActivity extends FragmentActivity implements private static final String TAG = "SettingsHomepageActivity"; + // Additional extra of Settings#ACTION_SETTINGS_LARGE_SCREEN_DEEP_LINK. // Put true value to the intent when startActivity for a deep link intent from this Activity. public static final String EXTRA_IS_FROM_SETTINGS_HOMEPAGE = "is_from_settings_homepage"; + // Additional extra of Settings#ACTION_SETTINGS_LARGE_SCREEN_DEEP_LINK. + // Set & get Uri of the Intent separately to prevent failure of Intent#ParseUri. + public static final String EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA = + "settings_large_screen_deep_link_intent_data"; + // An alias class name of SettingsHomepageActivity. public static final String ALIAS_DEEP_LINK = "com.android.settings.DeepLinkHomepageActivity"; @@ -232,10 +238,13 @@ public class SettingsHomepageActivity extends FragmentActivity implements targetIntent.replaceExtras(intent); targetIntent.putExtra(EXTRA_IS_FROM_SETTINGS_HOMEPAGE, true); + targetIntent.putExtra(SettingsActivity.EXTRA_IS_FROM_SLICE, false); + targetIntent.setData(intent.getParcelableExtra( + SettingsHomepageActivity.EXTRA_SETTINGS_LARGE_SCREEN_DEEP_LINK_INTENT_DATA)); // Set 2-pane pair rule for the deep link page. ActivityEmbeddingRulesController.registerTwoPanePairRule(this, - new ComponentName(Utils.SETTINGS_PACKAGE_NAME, ALIAS_DEEP_LINK), + getDeepLinkComponent(), targetComponentName, targetIntent.getAction(), true /* finishPrimaryWithSecondary */, @@ -249,6 +258,10 @@ public class SettingsHomepageActivity extends FragmentActivity implements startActivity(targetIntent); } + protected ComponentName getDeepLinkComponent() { + return new ComponentName(Utils.SETTINGS_PACKAGE_NAME, ALIAS_DEEP_LINK); + } + private String getHighlightMenuKey() { final Intent intent = getIntent(); if (intent != null && TextUtils.equals(intent.getAction(), diff --git a/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java b/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java new file mode 100644 index 00000000000..2f836127e21 --- /dev/null +++ b/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java @@ -0,0 +1,27 @@ +/* + * 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.homepage; + +import android.content.ComponentName; + +/** Activity for Slices to launch Settings deep link page */ +public class SliceDeepLinkHomepageActivity extends SettingsHomepageActivity { + @Override + protected ComponentName getDeepLinkComponent() { + return new ComponentName(getApplicationContext(), getClass()); + } +} diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java index 402e044230d..2957df21bd5 100644 --- a/src/com/android/settings/slices/SliceBuilderUtils.java +++ b/src/com/android/settings/slices/SliceBuilderUtils.java @@ -16,6 +16,7 @@ package com.android.settings.slices; +import static com.android.settings.SettingsActivity.EXTRA_IS_FROM_SLICE; import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; import static com.android.settings.slices.SettingsSliceProvider.EXTRA_SLICE_KEY; @@ -211,7 +212,9 @@ public class SliceBuilderUtils { .setTitleText(screenTitle) .setSourceMetricsCategory(sourceMetricsCategory) .toIntent(); - searchDestination.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key) + searchDestination + .putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key) + .putExtra(EXTRA_IS_FROM_SLICE, true) .setAction("com.android.settings.SEARCH_RESULT_TRAMPOLINE") .setComponent(null); searchDestination.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);