Commit e5387439 authored by Eric Seckler's avatar Eric Seckler Committed by Commit Bot

tracing: Make tracing mode and categories configurable (android)

Adds preferences for configuring the tracing mode and enabled tracing
categories to the mobile tracing preferences.

Bug: 898512
Change-Id: I23583dd24868918ce29eebce68568344b7c3c2f0
Binary-Size: feature implementation, strings will not be translated.
Reviewed-on: https://chromium-review.googlesource.com/c/1340300
Commit-Queue: Eric Seckler <eseckler@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609657}
parent 94123b05
...@@ -4,7 +4,21 @@ ...@@ -4,7 +4,21 @@
found in the LICENSE file. --> found in the LICENSE file. -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- TODO(eseckler): Add configuration options for categories and tracing mode. --> <Preference
android:fragment="org.chromium.chrome.browser.preferences.developer.TracingCategoriesPreferences"
android:key="default_categories"
android:title="@string/prefs_tracing_default_categories_title"
android:order="0"/>
<Preference
android:fragment="org.chromium.chrome.browser.preferences.developer.TracingCategoriesPreferences"
android:key="non_default_categories"
android:title="@string/prefs_tracing_non_default_categories_title"
android:order="1"/>
<org.chromium.chrome.browser.preferences.ChromeBaseListPreference
android:key="mode"
android:title="@string/prefs_tracing_mode_title"
android:persistent="false"
android:order="2"/>
<org.chromium.chrome.browser.preferences.ButtonPreference <org.chromium.chrome.browser.preferences.ButtonPreference
android:key="start_recording"/> android:key="start_recording"/>
<org.chromium.chrome.browser.preferences.TextMessagePreference <org.chromium.chrome.browser.preferences.TextMessagePreference
......
...@@ -28,8 +28,7 @@ public class AndroidPaymentAppsFragment extends PreferenceFragment { ...@@ -28,8 +28,7 @@ public class AndroidPaymentAppsFragment extends PreferenceFragment {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
PreferenceUtils.addPreferencesFromResource( PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen);
this, R.xml.autofill_and_payments_preference_fragment_screen);
getActivity().setTitle(R.string.payment_apps_title); getActivity().setTitle(R.string.payment_apps_title);
} }
......
...@@ -35,8 +35,7 @@ public class AutofillPaymentMethodsFragment ...@@ -35,8 +35,7 @@ public class AutofillPaymentMethodsFragment
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
PreferenceUtils.addPreferencesFromResource( PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen);
this, R.xml.autofill_and_payments_preference_fragment_screen);
getActivity().setTitle(R.string.autofill_payment_methods); getActivity().setTitle(R.string.autofill_payment_methods);
} }
......
...@@ -34,8 +34,7 @@ public class AutofillProfilesFragment ...@@ -34,8 +34,7 @@ public class AutofillProfilesFragment
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
PreferenceUtils.addPreferencesFromResource( PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen);
this, R.xml.autofill_and_payments_preference_fragment_screen);
getActivity().setTitle(R.string.autofill_addresses_settings_title); getActivity().setTitle(R.string.autofill_addresses_settings_title);
} }
......
eseckler@chromium.org
skyostil@chromium.org
per-file Tracing*=file://base/trace_event/OWNERS
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.preferences.developer;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference;
import org.chromium.chrome.browser.preferences.PreferenceUtils;
import org.chromium.chrome.browser.tracing.TracingController;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Settings fragment that configures chrome tracing categories of a specific type. The type is
* passed to the fragment via an extra (EXTRA_CATEGORY_TYPE).
*/
public class TracingCategoriesPreferences
extends PreferenceFragment implements Preference.OnPreferenceChangeListener {
public static final String EXTRA_CATEGORY_TYPE = "type";
private @TracingPreferences.CategoryType int mType;
private Set<String> mEnabledCategories;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.prefs_tracing_category_selection_title);
PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen);
getPreferenceScreen().setOrderingAsAdded(true);
mType = getArguments().getInt(EXTRA_CATEGORY_TYPE);
mEnabledCategories = new HashSet<>(TracingPreferences.getEnabledCategories(mType));
List<String> sortedCategories =
new ArrayList<>(TracingController.getInstance().getKnownCategories());
Collections.sort(sortedCategories);
for (String category : sortedCategories) {
if (TracingPreferences.getCategoryType(category) == mType) createPreference(category);
}
}
private void createPreference(String category) {
CheckBoxPreference preference = new ChromeBaseCheckBoxPreference(getActivity(), null);
preference.setKey(category);
preference.setTitle(category.startsWith(TracingPreferences.NON_DEFAULT_CATEGORY_PREFIX)
? category.substring(
TracingPreferences.NON_DEFAULT_CATEGORY_PREFIX.length())
: category);
preference.setChecked(mEnabledCategories.contains(category));
preference.setPersistent(false); // We persist the preference value ourselves.
preference.setOnPreferenceChangeListener(this);
getPreferenceScreen().addPreference(preference);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (boolean) newValue;
if (value) {
mEnabledCategories.add(preference.getKey());
} else {
mEnabledCategories.remove(preference.getKey());
}
TracingPreferences.setEnabledCategories(mType, mEnabledCategories);
return true;
}
}
...@@ -5,36 +5,189 @@ ...@@ -5,36 +5,189 @@
package org.chromium.chrome.browser.preferences.developer; package org.chromium.chrome.browser.preferences.developer;
import android.os.Bundle; import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.support.annotation.IntDef;
import org.chromium.base.ContextUtils;
import org.chromium.base.VisibleForTesting; import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.PreferenceUtils; import org.chromium.chrome.browser.preferences.PreferenceUtils;
import org.chromium.chrome.browser.tracing.TracingController; import org.chromium.chrome.browser.tracing.TracingController;
import org.chromium.chrome.browser.tracing.TracingNotificationManager; import org.chromium.chrome.browser.tracing.TracingNotificationManager;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
/** /**
* Settings fragment that shows options for recording a performance trace. * Settings fragment that shows options for recording a performance trace.
*/ */
public class TracingPreferences extends PreferenceFragment implements TracingController.Observer { public class TracingPreferences extends PreferenceFragment implements TracingController.Observer {
static final String NON_DEFAULT_CATEGORY_PREFIX = "disabled-by-default-";
@VisibleForTesting
static final String UI_PREF_DEFAULT_CATEGORIES = "default_categories";
@VisibleForTesting
static final String UI_PREF_NON_DEFAULT_CATEGORIES = "non_default_categories";
@VisibleForTesting
static final String UI_PREF_MODE = "mode";
@VisibleForTesting @VisibleForTesting
static final String UI_PREF_START_RECORDING = "start_recording"; static final String UI_PREF_START_RECORDING = "start_recording";
@VisibleForTesting @VisibleForTesting
static final String UI_PREF_TRACING_STATUS = "tracing_status"; static final String UI_PREF_TRACING_STATUS = "tracing_status";
private static final String PREF_TRACING_CATEGORIES = "tracing_categories";
private static final String PREF_TRACING_MODE = "tracing_mode";
// Ordered map that maps tracing mode string to resource id for its description.
private static final Map<String, Integer> TRACING_MODES = createTracingModesMap();
private Preference mPrefDefaultCategories;
private Preference mPrefNondefaultCategories;
private ListPreference mPrefMode;
private Preference mPrefStartRecording; private Preference mPrefStartRecording;
private Preference mPrefTracingStatus; private Preference mPrefTracingStatus;
/**
* Type of a tracing category indicating whether it is enabled by default or not.
*/
@IntDef({CategoryType.DEFAULT, CategoryType.NON_DEFAULT})
@Retention(RetentionPolicy.SOURCE)
public @interface CategoryType {
int DEFAULT = 0;
int NON_DEFAULT = 1;
}
private static Map<String, Integer> createTracingModesMap() {
Map<String, Integer> map = new LinkedHashMap<>();
map.put("record-until-full", R.string.prefs_tracing_mode_record_until_full);
map.put("record-as-much-as-possible",
R.string.prefs_tracing_mode_record_as_much_as_possible);
map.put("record-continuously", R.string.prefs_tracing_mode_record_continuously);
return map;
}
/**
* @return the current set of all enabled categories, irrespective of their type.
*/
public static Set<String> getEnabledCategories() {
Set<String> enabled =
ContextUtils.getAppSharedPreferences().getStringSet(PREF_TRACING_CATEGORIES, null);
if (enabled == null) {
enabled = new HashSet<>();
// By default, enable all default categories.
for (String category : TracingController.getInstance().getKnownCategories()) {
if (getCategoryType(category) == CategoryType.DEFAULT) enabled.add(category);
}
}
return enabled;
}
/**
* Get the set of enabled categories of a given category type.
*
* @param type the category type.
* @return the current set of enabled categories with |type|.
*/
public static Set<String> getEnabledCategories(@CategoryType int type) {
Set<String> enabled = new HashSet<>();
for (String category : getEnabledCategories()) {
if (type == getCategoryType(category)) {
enabled.add(category);
}
}
return enabled;
}
/**
* Set the enabled categories of a given category type. The set of enabled categories with
* different types will not be changed.
*
* @param type the category type.
* @param enabledOfType the set of enabled categories with the given |type|.
*/
public static void setEnabledCategories(@CategoryType int type, Set<String> enabledOfType) {
Set<String> enabled = new HashSet<>(enabledOfType);
for (String category : getEnabledCategories()) {
if (type != getCategoryType(category)) {
enabled.add(category);
}
}
ContextUtils.getAppSharedPreferences()
.edit()
.putStringSet(PREF_TRACING_CATEGORIES, enabled)
.apply();
}
/**
* Get the type of a category derived from its name.
* @param category the name of the category.
* @return the type of the category.
*/
public static @CategoryType int getCategoryType(String category) {
return category.startsWith(NON_DEFAULT_CATEGORY_PREFIX) ? CategoryType.NON_DEFAULT
: CategoryType.DEFAULT;
}
/**
* @return the current tracing mode stored in the preferences. Either "record-until-full",
* "record-as-much-as-possible", or "record-continuously".
*/
public static String getSelectedTracingMode() {
return ContextUtils.getAppSharedPreferences().getString(
PREF_TRACING_MODE, TRACING_MODES.keySet().iterator().next());
}
/**
* Select and store a new tracing mode in the preferences.
*
* @param tracingMode the new tracing mode, should be either "record-until-full",
* "record-as-much-as-possible", or "record-continuously".
*/
public static void setSelectedTracingMode(String tracingMode) {
assert TRACING_MODES.containsKey(tracingMode);
ContextUtils.getAppSharedPreferences()
.edit()
.putString(PREF_TRACING_MODE, tracingMode)
.apply();
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.prefs_tracing); getActivity().setTitle(R.string.prefs_tracing);
PreferenceUtils.addPreferencesFromResource(this, R.xml.tracing_preferences); PreferenceUtils.addPreferencesFromResource(this, R.xml.tracing_preferences);
mPrefDefaultCategories = findPreference(UI_PREF_DEFAULT_CATEGORIES);
mPrefNondefaultCategories = findPreference(UI_PREF_NON_DEFAULT_CATEGORIES);
mPrefMode = (ListPreference) findPreference(UI_PREF_MODE);
mPrefStartRecording = findPreference(UI_PREF_START_RECORDING); mPrefStartRecording = findPreference(UI_PREF_START_RECORDING);
mPrefTracingStatus = findPreference(UI_PREF_TRACING_STATUS); mPrefTracingStatus = findPreference(UI_PREF_TRACING_STATUS);
mPrefDefaultCategories.getExtras().putInt(
TracingCategoriesPreferences.EXTRA_CATEGORY_TYPE, CategoryType.DEFAULT);
mPrefNondefaultCategories.getExtras().putInt(
TracingCategoriesPreferences.EXTRA_CATEGORY_TYPE, CategoryType.NON_DEFAULT);
mPrefMode.setEntryValues(TRACING_MODES.keySet().toArray(new String[TRACING_MODES.size()]));
String[] descriptions = new String[TRACING_MODES.size()];
int i = 0;
for (int resourceId : TRACING_MODES.values()) {
descriptions[i++] = getActivity().getResources().getString(resourceId);
}
mPrefMode.setEntries(descriptions);
mPrefMode.setOnPreferenceChangeListener((preference, newValue) -> {
setSelectedTracingMode((String) newValue);
updatePreferences();
return true;
});
mPrefStartRecording.setOnPreferenceClickListener(preference -> { mPrefStartRecording.setOnPreferenceClickListener(preference -> {
TracingController.getInstance().startRecording(); TracingController.getInstance().startRecording();
updatePreferences(); updatePreferences();
...@@ -67,8 +220,34 @@ public class TracingPreferences extends PreferenceFragment implements TracingCon ...@@ -67,8 +220,34 @@ public class TracingPreferences extends PreferenceFragment implements TracingCon
boolean idle = state == TracingController.State.IDLE || !initialized; boolean idle = state == TracingController.State.IDLE || !initialized;
boolean notificationsEnabled = TracingNotificationManager.browserNotificationsEnabled(); boolean notificationsEnabled = TracingNotificationManager.browserNotificationsEnabled();
mPrefDefaultCategories.setEnabled(initialized);
mPrefNondefaultCategories.setEnabled(initialized);
mPrefMode.setEnabled(initialized);
mPrefStartRecording.setEnabled(idle && initialized && notificationsEnabled); mPrefStartRecording.setEnabled(idle && initialized && notificationsEnabled);
if (initialized) {
int defaultTotal = 0;
int nondefaultTotal = 0;
for (String category : TracingController.getInstance().getKnownCategories()) {
if (getCategoryType(category) == CategoryType.DEFAULT) {
defaultTotal++;
} else {
nondefaultTotal++;
}
}
int defaultEnabled = getEnabledCategories(CategoryType.DEFAULT).size();
int nondefaultEnabled = getEnabledCategories(CategoryType.NON_DEFAULT).size();
mPrefDefaultCategories.setSummary(getActivity().getResources().getString(
R.string.prefs_tracing_categories_summary, defaultEnabled, defaultTotal));
mPrefNondefaultCategories.setSummary(getActivity().getResources().getString(
R.string.prefs_tracing_categories_summary, nondefaultEnabled, nondefaultTotal));
mPrefMode.setValue(getSelectedTracingMode());
mPrefMode.setSummary(TRACING_MODES.get(getSelectedTracingMode()));
}
if (!notificationsEnabled) { if (!notificationsEnabled) {
mPrefStartRecording.setTitle(R.string.prefs_tracing_start); mPrefStartRecording.setTitle(R.string.prefs_tracing_start);
mPrefTracingStatus.setTitle(R.string.tracing_notifications_disabled); mPrefTracingStatus.setTitle(R.string.tracing_notifications_disabled);
......
...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.tracing; ...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.tracing;
import android.content.Context; import android.content.Context;
import android.support.annotation.IntDef; import android.support.annotation.IntDef;
import android.text.TextUtils;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.base.Log; import org.chromium.base.Log;
...@@ -13,6 +14,7 @@ import org.chromium.base.ObserverList; ...@@ -13,6 +14,7 @@ import org.chromium.base.ObserverList;
import org.chromium.base.VisibleForTesting; import org.chromium.base.VisibleForTesting;
import org.chromium.base.task.AsyncTask; import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.developer.TracingPreferences;
import org.chromium.content_public.browser.TracingControllerAndroid; import org.chromium.content_public.browser.TracingControllerAndroid;
import org.chromium.ui.widget.Toast; import org.chromium.ui.widget.Toast;
...@@ -194,9 +196,9 @@ public class TracingController { ...@@ -194,9 +196,9 @@ public class TracingController {
private void startNativeTrace() { private void startNativeTrace() {
assert mState == State.STARTING; assert mState == State.STARTING;
// TODO(eseckler): Support configuring these. // TODO(eseckler): TracingControllerAndroid currently doesn't support a json trace config.
String categories = "*"; String categories = TextUtils.join(",", TracingPreferences.getEnabledCategories());
String options = "record-until-full"; String options = TracingPreferences.getSelectedTracingMode();
if (!mNativeController.startTracing( if (!mNativeController.startTracing(
mTracingTempFile.getPath(), false, categories, options, true)) { mTracingTempFile.getPath(), false, categories, options, true)) {
......
...@@ -1415,6 +1415,30 @@ Your Google account may have other forms of browsing history like searches and a ...@@ -1415,6 +1415,30 @@ Your Google account may have other forms of browsing history like searches and a
<message name="IDS_PREFS_TRACING_ACTIVE_SUMMARY" translateable="false" desc="The summary of a text preference shown when a Chrome trace is being recorded."> <message name="IDS_PREFS_TRACING_ACTIVE_SUMMARY" translateable="false" desc="The summary of a text preference shown when a Chrome trace is being recorded.">
A trace is being recorded. Use the notification to stop and share the result. A trace is being recorded. Use the notification to stop and share the result.
</message> </message>
<message name="IDS_PREFS_TRACING_DEFAULT_CATEGORIES_TITLE" translateable="false" desc="Title of a preference for selecting the enabled default tracing categories.">
Default categories
</message>
<message name="IDS_PREFS_TRACING_NON_DEFAULT_CATEGORIES_TITLE" translateable="false" desc="Title of a preference for selecting the enabled disabled-by-default tracing categories.">
Disabled-by-default categories
</message>
<message name="IDS_PREFS_TRACING_CATEGORIES_SUMMARY" translateable="false" desc="The summary of a preference for selecting the enabled categories.">
<ph name="NUM_ENABLED_CATEGORIES">%1$d<ex>3</ex></ph> out of <ph name="NUM_TOTAL_CATEGORIES">%2$d<ex>20</ex></ph> enabled
</message>
<message name="IDS_PREFS_TRACING_CATEGORY_SELECTION_TITLE" translateable="false" desc="Title for the trace category selection preferences page. [CHAR-LIMIT=32]">
Select categories
</message>
<message name="IDS_PREFS_TRACING_MODE_TITLE" translateable="false" desc="Title of a preference for changing the tracing mode.">
Tracing mode
</message>
<message name="IDS_PREFS_TRACING_MODE_RECORD_UNTIL_FULL" translateable="false" desc="Title for the tracing mode entry that records data until the buffer is full.">
Record until full
</message>
<message name="IDS_PREFS_TRACING_MODE_RECORD_AS_MUCH_AS_POSSIBLE" translateable="false" desc="Title for the tracing mode entry that records as much data as possible.">
Record until full (large buffer)
</message>
<message name="IDS_PREFS_TRACING_MODE_RECORD_CONTINUOUSLY" translateable="false" desc="Title for the tracing mode entry that records data continuously into a ring buffer.">
Record continuously
</message>
<!-- Tracing notifications (not translated, since part of developer preferences) --> <!-- Tracing notifications (not translated, since part of developer preferences) -->
<message name="IDS_TRACING_NOTIFICATIONS_DISABLED" translateable="false" desc="Message of a toast shown when tracing could not be started because the Chrome app's notifications are disabled."> <message name="IDS_TRACING_NOTIFICATIONS_DISABLED" translateable="false" desc="Message of a toast shown when tracing could not be started because the Chrome app's notifications are disabled.">
......
...@@ -1305,6 +1305,7 @@ chrome_java_sources = [ ...@@ -1305,6 +1305,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java", "java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionStatsPreference.java",
"java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionDataUseItem.java", "java/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionDataUseItem.java",
"java/src/org/chromium/chrome/browser/preferences/developer/DeveloperPreferences.java", "java/src/org/chromium/chrome/browser/preferences/developer/DeveloperPreferences.java",
"java/src/org/chromium/chrome/browser/preferences/developer/TracingCategoriesPreferences.java",
"java/src/org/chromium/chrome/browser/preferences/developer/TracingPreferences.java", "java/src/org/chromium/chrome/browser/preferences/developer/TracingPreferences.java",
"java/src/org/chromium/chrome/browser/preferences/download/DownloadDirectoryAdapter.java", "java/src/org/chromium/chrome/browser/preferences/download/DownloadDirectoryAdapter.java",
"java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreference.java", "java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreference.java",
......
...@@ -8,13 +8,19 @@ import static android.app.Notification.FLAG_ONGOING_EVENT; ...@@ -8,13 +8,19 @@ import static android.app.Notification.FLAG_ONGOING_EVENT;
import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
import android.app.AlertDialog;
import android.app.Notification; import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
import android.util.Pair;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
...@@ -41,12 +47,14 @@ import org.chromium.chrome.browser.tracing.TracingController; ...@@ -41,12 +47,14 @@ import org.chromium.chrome.browser.tracing.TracingController;
import org.chromium.chrome.browser.tracing.TracingNotificationManager; import org.chromium.chrome.browser.tracing.TracingNotificationManager;
import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.util.ActivityUtils;
import org.chromium.chrome.test.util.browser.Features; import org.chromium.chrome.test.util.browser.Features;
import org.chromium.chrome.test.util.browser.notifications.MockNotificationManagerProxy; import org.chromium.chrome.test.util.browser.notifications.MockNotificationManagerProxy;
import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.CriteriaHelper;
import java.io.File; import java.io.File;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
...@@ -100,26 +108,26 @@ public class TracingPreferencesTest { ...@@ -100,26 +108,26 @@ public class TracingPreferencesTest {
}, scaleTimeout(15000) /* maxTimeoutMs */, 50 /* checkIntervalMs */); }, scaleTimeout(15000) /* maxTimeoutMs */, 50 /* checkIntervalMs */);
} }
@Test private void waitForTracingControllerInitialization(PreferenceFragment fragment)
@MediumTest throws Exception {
@Feature({"Preferences"}) final Preference defaultCategoriesPref =
@Features.EnableFeatures(ChromeFeatureList.DEVELOPER_PREFERENCES) fragment.findPreference(TracingPreferences.UI_PREF_DEFAULT_CATEGORIES);
@DisableIf.Build(sdk_is_less_than = 21, message = "crbug.com/899894") final Preference nonDefaultCategoriesPref =
public void testRecordTrace() throws Exception { fragment.findPreference(TracingPreferences.UI_PREF_NON_DEFAULT_CATEGORIES);
Context context = ContextUtils.getApplicationContext(); final Preference modePref = fragment.findPreference(TracingPreferences.UI_PREF_MODE);
mActivityTestRule.startMainActivityOnBlankPage(); final Preference startTracingButton =
Preferences activity = fragment.findPreference(TracingPreferences.UI_PREF_START_RECORDING);
mActivityTestRule.startPreferences(TracingPreferences.class.getName());
final PreferenceFragment fragment = (PreferenceFragment) activity.getFragmentForTest();
final ButtonPreference startTracingButton = (ButtonPreference) fragment.findPreference(
TracingPreferences.UI_PREF_START_RECORDING);
// Wait for TracingController to initialize and button to get enabled.
CallbackHelper callbackHelper = new CallbackHelper(); CallbackHelper callbackHelper = new CallbackHelper();
ThreadUtils.runOnUiThreadBlocking(() -> { ThreadUtils.runOnUiThreadBlocking(() -> {
if (TracingController.getInstance().getState() if (TracingController.getInstance().getState()
== TracingController.State.INITIALIZING) { == TracingController.State.INITIALIZING) {
// Controls should be disabled while initializing.
Assert.assertFalse(defaultCategoriesPref.isEnabled());
Assert.assertFalse(nonDefaultCategoriesPref.isEnabled());
Assert.assertFalse(modePref.isEnabled());
Assert.assertFalse(startTracingButton.isEnabled()); Assert.assertFalse(startTracingButton.isEnabled());
TracingController.getInstance().addObserver(new TracingController.Observer() { TracingController.getInstance().addObserver(new TracingController.Observer() {
@Override @Override
public void onTracingStateChanged(@TracingController.State int state) { public void onTracingStateChanged(@TracingController.State int state) {
...@@ -133,11 +141,29 @@ public class TracingPreferencesTest { ...@@ -133,11 +141,29 @@ public class TracingPreferencesTest {
callbackHelper.notifyCalled(); callbackHelper.notifyCalled();
}); });
callbackHelper.waitForCallback(0 /* currentCallCount */); callbackHelper.waitForCallback(0 /* currentCallCount */);
}
@Test
@MediumTest
@Feature({"Preferences"})
@Features.EnableFeatures(ChromeFeatureList.DEVELOPER_PREFERENCES)
@DisableIf.Build(sdk_is_less_than = 21, message = "crbug.com/899894")
public void testRecordTrace() throws Exception {
Context context = ContextUtils.getApplicationContext();
mActivityTestRule.startMainActivityOnBlankPage();
Preferences activity =
mActivityTestRule.startPreferences(TracingPreferences.class.getName());
final PreferenceFragment fragment = (PreferenceFragment) activity.getFragmentForTest();
final ButtonPreference startTracingButton = (ButtonPreference) fragment.findPreference(
TracingPreferences.UI_PREF_START_RECORDING);
waitForTracingControllerInitialization(fragment);
// Setting to IDLE state tries to dismiss the (non-existent) notification. // Setting to IDLE state tries to dismiss the (non-existent) notification.
waitForNotificationManagerMutation(); waitForNotificationManagerMutation();
Assert.assertEquals(0, mMockNotificationManager.getNotifications().size()); Assert.assertEquals(0, mMockNotificationManager.getNotifications().size());
CallbackHelper callbackHelper = new CallbackHelper();
ThreadUtils.runOnUiThreadBlocking(() -> { ThreadUtils.runOnUiThreadBlocking(() -> {
Assert.assertEquals( Assert.assertEquals(
TracingController.State.IDLE, TracingController.getInstance().getState()); TracingController.State.IDLE, TracingController.getInstance().getState());
...@@ -180,7 +206,7 @@ public class TracingPreferencesTest { ...@@ -180,7 +206,7 @@ public class TracingPreferencesTest {
}); });
// Wait for state change to RECORDING. // Wait for state change to RECORDING.
callbackHelper.waitForCallback(1 /* currentCallCount */); callbackHelper.waitForCallback(0 /* currentCallCount */);
// Recording started, a notification with a stop button should be displayed. // Recording started, a notification with a stop button should be displayed.
Notification notification = waitForNotification().notification; Notification notification = waitForNotification().notification;
...@@ -191,7 +217,7 @@ public class TracingPreferencesTest { ...@@ -191,7 +217,7 @@ public class TracingPreferencesTest {
// Initiate stopping the recording and wait for state changes to STOPPING and STOPPED. // Initiate stopping the recording and wait for state changes to STOPPING and STOPPED.
stopIntent.send(); stopIntent.send();
callbackHelper.waitForCallback(2 /* currentCallCount */, 2 /* numberOfCallsToWaitFor */, callbackHelper.waitForCallback(1 /* currentCallCount */, 2 /* numberOfCallsToWaitFor */,
scaleTimeout(15000) /* timeout */, TimeUnit.MILLISECONDS); scaleTimeout(15000) /* timeout */, TimeUnit.MILLISECONDS);
// Notification should be replaced twice, once with an "is stopping" notification and then // Notification should be replaced twice, once with an "is stopping" notification and then
...@@ -211,7 +237,7 @@ public class TracingPreferencesTest { ...@@ -211,7 +237,7 @@ public class TracingPreferencesTest {
// Discard the trace and wait for state change back to IDLE. // Discard the trace and wait for state change back to IDLE.
deleteIntent.send(); deleteIntent.send();
callbackHelper.waitForCallback(4 /* currentCallCount */); callbackHelper.waitForCallback(3 /* currentCallCount */);
// The temporary file should be deleted. // The temporary file should be deleted.
Assert.assertFalse(tempFile.exists()); Assert.assertFalse(tempFile.exists());
...@@ -238,24 +264,7 @@ public class TracingPreferencesTest { ...@@ -238,24 +264,7 @@ public class TracingPreferencesTest {
(TextMessagePreference) fragment.findPreference( (TextMessagePreference) fragment.findPreference(
TracingPreferences.UI_PREF_TRACING_STATUS); TracingPreferences.UI_PREF_TRACING_STATUS);
// Wait for TracingController to initialize. waitForTracingControllerInitialization(fragment);
CallbackHelper callbackHelper = new CallbackHelper();
ThreadUtils.runOnUiThreadBlocking(() -> {
if (TracingController.getInstance().getState()
== TracingController.State.INITIALIZING) {
Assert.assertFalse(startTracingButton.isEnabled());
TracingController.getInstance().addObserver(new TracingController.Observer() {
@Override
public void onTracingStateChanged(@TracingController.State int state) {
callbackHelper.notifyCalled();
TracingController.getInstance().removeObserver(this);
}
});
return;
}
callbackHelper.notifyCalled();
});
callbackHelper.waitForCallback(0 /* currentCallCount */);
Assert.assertFalse(startTracingButton.isEnabled()); Assert.assertFalse(startTracingButton.isEnabled());
Assert.assertEquals(context.getString(R.string.tracing_notifications_disabled), Assert.assertEquals(context.getString(R.string.tracing_notifications_disabled),
...@@ -263,4 +272,108 @@ public class TracingPreferencesTest { ...@@ -263,4 +272,108 @@ public class TracingPreferencesTest {
mMockNotificationManager.setNotificationsEnabled(true); mMockNotificationManager.setNotificationsEnabled(true);
} }
@Test
@MediumTest
@Feature({"Preferences"})
@Features.EnableFeatures(ChromeFeatureList.DEVELOPER_PREFERENCES)
public void testSelectCategories() throws Exception {
Context context = ContextUtils.getApplicationContext();
// We need a renderer so that its tracing categories will be populated.
mActivityTestRule.startMainActivityOnBlankPage();
Preferences activity =
mActivityTestRule.startPreferences(TracingPreferences.class.getName());
final PreferenceFragment fragment = (PreferenceFragment) activity.getFragmentForTest();
final Preference defaultCategoriesPref =
fragment.findPreference(TracingPreferences.UI_PREF_DEFAULT_CATEGORIES);
final Preference nonDefaultCategoriesPref =
fragment.findPreference(TracingPreferences.UI_PREF_NON_DEFAULT_CATEGORIES);
waitForTracingControllerInitialization(fragment);
ThreadUtils.runOnUiThreadBlocking(() -> {
Assert.assertTrue(defaultCategoriesPref.isEnabled());
Assert.assertTrue(nonDefaultCategoriesPref.isEnabled());
});
// Lists preferences for categories of a specific type and an example category name each.
List<Pair<Preference, String>> categoriesPrefs =
Arrays.asList(new Pair<>(defaultCategoriesPref, "toplevel"),
new Pair<>(nonDefaultCategoriesPref, "disabled-by-default-cc.debug"));
for (Pair<Preference, String> categoriesPrefAndSampleCategory : categoriesPrefs) {
Preference categoriesPref = categoriesPrefAndSampleCategory.first;
String sampleCategoryName = categoriesPrefAndSampleCategory.second;
// Click the preference, which should open a new preferences fragment in a new activity.
Preferences categoriesActivity = ActivityUtils.waitForActivity(
InstrumentationRegistry.getInstrumentation(), Preferences.class, () -> {
ThreadUtils.runOnUiThreadBlocking(() -> {
PreferencesTest.clickPreference(fragment, categoriesPref);
});
});
PreferenceFragment categoriesFragment =
(PreferenceFragment) categoriesActivity.getFragmentForTest();
Assert.assertEquals(TracingCategoriesPreferences.class, categoriesFragment.getClass());
CheckBoxPreference sampleCategoryPref =
(CheckBoxPreference) categoriesFragment.findPreference(sampleCategoryName);
Assert.assertNotNull(sampleCategoryPref);
boolean originallyEnabled =
TracingPreferences.getEnabledCategories().contains(sampleCategoryName);
Assert.assertEquals(originallyEnabled, sampleCategoryPref.isChecked());
// Simulate selecting / deselecting the category.
ThreadUtils.runOnUiThreadBlocking(() -> {
PreferencesTest.clickPreference(categoriesFragment, sampleCategoryPref);
});
Assert.assertNotEquals(originallyEnabled, sampleCategoryPref.isChecked());
boolean finallyEnabled =
TracingPreferences.getEnabledCategories().contains(sampleCategoryName);
Assert.assertNotEquals(originallyEnabled, finallyEnabled);
// Return to original activity.
Preferences originalActivity = ActivityUtils.waitForActivity(
InstrumentationRegistry.getInstrumentation(), Preferences.class, () -> {
ThreadUtils.runOnUiThreadBlocking(() -> { categoriesActivity.finish(); });
});
Assert.assertEquals(activity, originalActivity);
}
}
@Test
@SmallTest
@Feature({"Preferences"})
@Features.EnableFeatures(ChromeFeatureList.DEVELOPER_PREFERENCES)
public void testSelectMode() throws Exception {
Context context = ContextUtils.getApplicationContext();
Preferences activity =
mActivityTestRule.startPreferences(TracingPreferences.class.getName());
final PreferenceFragment fragment = (PreferenceFragment) activity.getFragmentForTest();
final ListPreference modePref =
(ListPreference) fragment.findPreference(TracingPreferences.UI_PREF_MODE);
waitForTracingControllerInitialization(fragment);
ThreadUtils.runOnUiThreadBlocking(() -> {
Assert.assertTrue(modePref.isEnabled());
// By default, the "record-until-full" mode is selected.
Assert.assertEquals("record-until-full", TracingPreferences.getSelectedTracingMode());
// Clicking the pref should open a dialog.
PreferencesTest.clickPreference(fragment, modePref);
Assert.assertNotNull(modePref.getDialog());
AlertDialog dialog = (AlertDialog) modePref.getDialog();
Assert.assertEquals(3, dialog.getListView().getAdapter().getCount());
modePref.getDialog().dismiss();
// Simulate changing the mode.
modePref.getOnPreferenceChangeListener().onPreferenceChange(
modePref, "record-continuously");
Assert.assertEquals("record-continuously", TracingPreferences.getSelectedTracingMode());
});
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment