Only allow Settings app launch search result page

Bug: 68199963
Test: robotest
Change-Id: I0018e9c60b0dd46fc2420a563a93b706bf252dc4
This commit is contained in:
Fan Zhang
2017-10-24 09:27:02 -07:00
parent 01ff9a80d0
commit 25f29bf126
28 changed files with 178 additions and 69 deletions

View File

@@ -219,6 +219,12 @@
android:theme="@style/Theme.Settings.NoActionBar"> android:theme="@style/Theme.Settings.NoActionBar">
</activity> </activity>
<activity android:name=".search.SearchResultTrampoline"
android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true"
android:exported="true">
</activity>
<!-- Top-level settings --> <!-- Top-level settings -->
<activity android:name="Settings$WifiSettingsActivity" <activity android:name="Settings$WifiSettingsActivity"

View File

@@ -94,7 +94,7 @@ public class AmbientDisplayAlwaysOnPreferenceController extends
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
AmbientDisplaySettings.class.getName(), KEY_ALWAYS_ON, AmbientDisplaySettings.class.getName(), KEY_ALWAYS_ON,
mContext.getString(R.string.ambient_display_screen_title)); mContext.getString(R.string.ambient_display_screen_title));

View File

@@ -13,6 +13,9 @@
*/ */
package com.android.settings.display; 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.Context;
import android.content.Intent; import android.content.Intent;
import android.os.UserHandle; import android.os.UserHandle;
@@ -30,9 +33,6 @@ import com.android.settings.search.InlineSwitchPayload;
import com.android.settings.search.ResultPayload; import com.android.settings.search.ResultPayload;
import com.android.settingslib.core.AbstractPreferenceController; 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 public class AmbientDisplayNotificationsPreferenceController extends
AbstractPreferenceController implements PreferenceControllerMixin, AbstractPreferenceController implements PreferenceControllerMixin,
Preference.OnPreferenceChangeListener { Preference.OnPreferenceChangeListener {
@@ -86,7 +86,7 @@ public class AmbientDisplayNotificationsPreferenceController extends
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
AmbientDisplaySettings.class.getName(), KEY_AMBIENT_DISPLAY_NOTIFICATIONS, AmbientDisplaySettings.class.getName(), KEY_AMBIENT_DISPLAY_NOTIFICATIONS,
mContext.getString(R.string.ambient_display_screen_title)); mContext.getString(R.string.ambient_display_screen_title));

View File

@@ -73,7 +73,7 @@ public class AutoBrightnessPreferenceController extends AbstractPreferenceContro
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
DisplaySettings.class.getName(), mAutoBrightnessKey, DisplaySettings.class.getName(), mAutoBrightnessKey,
mContext.getString(R.string.display_settings)); mContext.getString(R.string.display_settings));

View File

@@ -162,7 +162,7 @@ public class AssistGestureSettingsPreferenceController extends GesturePreference
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
AssistGestureSettings.class.getName(), mAssistGesturePrefKey, AssistGestureSettings.class.getName(), mAssistGesturePrefKey,
mContext.getString(R.string.display_settings)); mContext.getString(R.string.display_settings));

View File

@@ -89,7 +89,7 @@ public class DoubleTapPowerPreferenceController extends GesturePreferenceControl
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
DoubleTapPowerSettings.class.getName(), mDoubleTapPowerKey, DoubleTapPowerSettings.class.getName(), mDoubleTapPowerKey,
mContext.getString(R.string.display_settings)); mContext.getString(R.string.display_settings));

View File

@@ -89,7 +89,7 @@ public class DoubleTapScreenPreferenceController extends GesturePreferenceContro
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
DoubleTapScreenSettings.class.getName(), mDoubleTapScreenPrefKey, DoubleTapScreenSettings.class.getName(), mDoubleTapScreenPrefKey,
mContext.getString(R.string.display_settings)); mContext.getString(R.string.display_settings));

View File

@@ -95,7 +95,7 @@ public class PickupGesturePreferenceController extends GesturePreferenceControll
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
PickupGestureSettings.class.getName(), mPickUpPrefKey, PickupGestureSettings.class.getName(), mPickUpPrefKey,
mContext.getString(R.string.display_settings)); mContext.getString(R.string.display_settings));

View File

