diff --git a/AndroidManifest.xml b/AndroidManifest.xml index e4e1a10d293..41b4d05a35f 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -299,6 +299,15 @@ + + + + + + + mHomeActivity = new WeakReference<>(null); + private WeakReference mHomeActivity = new WeakReference<>(null); @Override public void onCreate() { @@ -37,11 +37,11 @@ public class SettingsApplication extends Application { controller.initRules(); } - public void setHomeActivity(Activity homeActivity) { + public void setHomeActivity(SettingsHomepageActivity homeActivity) { mHomeActivity = new WeakReference<>(homeActivity); } - public Activity getHomeActivity() { + public SettingsHomepageActivity getHomeActivity() { return mHomeActivity.get(); } } diff --git a/src/com/android/settings/SettingsInitialize.java b/src/com/android/settings/SettingsInitialize.java index 500ce779ef5..376d9160c6b 100644 --- a/src/com/android/settings/SettingsInitialize.java +++ b/src/com/android/settings/SettingsInitialize.java @@ -41,6 +41,7 @@ import androidx.window.embedding.SplitController; import com.android.settings.Settings.CreateShortcutActivity; import com.android.settings.homepage.SettingsHomepageActivity; +import com.android.settings.search.SearchStateReceiver; import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; @@ -67,7 +68,7 @@ public class SettingsInitialize extends BroadcastReceiver { managedProfileSetup(context, pm, broadcast, userInfo); webviewSettingSetup(context, pm, userInfo); ThreadUtils.postOnBackgroundThread(() -> refreshExistingShortcuts(context)); - enableTwoPaneDeepLinkActivityIfNecessary(pm, broadcast); + enableTwoPaneDeepLinkActivityIfNecessary(pm, context); } private void managedProfileSetup(Context context, final PackageManager pm, Intent broadcast, @@ -148,12 +149,16 @@ public class SettingsInitialize extends BroadcastReceiver { shortcutManager.updateShortcuts(updates); } - private void enableTwoPaneDeepLinkActivityIfNecessary(PackageManager pm, Intent intent) { + private void enableTwoPaneDeepLinkActivityIfNecessary(PackageManager pm, Context context) { final ComponentName deepLinkHome = new ComponentName(Utils.SETTINGS_PACKAGE_NAME, SettingsHomepageActivity.ALIAS_DEEP_LINK); + final ComponentName searchStateReceiver = new ComponentName(context, + SearchStateReceiver.class); final int enableState = SplitController.getInstance().isSplitSupported() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED; pm.setComponentEnabledSetting(deepLinkHome, enableState, PackageManager.DONT_KILL_APP); + pm.setComponentEnabledSetting(searchStateReceiver, enableState, + PackageManager.DONT_KILL_APP); } } diff --git a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java index 4060e53ad58..154065715e9 100644 --- a/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java +++ b/src/com/android/settings/activityembedding/ActivityEmbeddingRulesController.java @@ -35,6 +35,7 @@ import com.android.settings.Settings; import com.android.settings.SubSettings; import com.android.settings.Utils; import com.android.settings.homepage.SettingsHomepageActivity; +import com.android.settings.homepage.SliceDeepLinkHomepageActivity; import java.util.HashSet; import java.util.Set; @@ -128,6 +129,15 @@ public class ActivityEmbeddingRulesController { true /* finishPrimaryWithSecondary */, true /* finishSecondaryWithPrimary */, clearTop); + + registerTwoPanePairRule( + context, + getComponentName(context, SliceDeepLinkHomepageActivity.class), + secondaryComponent, + secondaryIntentAction, + true /* finishPrimaryWithSecondary */, + true /* finishSecondaryWithPrimary */, + clearTop); } /** Register a SplitPairRule for SubSettings if the device supports 2-pane. */ diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java index 051204dc767..4e843fd033d 100644 --- a/src/com/android/settings/homepage/SettingsHomepageActivity.java +++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java @@ -78,6 +78,7 @@ public class SettingsHomepageActivity extends FragmentActivity implements private static final int DEFAULT_HIGHLIGHT_MENU_KEY = R.string.menu_key_network; private static final long HOMEPAGE_LOADING_TIMEOUT_MS = 300; + private TopLevelSettings mMainFragment; private View mHomepageView; private View mSuggestionView; private CategoryMixin mCategoryMixin; @@ -124,6 +125,11 @@ public class SettingsHomepageActivity extends FragmentActivity implements homepageView.setVisibility(View.VISIBLE); } + /** Returns the main content fragment */ + public TopLevelSettings getMainFragment() { + return mMainFragment; + } + @Override public CategoryMixin getCategoryMixin() { return mCategoryMixin; @@ -132,7 +138,6 @@ public class SettingsHomepageActivity extends FragmentActivity implements @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setHomeActivity(); setContentView(R.layout.settings_homepage_container); final View appBar = findViewById(R.id.app_bar_container); @@ -162,10 +167,10 @@ public class SettingsHomepageActivity extends FragmentActivity implements showFragment(new ContextualCardsFragment(), R.id.contextual_cards_content); } } - final Fragment fragment = new TopLevelSettings(); - fragment.getArguments().putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, + mMainFragment = new TopLevelSettings(); + mMainFragment.getArguments().putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, getHighlightMenuKey()); - showFragment(fragment, R.id.main_content); + showFragment(mMainFragment, R.id.main_content); ((FrameLayout) findViewById(R.id.main_content)) .getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING); @@ -174,6 +179,12 @@ public class SettingsHomepageActivity extends FragmentActivity implements launchDeepLinkIntentToRight(); } + @Override + protected void onStart() { + ((SettingsApplication) getApplication()).setHomeActivity(this); + super.onStart(); + } + @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); @@ -189,10 +200,6 @@ public class SettingsHomepageActivity extends FragmentActivity implements launchDeepLinkIntentToRight(); } - protected void setHomeActivity() { - ((SettingsApplication) getApplication()).setHomeActivity(this); - } - private void showSuggestionFragment() { final Class fragment = FeatureFactory.getFactory(this) .getSuggestionFeatureProvider(this).getContextualSuggestionFragment(); @@ -314,13 +321,9 @@ public class SettingsHomepageActivity extends FragmentActivity implements } private void reloadHighlightMenuKey() { - final TopLevelSettings fragment = - (TopLevelSettings) getSupportFragmentManager().findFragmentById(R.id.main_content); - if (fragment != null) { - fragment.getArguments().putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, - getHighlightMenuKey()); - fragment.reloadHighlightMenuKey(); - } + mMainFragment.getArguments().putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, + getHighlightMenuKey()); + mMainFragment.reloadHighlightMenuKey(); } private void initHomepageContainer() { diff --git a/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java b/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java index 61e946d3bd8..2f836127e21 100644 --- a/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java +++ b/src/com/android/settings/homepage/SliceDeepLinkHomepageActivity.java @@ -20,11 +20,6 @@ import android.content.ComponentName; /** Activity for Slices to launch Settings deep link page */ public class SliceDeepLinkHomepageActivity extends SettingsHomepageActivity { - @Override - protected void setHomeActivity() { - // do not overwrite homepage activity in SettingsApplication - } - @Override protected ComponentName getDeepLinkComponent() { return new ComponentName(getApplicationContext(), getClass()); diff --git a/src/com/android/settings/homepage/TopLevelSettings.java b/src/com/android/settings/homepage/TopLevelSettings.java index 548b3c4bec0..193b69e6625 100644 --- a/src/com/android/settings/homepage/TopLevelSettings.java +++ b/src/com/android/settings/homepage/TopLevelSettings.java @@ -52,10 +52,12 @@ public class TopLevelSettings extends DashboardFragment implements private static final String TAG = "TopLevelSettings"; private static final String SAVED_HIGHLIGHTED_PREF = "highlighted_pref"; + private static final String SAVED_CACHED_PREF = "cached_pref"; private HighlightableTopLevelPreferenceAdapter mTopLevelAdapter; private String mHighlightedPreferenceKey; + private String mCachedPreferenceKey; public TopLevelSettings() { final Bundle args = new Bundle(); @@ -125,6 +127,7 @@ public class TopLevelSettings extends DashboardFragment implements super.onCreate(icicle); if (icicle != null) { mHighlightedPreferenceKey = icicle.getString(SAVED_HIGHLIGHTED_PREF); + mCachedPreferenceKey = icicle.getString(SAVED_CACHED_PREF); } } @@ -132,6 +135,7 @@ public class TopLevelSettings extends DashboardFragment implements public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString(SAVED_HIGHLIGHTED_PREF, mHighlightedPreferenceKey); + outState.putString(SAVED_CACHED_PREF, mCachedPreferenceKey); } @Override @@ -169,9 +173,10 @@ public class TopLevelSettings extends DashboardFragment implements } } - /** Highlight a preference with specified key */ + /** Highlight a preference with specified preference key */ public void setHighlightPreferenceKey(String prefKey) { if (mTopLevelAdapter != null) { + mCachedPreferenceKey = null; mHighlightedPreferenceKey = prefKey; mTopLevelAdapter.highlightPreference(prefKey, /* scrollNeeded= */ false); } @@ -184,13 +189,38 @@ public class TopLevelSettings extends DashboardFragment implements } } - /** Disable highlight on the menu entry */ - public void disableMenuHighlight() { + /** Show/hide the highlight on the menu entry */ + public void setMenuHighlightShowed(boolean show) { if (mTopLevelAdapter == null) { return; } - mHighlightedPreferenceKey = null; - mTopLevelAdapter.highlightPreference(mHighlightedPreferenceKey, /* scrollNeeded= */ false); + + if (show) { + mHighlightedPreferenceKey = mCachedPreferenceKey; + mCachedPreferenceKey = null; + } else { + if (mCachedPreferenceKey == null) { + mCachedPreferenceKey = mHighlightedPreferenceKey; + } + mHighlightedPreferenceKey = null; + } + mTopLevelAdapter.highlightPreference(mHighlightedPreferenceKey, /* scrollNeeded= */ show); + } + + /** Highlight and scroll to a preference with specified menu key */ + public void setHighlightMenuKey(String menuKey) { + if (mTopLevelAdapter == null) { + return; + } + + final String prefKey = HighlightableMenu.lookupPreferenceKey(menuKey); + if (TextUtils.isEmpty(prefKey)) { + Log.e(TAG, "Invalid highlight menu key: " + menuKey); + } else { + Log.d(TAG, "Menu key: " + menuKey); + mHighlightedPreferenceKey = prefKey; + mTopLevelAdapter.highlightPreference(prefKey, /* scrollNeeded= */ true); + } } @Override diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java index 9b081e18925..39e571f72fe 100644 --- a/src/com/android/settings/search/SearchFeatureProvider.java +++ b/src/com/android/settings/search/SearchFeatureProvider.java @@ -33,8 +33,6 @@ import androidx.fragment.app.FragmentActivity; import com.android.settings.R; import com.android.settings.Utils; -import com.android.settings.activityembedding.ActivityEmbeddingUtils; -import com.android.settings.homepage.TopLevelSettings; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.search.SearchIndexableResources; @@ -108,18 +106,8 @@ public interface SearchFeatureProvider { FeatureFactory.getFactory(context).getMetricsFeatureProvider() .logSettingsTileClick(KEY_HOMEPAGE_SEARCH_BAR, pageId); - if (ActivityEmbeddingUtils.isEmbeddingActivityEnabled(context)) { - final TopLevelSettings fragment = (TopLevelSettings) activity - .getSupportFragmentManager().findFragmentById(R.id.main_content); - if (fragment != null) { - fragment.disableMenuHighlight(); - } - activity.startActivity(intent); - } else { - final Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(activity) - .toBundle(); - activity.startActivity(intent, bundle); - } + final Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(activity).toBundle(); + activity.startActivity(intent, bundle); }); } diff --git a/src/com/android/settings/search/SearchResultTrampoline.java b/src/com/android/settings/search/SearchResultTrampoline.java index a770126ab82..f9cbc362419 100644 --- a/src/com/android/settings/search/SearchResultTrampoline.java +++ b/src/com/android/settings/search/SearchResultTrampoline.java @@ -28,9 +28,11 @@ import android.text.TextUtils; import android.util.Log; import com.android.settings.SettingsActivity; +import com.android.settings.SettingsApplication; import com.android.settings.SubSettings; import com.android.settings.activityembedding.ActivityEmbeddingRulesController; import com.android.settings.activityembedding.ActivityEmbeddingUtils; +import com.android.settings.homepage.SettingsHomepageActivity; import com.android.settings.overlay.FeatureFactory; import java.net.URISyntaxException; @@ -99,12 +101,20 @@ public class SearchResultTrampoline extends Activity { // navigation behavior. ActivityEmbeddingRulesController.registerSubSettingsPairRule(this, false /* clearTop */); - // TODO: pass menu key to homepage + intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); + + // Pass menu key to homepage + final SettingsHomepageActivity homeActivity = + ((SettingsApplication) getApplicationContext()).getHomeActivity(); + if (homeActivity != null) { + homeActivity.getMainFragment().setHighlightMenuKey(highlightMenuKey); + } } else { // Two-pane case - startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey)); + startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); } // Done. diff --git a/src/com/android/settings/search/SearchStateReceiver.java b/src/com/android/settings/search/SearchStateReceiver.java new file mode 100644 index 00000000000..d1f6f161a48 --- /dev/null +++ b/src/com/android/settings/search/SearchStateReceiver.java @@ -0,0 +1,58 @@ +/* + * 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.search; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; + +import com.android.settings.SettingsApplication; +import com.android.settings.homepage.SettingsHomepageActivity; + +/** + * A broadcast receiver that monitors the search state to show/hide the menu highlight + */ +public class SearchStateReceiver extends BroadcastReceiver { + + private static final String TAG = "SearchStateReceiver"; + private static final String ACTION_SEARCH_START = "com.android.settings.SEARCH_START"; + private static final String ACTION_SEARCH_EXIT = "com.android.settings.SEARCH_EXIT"; + + @Override + public void onReceive(Context context, Intent intent) { + if (intent == null) { + Log.w(TAG, "Null intent"); + return; + } + + final SettingsHomepageActivity homeActivity = + ((SettingsApplication) context.getApplicationContext()).getHomeActivity(); + if (homeActivity == null) { + return; + } + + final String action = intent.getAction(); + Log.d(TAG, "action: " + action); + if (TextUtils.equals(ACTION_SEARCH_START, action)) { + homeActivity.getMainFragment().setMenuHighlightShowed(false); + } else if (TextUtils.equals(ACTION_SEARCH_EXIT, action)) { + homeActivity.getMainFragment().setMenuHighlightShowed(true); + } + } +}