Merge "Only allow Settings app launch search result page"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index e1d2225..69dc2ae 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -219,6 +219,12 @@
                   android:theme="@style/Theme.Settings.NoActionBar">
         </activity>
 
+        <activity android:name=".search.SearchResultTrampoline"
+                  android:theme="@android:style/Theme.NoDisplay"
+                  android:excludeFromRecents="true"
+                  android:exported="true">
+        </activity>
+
         <!-- Top-level settings -->
 
         <activity android:name="Settings$WifiSettingsActivity"
diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
index 280098d..2fb538e 100644
--- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceController.java
@@ -94,7 +94,7 @@
 
     @Override
     public ResultPayload getResultPayload() {
-        final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 AmbientDisplaySettings.class.getName(), KEY_ALWAYS_ON,
                 mContext.getString(R.string.ambient_display_screen_title));
 
diff --git a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
index c1af133..68a21ce 100644
--- a/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
+++ b/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceController.java
@@ -13,6 +13,9 @@
  */
 package com.android.settings.display;
 
+import static android.provider.Settings.Secure.DOZE_ENABLED;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_AMBIENT_DISPLAY;
+
 import android.content.Context;
 import android.content.Intent;
 import android.os.UserHandle;
@@ -30,9 +33,6 @@
 import com.android.settings.search.ResultPayload;
 import com.android.settingslib.core.AbstractPreferenceController;
 
-import static android.provider.Settings.Secure.DOZE_ENABLED;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_AMBIENT_DISPLAY;
-
 public class AmbientDisplayNotificationsPreferenceController extends
         AbstractPreferenceController implements PreferenceControllerMixin,
         Preference.OnPreferenceChangeListener {
@@ -86,7 +86,7 @@
 
     @Override
     public ResultPayload getResultPayload() {
-        final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 AmbientDisplaySettings.class.getName(), KEY_AMBIENT_DISPLAY_NOTIFICATIONS,
                 mContext.getString(R.string.ambient_display_screen_title));
 
diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
index e74a1a0..f242022 100644
--- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java
+++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
@@ -73,7 +73,7 @@
 
     @Override
     public ResultPayload getResultPayload() {
-        final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 DisplaySettings.class.getName(), mAutoBrightnessKey,
                 mContext.getString(R.string.display_settings));
 
diff --git a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
index bf6ee8c..1ecba0d 100644
--- a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
+++ b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java
@@ -162,7 +162,7 @@
 
     @Override
     public ResultPayload getResultPayload() {
-        final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 AssistGestureSettings.class.getName(), mAssistGesturePrefKey,
                 mContext.getString(R.string.display_settings));
 
diff --git a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
index bee9893..049ee18 100644
--- a/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTapPowerPreferenceController.java
@@ -89,7 +89,7 @@
 
     @Override
     public ResultPayload getResultPayload() {
-        final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 DoubleTapPowerSettings.class.getName(), mDoubleTapPowerKey,
                 mContext.getString(R.string.display_settings));
 
diff --git a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
index 9ec06ae..deffa97 100644
--- a/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
+++ b/src/com/android/settings/gestures/DoubleTapScreenPreferenceController.java
@@ -89,7 +89,7 @@
 
     @Override
     public ResultPayload getResultPayload() {
-        final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 DoubleTapScreenSettings.class.getName(), mDoubleTapScreenPrefKey,
                 mContext.getString(R.string.display_settings));
 
diff --git a/src/com/android/settings/gestures/PickupGesturePreferenceController.java b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
index e1b444c..314cbc3 100644
--- a/src/com/android/settings/gestures/PickupGesturePreferenceController.java
+++ b/src/com/android/settings/gestures/PickupGesturePreferenceController.java
@@ -95,7 +95,7 @@
 
     @Override
     public ResultPayload getResultPayload() {
-        final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 PickupGestureSettings.class.getName(), mPickUpPrefKey,
                 mContext.getString(R.string.display_settings));
 
diff --git a/src/com/android/settings/location/LocationPreferenceController.java b/src/com/android/settings/location/LocationPreferenceController.java
index 225100f..9b68848 100644
--- a/src/com/android/settings/location/LocationPreferenceController.java
+++ b/src/com/android/settings/location/LocationPreferenceController.java
@@ -127,7 +127,7 @@
 
     @Override
     public ResultPayload getResultPayload() {
-        final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 LocationSettings.class.getName(), KEY_LOCATION,
                 mContext.getString(R.string.location_settings_title));
 
diff --git a/src/com/android/settings/notification/BadgingNotificationPreferenceController.java b/src/com/android/settings/notification/BadgingNotificationPreferenceController.java
index 94eccf9..18efd43 100644
--- a/src/com/android/settings/notification/BadgingNotificationPreferenceController.java
+++ b/src/com/android/settings/notification/BadgingNotificationPreferenceController.java
@@ -133,7 +133,7 @@
 
     @Override
     public ResultPayload getResultPayload() {
-        final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext,
+        final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
                 ConfigureNotificationSettings.class.getName(), KEY_NOTIFICATION_BADGING,
                 mContext.getString(R.string.configure_notification_settings));
 
diff --git a/src/com/android/settings/search/AccessibilityServiceResultLoader.java b/src/com/android/settings/search/AccessibilityServiceResultLoader.java
index 64cceb7..345ab30 100644
--- a/src/com/android/settings/search/AccessibilityServiceResultLoader.java
+++ b/src/com/android/settings/search/AccessibilityServiceResultLoader.java
@@ -102,7 +102,7 @@
             }
             final String componentName = new ComponentName(serviceInfo.packageName,
                     serviceInfo.name).flattenToString();