@@ -127,7 +127,7 @@ public class LocationPreferenceController extends AbstractPreferenceController
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
LocationSettings.class.getName(), KEY_LOCATION, LocationSettings.class.getName(), KEY_LOCATION,
mContext.getString(R.string.location_settings_title)); mContext.getString(R.string.location_settings_title));

View File

@@ -133,7 +133,7 @@ public class BadgingNotificationPreferenceController extends AbstractPreferenceC
@Override @Override
public ResultPayload getResultPayload() { public ResultPayload getResultPayload() {
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(mContext, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(mContext,
ConfigureNotificationSettings.class.getName(), KEY_NOTIFICATION_BADGING, ConfigureNotificationSettings.class.getName(), KEY_NOTIFICATION_BADGING,
mContext.getString(R.string.configure_notification_settings)); mContext.getString(R.string.configure_notification_settings));

View File

@@ -102,7 +102,7 @@ public class AccessibilityServiceResultLoader extends AsyncLoader<Set<? extends
} }
final String componentName = new ComponentName(serviceInfo.packageName, final String componentName = new ComponentName(serviceInfo.packageName,
serviceInfo.name).flattenToString(); serviceInfo.name).flattenToString();
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(context, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
AccessibilitySettings.class.getName(), componentName, screenTitle); AccessibilitySettings.class.getName(), componentName, screenTitle);
results.add(new SearchResult.Builder() results.add(new SearchResult.Builder()

View File

@@ -46,21 +46,28 @@ public class DatabaseIndexingUtils {
"SEARCH_INDEX_DATA_PROVIDER"; "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) { 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(); final Bundle args = new Bundle();
args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key); args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, key);
return Utils.onBuildStartFragmentIntent(context, final Intent searchDestination = Utils.onBuildStartFragmentIntent(context,
className, args, null, 0, screenTitle, false, className, args, null, 0, screenTitle, false, sourceMetricsCategory);
MetricsProto.MetricsEvent.DASHBOARD_SEARCH_RESULTS); 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 * @param className which wil provide the map between from {@link Uri}s to
* {@link PreferenceControllerMixin} * {@link PreferenceControllerMixin}
* @param context
* @return A map between {@link Uri}s and {@link PreferenceControllerMixin}s to get the payload * @return A map between {@link Uri}s and {@link PreferenceControllerMixin}s to get the payload
* types for Settings. * types for Settings.
*/ */
@@ -85,7 +92,7 @@ public class DatabaseIndexingUtils {
List<AbstractPreferenceController> controllers = List<AbstractPreferenceController> controllers =
provider.getPreferenceControllers(context); provider.getPreferenceControllers(context);
if (controllers == null ) { if (controllers == null) {
return null; return null;
} }

View File

@@ -107,7 +107,7 @@ public class InputDeviceResultLoader extends AsyncLoader<Set<? extends SearchRes
: context.getString(R.string.keyboard_layout_default_label); : context.getString(R.string.keyboard_layout_default_label);
final String key = deviceName; final String key = deviceName;
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(context, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
PHYSICAL_KEYBOARD_FRAGMENT, key, screenTitle); PHYSICAL_KEYBOARD_FRAGMENT, key, screenTitle);
results.add(new SearchResult.Builder() results.add(new SearchResult.Builder()
.setTitle(deviceName) .setTitle(deviceName)
@@ -140,7 +140,7 @@ public class InputDeviceResultLoader extends AsyncLoader<Set<? extends SearchRes
final ServiceInfo serviceInfo = info.getServiceInfo(); final ServiceInfo serviceInfo = info.getServiceInfo();
final String key = new ComponentName(serviceInfo.packageName, serviceInfo.name) final String key = new ComponentName(serviceInfo.packageName, serviceInfo.name)
.flattenToString(); .flattenToString();
final Intent intent = DatabaseIndexingUtils.buildSubsettingIntent(context, final Intent intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context,
VIRTUAL_KEYBOARD_FRAGMENT, key, screenTitle); VIRTUAL_KEYBOARD_FRAGMENT, key, screenTitle);
results.add(new SearchResult.Builder() results.add(new SearchResult.Builder()
.setTitle(title) .setTitle(title)

View File

@@ -20,6 +20,7 @@ import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.os.UserHandle; import android.os.UserHandle;
import android.support.annotation.VisibleForTesting;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@@ -34,6 +35,8 @@ import java.util.List;
public class IntentSearchViewHolder extends SearchViewHolder { public class IntentSearchViewHolder extends SearchViewHolder {
private static final String TAG = "IntentSearchViewHolder"; private static final String TAG = "IntentSearchViewHolder";
@VisibleForTesting
static final int REQUEST_CODE_NO_OP = 0;
public IntentSearchViewHolder(View view) { public IntentSearchViewHolder(View view) {
super(view); super(view);
@@ -60,7 +63,7 @@ public class IntentSearchViewHolder extends SearchViewHolder {
final PackageManager pm = fragment.getActivity().getPackageManager(); final PackageManager pm = fragment.getActivity().getPackageManager();
final List<ResolveInfo> info = pm.queryIntentActivities(intent, 0 /* flags */); final List<ResolveInfo> info = pm.queryIntentActivities(intent, 0 /* flags */);
if (info != null && !info.isEmpty()) { if (info != null && !info.isEmpty()) {
fragment.startActivity(intent); fragment.startActivityForResult(intent, REQUEST_CODE_NO_OP);
} else { } else {
Log.e(TAG, "Cannot launch search result, title: " Log.e(TAG, "Cannot launch search result, title: "
+ result.title + ", " + intent); + result.title + ", " + intent);

View File

@@ -16,6 +16,8 @@
*/ */
package com.android.settings.search; package com.android.settings.search;
import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.view.View; import android.view.View;
@@ -32,6 +34,15 @@ public interface SearchFeatureProvider {
*/ */
boolean isEnabled(Context context); 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. * Returns a new loader to search in index database.
*/ */

View File

@@ -17,6 +17,7 @@
package com.android.settings.search; package com.android.settings.search;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
@@ -42,6 +43,18 @@ public class SearchFeatureProviderImpl implements SearchFeatureProvider {
return true; return true;
} }
@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 @Override
public DatabaseResultLoader getDatabaseSearchLoader(Context context, String query) { public DatabaseResultLoader getDatabaseSearchLoader(Context context, String query) {
return new DatabaseResultLoader(context, cleanQuery(query), getSiteMapManager()); return new DatabaseResultLoader(context, cleanQuery(query), getSiteMapManager());

View File

@@ -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();
}
}

View File

@@ -273,7 +273,7 @@ public class IndexData {
|| TextUtils.equals(mIntentTargetPackage, || TextUtils.equals(mIntentTargetPackage,
SearchIndexableResources.SUBSETTING_TARGET_PACKAGE)) { SearchIndexableResources.SUBSETTING_TARGET_PACKAGE)) {
// Action is null, we will launch it as a sub-setting // Action is null, we will launch it as a sub-setting
intent = DatabaseIndexingUtils.buildSubsettingIntent(context, mClassName, mKey, intent = DatabaseIndexingUtils.buildSearchResultPageIntent(context, mClassName, mKey,
mScreenTitle); mScreenTitle);
} else { } else {
intent = new Intent(mIntentAction); intent = new Intent(mIntentAction);

View File

@@ -16,14 +16,21 @@
package com.android.settings.applications.assist; 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.ContentResolver;
import android.content.Context; import android.content.Context;
import android.provider.Settings; import android.provider.Settings;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
import android.support.v7.preference.TwoStatePreference; import android.support.v7.preference.TwoStatePreference;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
import org.junit.Before; import org.junit.Before;
@@ -35,13 +42,6 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.util.ReflectionHelpers; 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) @RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AssistContextPreferenceControllerTest { public class AssistContextPreferenceControllerTest {

View File

@@ -17,7 +17,6 @@
package com.android.settings.display; package com.android.settings.display;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;

View File

@@ -17,9 +17,7 @@
package com.android.settings.display; package com.android.settings.display;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_AMBIENT_DISPLAY; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_AMBIENT_DISPLAY;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
@@ -33,11 +31,11 @@ import android.provider.Settings;
import android.support.v14.preference.SwitchPreference; import android.support.v14.preference.SwitchPreference;
import com.android.internal.hardware.AmbientDisplayConfiguration; 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.InlinePayload;
import com.android.settings.search.InlineSwitchPayload; import com.android.settings.search.InlineSwitchPayload;
import com.android.settings.testutils.SettingsRobolectricTestRunner; 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 com.android.settings.testutils.shadow.ShadowSecureSettings;
import org.junit.Before; import org.junit.Before;

View File

@@ -16,14 +16,20 @@
package com.android.settings.display; 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.ContentResolver;
import android.content.Context; import android.content.Context;
import android.provider.Settings; import android.provider.Settings;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.search.InlinePayload; import com.android.settings.search.InlinePayload;
import com.android.settings.search.InlineSwitchPayload; import com.android.settings.search.InlineSwitchPayload;
import com.android.settings.search.ResultPayload; import com.android.settings.search.ResultPayload;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -34,11 +40,6 @@ import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication; 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) @RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class AutoBrightnessPreferenceControllerTest { public class AutoBrightnessPreferenceControllerTest {

View File

@@ -35,7 +35,6 @@ import com.android.settings.search.InlineSwitchPayload;
import com.android.settings.search.ResultPayload; import com.android.settings.search.ResultPayload;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.SettingsShadowResources; import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.SettingsShadowSystemProperties;
import com.android.settings.testutils.shadow.ShadowSecureSettings; import com.android.settings.testutils.shadow.ShadowSecureSettings;
import org.junit.After; import org.junit.After;

View File

@@ -16,7 +16,6 @@
package com.android.settings.location; package com.android.settings.location;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -34,11 +33,11 @@ import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen; import android.support.v7.preference.PreferenceScreen;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.TestConfig;
import com.android.settings.search.InlineListPayload; import com.android.settings.search.InlineListPayload;
import com.android.settings.search.InlinePayload; import com.android.settings.search.InlinePayload;
import com.android.settings.search.ResultPayload; import com.android.settings.search.ResultPayload;
import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.shadow.ShadowSecureSettings; import com.android.settings.testutils.shadow.ShadowSecureSettings;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;

View File

@@ -16,6 +16,14 @@
package com.android.settings.notification; 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.ContentResolver;
import android.content.Context; import android.content.Context;
import android.provider.Settings; import android.provider.Settings;
@@ -38,16 +46,6 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication; 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) @RunWith(RobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class BadgingNotificationPreferenceControllerTest { public class BadgingNotificationPreferenceControllerTest {

View File

@@ -23,10 +23,10 @@ import android.content.Context;
import android.util.ArrayMap; import android.util.ArrayMap;
import com.android.internal.hardware.AmbientDisplayConfiguration; import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.deviceinfo.SystemUpdatePreferenceController; import com.android.settings.deviceinfo.SystemUpdatePreferenceController;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;

View File

@@ -221,7 +221,8 @@ public class IntentSearchViewHolderTest {
assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY); assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY);
assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.VISIBLE);
verify(mFragment).onSearchResultClicked(eq(mHolder), any(SearchResult.class)); 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 @Test
@@ -237,7 +238,8 @@ public class IntentSearchViewHolderTest {
assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY); assertThat(mHolder.summaryView.getText()).isEqualTo(SUMMARY);
assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.VISIBLE); assertThat(mHolder.summaryView.getVisibility()).isEqualTo(View.VISIBLE);
verify(mFragment).onSearchResultClicked(eq(mHolder), any(SearchResult.class)); 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) { private SearchResult getSearchResult(String title, String summary, Drawable icon) {

View File

@@ -17,8 +17,10 @@
package com.android.settings.search; package com.android.settings.search;
import static com.google.common.truth.Truth.assertThat;
import android.app.Activity; import android.app.Activity;
import android.view.Menu; import android.content.ComponentName;
import com.android.settings.TestConfig; import com.android.settings.TestConfig;
import com.android.settings.dashboard.SiteMapManager; import com.android.settings.dashboard.SiteMapManager;
@@ -27,23 +29,16 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric; import org.robolectric.Robolectric;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
@RunWith(SettingsRobolectricTestRunner.class) @RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class SearchFeatureProviderImplTest { public class SearchFeatureProviderImplTest {
private SearchFeatureProviderImpl mProvider; private SearchFeatureProviderImpl mProvider;
private Activity mActivity; private Activity mActivity;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Menu menu;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@@ -76,4 +71,20 @@ public class SearchFeatureProviderImplTest {
assertThat(loader.mQuery).isEqualTo(query.trim()); 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);
}
} }