1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.search; 18 19 import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS; 20 import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_TAB; 21 22 import android.app.Activity; 23 import android.content.ComponentName; 24 import android.content.Intent; 25 import android.os.Bundle; 26 import android.provider.Settings; 27 import android.text.TextUtils; 28 import android.util.FeatureFlagUtils; 29 import android.util.Log; 30 31 import com.android.settings.SettingsActivity; 32 import com.android.settings.SettingsApplication; 33 import com.android.settings.SubSettings; 34 import com.android.settings.activityembedding.ActivityEmbeddingRulesController; 35 import com.android.settings.activityembedding.ActivityEmbeddingUtils; 36 import com.android.settings.core.FeatureFlags; 37 import com.android.settings.homepage.DeepLinkHomepageActivityInternal; 38 import com.android.settings.homepage.SettingsHomepageActivity; 39 import com.android.settings.overlay.FeatureFactory; 40 41 import java.net.URISyntaxException; 42 43 /** 44 * A trampoline activity that launches setting result page. 45 */ 46 public class SearchResultTrampoline extends Activity { 47 48 private static final String TAG = "SearchResultTrampoline"; 49 50 @Override onCreate(Bundle savedInstanceState)51 protected void onCreate(Bundle savedInstanceState) { 52 super.onCreate(savedInstanceState); 53 54 final ComponentName callingActivity = getCallingActivity(); 55 // First make sure caller has privilege to launch a search result page. 56 FeatureFactory.getFactory(this) 57 .getSearchFeatureProvider() 58 .verifyLaunchSearchResultPageCaller(this, callingActivity); 59 // Didn't crash, proceed and launch the result as a subsetting. 60 Intent intent = getIntent(); 61 final String highlightMenuKey = intent.getStringExtra( 62 Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_HIGHLIGHT_MENU_KEY); 63 64 final String fragment = intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT); 65 if (!TextUtils.isEmpty(fragment)) { 66 // Hack to take EXTRA_FRAGMENT_ARG_KEY from intent and set into 67 // EXTRA_SHOW_FRAGMENT_ARGUMENTS. This is necessary because intent could be from 68 // external caller and args may not persisted. 69 final String settingKey = intent.getStringExtra( 70 SettingsActivity.EXTRA_FRAGMENT_ARG_KEY); 71 final int tab = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TAB, 0); 72 final Bundle args = new Bundle(); 73 args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, settingKey); 74 args.putInt(EXTRA_SHOW_FRAGMENT_TAB, tab); 75 intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args); 76 77 // Reroute request to SubSetting. 78 intent.setClass(this /* context */, SubSettings.class); 79 } else { 80 // Direct link case 81 final String intentUriString = intent.getStringExtra( 82 Settings.EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI); 83 if (TextUtils.isEmpty(intentUriString)) { 84 Log.e(TAG, "No EXTRA_SETTINGS_EMBEDDED_DEEP_LINK_INTENT_URI for deep link"); 85 finish(); 86 return; 87 } 88 89 try { 90 intent = Intent.parseUri(intentUriString, Intent.URI_INTENT_SCHEME); 91 } catch (URISyntaxException e) { 92 Log.e(TAG, "Failed to parse deep link intent: " + e); 93 finish(); 94 return; 95 } 96 } 97 98 intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); 99 100 if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this)) { 101 startActivity(intent); 102 } else if (isSettingsIntelligence(callingActivity)) { 103 if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SETTINGS_SEARCH_ALWAYS_EXPAND)) { 104 startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey) 105 .setClass(this, DeepLinkHomepageActivityInternal.class) 106 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 107 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)); 108 } else { 109 // Register SplitPairRule for SubSettings, set clearTop false to prevent unexpected 110 // back navigation behavior. 111 ActivityEmbeddingRulesController.registerSubSettingsPairRule(this, 112 false /* clearTop */); 113 114 intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_NEW_TASK); 115 startActivity(intent); 116 117 // Pass menu key to homepage 118 final SettingsHomepageActivity homeActivity = 119 ((SettingsApplication) getApplicationContext()).getHomeActivity(); 120 if (homeActivity != null) { 121 homeActivity.getMainFragment().setHighlightMenuKey(highlightMenuKey, 122 /* scrollNeeded= */ true); 123 } 124 } 125 } else { 126 // Two-pane case 127 startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey) 128 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); 129 } 130 131 // Done. 132 finish(); 133 } 134 isSettingsIntelligence(ComponentName callingActivity)135 private boolean isSettingsIntelligence(ComponentName callingActivity) { 136 return callingActivity != null && TextUtils.equals( 137 callingActivity.getPackageName(), 138 FeatureFactory.getFactory(this).getSearchFeatureProvider() 139 .getSettingsIntelligencePkgName(this)); 140 } 141 } 142