-            final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(context,
+            final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
                     AccessibilitySettings.class.getName(), componentName, screenTitle);
 
             results.add(new SearchResult.Builder()
diff --git a/src/com/android/settings/search/DatabaseIndexingUtils.java b/src/com/android/settings/search/DatabaseIndexingUtils.java
index ce58256..8d63ea5 100644
--- a/src/com/android/settings/search/DatabaseIndexingUtils.java
+++ b/src/com/android/settings/search/DatabaseIndexingUtils.java
@@ -46,21 +46,28 @@
             "SEARCH_INDEX_DATA_PROVIDER";
 
     /**
-     * Builds intent into a subsetting.
+     * Builds intent that launches the search destination as a sub-setting.
      */
-    public static Intent buildSubsettingIntent(Context context, String className, String key,
+    public static Intent buildSearchResultPageIntent(Context context, String className, String key,
             String screenTitle) {
+        return buildSearchResultPageIntent(context, className, key, screenTitle,
+                MetricsProto.MetricsEvent.DASHBOARD_SEARCH_RESULTS);
+    }
+
+    public static Intent  buildSearchResultPageIntent(Context context, String className, String key,
+            String screenTitle, int sourceMetricsCategory) {
         final Bundle args = new Bundle();
         args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
-        return Utils.onBuildStartFragmentIntent(context,
-                className, args, null, 0, screenTitle, false,
-                MetricsProto.MetricsEvent.DASHBOARD_SEARCH_RESULTS);
+        final Intent searchDestination = Utils.onBuildStartFragmentIntent(context,
+                className, args, null, 0, screenTitle, false, sourceMetricsCategory);
+        searchDestination.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
+        searchDestination.setClass(context, SearchResultTrampoline.class);
+        return searchDestination;
     }
 
     /**
      * @param className which wil provide the map between from {@link Uri}s to
-     * {@link PreferenceControllerMixin}
-     * @param context
+     *                  {@link PreferenceControllerMixin}
      * @return A map between {@link Uri}s and {@link PreferenceControllerMixin}s to get the payload
      * types for Settings.
      */
@@ -85,7 +92,7 @@
         List<AbstractPreferenceController> controllers =
                 provider.getPreferenceControllers(context);
 
-        if (controllers == null ) {
+        if (controllers == null) {
             return null;
         }
 
@@ -106,7 +113,7 @@
     /**
      * @param uriMap Map between the {@link PreferenceControllerMixin} keys
      *               and the controllers themselves.
-     * @param key The look-up key
+     * @param key    The look-up key
      * @return The Payload from the {@link PreferenceControllerMixin} specified by the key,
      * if it exists. Otherwise null.
      */
diff --git a/src/com/android/settings/search/InputDeviceResultLoader.java b/src/com/android/settings/search/InputDeviceResultLoader.java
index 61e1ad1..e5e6553 100644
--- a/src/com/android/settings/search/InputDeviceResultLoader.java
+++ b/src/com/android/settings/search/InputDeviceResultLoader.java
@@ -107,7 +107,7 @@
                     : context.getString(R.string.keyboard_layout_default_label);
             final String key = deviceName;
 
-            final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(context,
+            final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
                     PHYSICAL_KEYBOARD_FRAGMENT, key, screenTitle);
             results.add(new SearchResult.Builder()
                     .setTitle(deviceName)
@@ -140,7 +140,7 @@
             final ServiceInfo serviceInfo = info.getServiceInfo();
             final String key = new ComponentName(serviceInfo.packageName, serviceInfo.name)
                     .flattenToString();
-            final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(context,
+            final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
                     VIRTUAL_KEYBOARD_FRAGMENT, key, screenTitle);
             results.add(new SearchResult.Builder()
                     .setTitle(title)
diff --git a/src/com/android/settings/search/IntentSearchViewHolder.java b/src/com/android/settings/search/IntentSearchViewHolder.java
index 711d08e..8f6aa2c 100644
--- a/src/com/android/settings/search/IntentSearchViewHolder.java
+++ b/src/com/android/settings/search/IntentSearchViewHolder.java
@@ -20,6 +20,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.UserHandle;
+import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 import android.view.View;
 
@@ -34,6 +35,8 @@
 public class IntentSearchViewHolder extends SearchViewHolder {
 
     private static final String TAG = "IntentSearchViewHolder";
+    @VisibleForTesting
+    static final int REQUEST_CODE_NO_OP = 0;
 
     public IntentSearchViewHolder(View view) {
         super(view);
@@ -60,7 +63,7 @@
                 final PackageManager pm = fragment.getActivity().getPackageManager();
                 final List<ResolveInfo> info = pm.queryIntentActivities(intent, 0 /* flags */);
                 if (info != null && !info.isEmpty()) {
-                    fragment.startActivity(intent);
+                    fragment.startActivityForResult(intent, REQUEST_CODE_NO_OP);
                 } else {
                     Log.e(TAG, "Cannot launch search result, title: "
                             + result.title + ", " + intent);
diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java
index 956808d..4df8203 100644
--- a/src/com/android/settings/search/SearchFeatureProvider.java
+++ b/src/com/android/settings/search/SearchFeatureProvider.java
@@ -16,6 +16,8 @@
  */
 package com.android.settings.search;
 
+import android.annotation.NonNull;
+import android.content.ComponentName;
 import android.content.Context;
 import android.view.View;
 
@@ -33,6 +35,15 @@
     boolean isEnabled(Context context);
 
     /**
+     * Ensures the caller has necessary privilege to launch search result page.
+     *
+     * @throws IllegalArgumentException when caller is null
+     * @throws SecurityException        when caller is not allowed to launch search result page
+     */
+    void verifyLaunchSearchResultPageCaller(Context context, @NonNull ComponentName caller)
+            throws SecurityException, IllegalArgumentException;
+
+    /**
      * Returns a new loader to search in index database.
      */
     DatabaseResultLoader getDatabaseSearchLoader(Context context, String query);
diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java
index 420b847..8c4883e 100644
--- a/src/com/android/settings/search/SearchFeatureProviderImpl.java
+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java
@@ -17,6 +17,7 @@
 
 package com.android.settings.search;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.text.TextUtils;
 import android.util.Log;
@@ -43,6 +44,18 @@
     }
 
     @Override
+    public void verifyLaunchSearchResultPageCaller(Context context, ComponentName caller) {
+        if (caller == null) {
+            throw new IllegalArgumentException("ExternalSettingsTrampoline intents "
+                    + "must be called with startActivityForResult");
+        }
+        final String packageName = caller.getPackageName();
+        if (!TextUtils.equals(packageName, context.getPackageName())) {
+            throw new SecurityException("Only Settings app can launch search result page");
+        }
+    }
+
+    @Override
     public DatabaseResultLoader getDatabaseSearchLoader(Context context, String query) {
         return new DatabaseResultLoader(context, cleanQuery(query), getSiteMapManager());
     }
diff --git a/src/com/android/settings/search/SearchResultTrampoline.java b/src/com/android/settings/search/SearchResultTrampoline.java
new file mode 100644
index 0000000..3bbe6bd
--- /dev/null
+++ b/src/com/android/settings/search/SearchResultTrampoline.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 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 static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.android.settings.SettingsActivity;
+import com.android.settings.SubSettings;
+import com.android.settings.overlay.FeatureFactory;
+
+/**
+ * A trampoline activity that launches setting result page.
+ */
+public class SearchResultTrampoline extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // First make sure caller has privilege to launch a search result page.
+        FeatureFactory.getFactory(this)
+                .getSearchFeatureProvider()
+                .verifyLaunchSearchResultPageCaller(this, getCallingActivity());
+        // Didn't crash, proceed and launch the result as a subsetting.
+        final Intent intent = getIntent();
+
+        // Hack to take EXTRA_FRAGMENT_ARG_KEY from intent and set into
+        // EXTRA_SHOW_FRAGMENT_ARGUMENTS. This is necessary because intent could be from external
+        // caller and args may not persisted.
+        final String settingKey = intent.getStringExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY);
+        final Bundle args = new Bundle();
+        args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, settingKey);
+        intent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
+
+        // Reroute request to SubSetting.
+        intent.setClass(this /* context */, SubSettings.class)
+                .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+        startActivity(intent);
+
+        // Done.
+        finish();
+    }
+
+}
diff --git a/src/com/android/settings/search/indexing/IndexData.java b/src/com/android/settings/search/indexing/IndexData.java
index 0e1fa2d..9dad3fe 100644
--- a/src/com/android/settings/search/indexing/IndexData.java
+++ b/src/com/android/settings/search/indexing/IndexData.java
@@ -273,7 +273,7 @@
                     || TextUtils.equals(mIntentTargetPackage,
                     SearchIndexableResources.SUBSETTING_TARGET_PACKAGE)) {
                 // Action is null, we will launch it as a sub-setting
-                intent = DatabaseIndexingUtils.buildSubsettingIntent(context, mClassName, mKey,
+                intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context, mClassName, mKey,
                         mScreenTitle);
             } else {
                 intent = new Intent(mIntentAction);
diff --git a/tests/robotests/src/com/android/settings/applications/assist/AssistContextPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/assist/AssistContextPreferenceControllerTest.java
index 6c8ad9b..c71bc29 100644
--- a/tests/robotests/src/com/android/settings/applications/assist/AssistContextPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/assist/AssistContextPreferenceControllerTest.java
@@ -16,14 +16,21 @@
 
 package com.android.settings.applications.assist;
 
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import android.content.ContentResolver;
 import android.content.Context;
 import android.provider.Settings;
 import android.support.v7.preference.PreferenceScreen;
 import android.support.v7.preference.TwoStatePreference;
 
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
 import org.junit.Before;
@@ -35,13 +42,6 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.util.ReflectionHelpers;
 
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class AssistContextPreferenceControllerTest {
diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
index 3869807..dfe81db 100644
--- a/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AmbientDisplayAlwaysOnPreferenceControllerTest.java
@@ -17,7 +17,6 @@
 package com.android.settings.display;
 
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
diff --git a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
index 242a05d..e1ce694 100644
--- a/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AmbientDisplayNotificationsPreferenceControllerTest.java
@@ -17,9 +17,7 @@
 package com.android.settings.display;
 
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_AMBIENT_DISPLAY;
-
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
@@ -33,11 +31,11 @@
 import android.support.v14.preference.SwitchPreference;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.settings.TestConfig;
+import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.search.InlinePayload;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
-import com.android.settings.core.instrumentation.MetricsFeatureProvider;
 import com.android.settings.testutils.shadow.ShadowSecureSettings;
 
 import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java
index 02f46f2..b46441d 100644
--- a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java
@@ -16,14 +16,20 @@
 
 package com.android.settings.display;
 
+import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE;
+import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
+import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
+import static com.google.common.truth.Truth.assertThat;
+
 import android.content.ContentResolver;
 import android.content.Context;
 import android.provider.Settings;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
 import com.android.settings.TestConfig;
 import com.android.settings.search.InlinePayload;
 import com.android.settings.search.InlineSwitchPayload;
 import com.android.settings.search.ResultPayload;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -34,11 +40,6 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
-import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE;
-import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
-import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
-import static com.google.common.truth.Truth.assertThat;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class AutoBrightnessPreferenceControllerTest {
diff --git a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java
index 0c804b3..1f5ca20 100644
--- a/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/gestures/DoubleTapPowerPreferenceControllerTest.java
@@ -35,7 +35,6 @@
 import com.android.settings.search.ResultPayload;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.SettingsShadowResources;
-import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
 import com.android.settings.testutils.shadow.ShadowSecureSettings;
 
 import org.junit.After;
diff --git a/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java
index 87691a5..355d6d0 100644
--- a/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/location/LocationPreferenceControllerTest.java
@@ -16,7 +16,6 @@
 package com.android.settings.location;
 
 import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.verify;
@@ -34,11 +33,11 @@
 import android.support.v7.preference.PreferenceScreen;
 
 import com.android.settings.R;
+import com.android.settings.TestConfig;
 import com.android.settings.search.InlineListPayload;
 import com.android.settings.search.InlinePayload;
 import com.android.settings.search.ResultPayload;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
-import com.android.settings.TestConfig;
 import com.android.settings.testutils.shadow.ShadowSecureSettings;
 import com.android.settingslib.core.lifecycle.Lifecycle;
 
diff --git a/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java
index c1a7d05..ac158b6 100644
--- a/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/BadgingNotificationPreferenceControllerTest.java
@@ -16,6 +16,14 @@
 
 package com.android.settings.notification;
 
+import static android.provider.Settings.Secure.NOTIFICATION_BADGING;
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 import android.content.ContentResolver;
 import android.content.Context;
 import android.provider.Settings;
@@ -38,16 +46,6 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
 
-import static android.provider.Settings.Secure.NOTIFICATION_BADGING;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
 @RunWith(RobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class BadgingNotificationPreferenceControllerTest {
diff --git a/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java b/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java
index 3bfa936..126abb9 100644
--- a/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/search/DatabaseIndexingUtilsTest.java
@@ -23,10 +23,10 @@
 import android.util.ArrayMap;
 
 import com.android.internal.hardware.AmbientDisplayConfiguration;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.TestConfig;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.deviceinfo.SystemUpdatePreferenceController;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java b/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java
index a3826f6..4ec080c 100644
--- a/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java
+++ b/tests/robotests/src/com/android/settings/search/IntentSearchViewHolderTest.java
@@ -221,7 +221,8 @@
         assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY);
         assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.VISIBLE);
         verify(mFragment).onSearchResultClicked(eq(mHolder), any(SearchResult.class));
-        verify(mFragment).startActivity(result.payload.getIntent());
+        verify(mFragment).startActivityForResult(result.payload.getIntent(),
+                IntentSearchViewHolder.REQUEST_CODE_NO_OP);
     }
 
     @Test
@@ -237,7 +238,8 @@
         assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY);
         assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.VISIBLE);
         verify(mFragment).onSearchResultClicked(eq(mHolder), any(SearchResult.class));
-        verify(mFragment, never()).startActivity(any(Intent.class));
+        verify(mFragment, never()).startActivityForResult(result.payload.getIntent(),
+                IntentSearchViewHolder.REQUEST_CODE_NO_OP);
     }
 
     private SearchResult getSearchResult(String title, String summary, Drawable icon) {
diff --git a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
index 30ffaf8..050d7aa 100644
--- a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java
@@ -17,8 +17,10 @@
 
 package com.android.settings.search;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.app.Activity;
-import android.view.Menu;
+import android.content.ComponentName;
 
 import com.android.settings.TestConfig;
 import com.android.settings.dashboard.SiteMapManager;
@@ -27,23 +29,16 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.annotation.Config;
 
-import static com.google.common.truth.Truth.assertThat;
-
 @RunWith(SettingsRobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
 public class SearchFeatureProviderImplTest {
     private SearchFeatureProviderImpl mProvider;
     private Activity mActivity;
 
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private Menu menu;
-
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
@@ -76,4 +71,20 @@
         assertThat(loader.mQuery).isEqualTo(query.trim());
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void verifyLaunchSearchResultPageCaller_nullCaller_shouldCrash() {
+        mProvider.verifyLaunchSearchResultPageCaller(mActivity, null /* caller */);
+    }
+
+    @Test(expected = SecurityException.class)
+    public void everifyLaunchSearchResultPageCaller_badCaller_shouldCrash() {
+        final ComponentName cn = new ComponentName("pkg", "class");
+        mProvider.verifyLaunchSearchResultPageCaller(mActivity, cn);
+    }
+
+    @Test
+    public void verifyLaunchSearchResultPageCaller_goodCaller_shouldNotCrash() {
+        final ComponentName cn = new ComponentName(mActivity.getPackageName(), "class");
+        mProvider.verifyLaunchSearchResultPageCaller(mActivity, cn);
+    }
 }