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 @@
found in the LICENSE file. -->
<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
android:key="start_recording"/>
<org.chromium.chrome.browser.preferences.TextMessagePreference
......
......@@ -28,8 +28,7 @@ public class AndroidPaymentAppsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceUtils.addPreferencesFromResource(
this, R.xml.autofill_and_payments_preference_fragment_screen);
PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen);
getActivity().setTitle(R.string.payment_apps_title);
}
......
......@@ -35,8 +35,7 @@ public class AutofillPaymentMethodsFragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceUtils.addPreferencesFromResource(
this, R.xml.autofill_and_payments_preference_fragment_screen);
PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen);
getActivity().setTitle(R.string.autofill_payment_methods);
}
......
......@@ -34,8 +34,7 @@ public class AutofillProfilesFragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceUtils.addPreferencesFromResource(
this, R.xml.autofill_and_payments_preference_fragment_screen);
PreferenceUtils.addPreferencesFromResource(this, R.xml.blank_preference_fragment_screen);
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 @@
package org.chromium.chrome.browser.preferences.developer;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.support.annotation.IntDef;
import org.chromium.base.ContextUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.PreferenceUtils;
import org.chromium.chrome.browser.tracing.TracingController;
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.
*/
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
static final String UI_PREF_START_RECORDING = "start_recording";
@VisibleForTesting
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 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
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.prefs_tracing);
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);
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 -> {
TracingController.getInstance().startRecording();
updatePreferences();
......@@ -67,8 +220,34 @@ public class TracingPreferences extends PreferenceFragment implements TracingCon
boolean idle = state == TracingController.State.IDLE || !initialized;
boolean notificationsEnabled = TracingNotificationManager.browserNotificationsEnabled();
mPrefDefaultCategories.setEnabled(initialized);
mPrefNondefaultCategories.setEnabled(initialized);
mPrefMode.setEnabled(initialized);
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) {
mPrefStartRecording.setTitle(R.string.prefs_tracing_start);
mPrefTracingStatus.setTitle(R.string.tracing_notifications_disabled);
......
......@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.tracing;
import android.content.Context;
import android.support.annotation.IntDef;
import android.text.TextUtils;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
......@@ -13,6 +14,7 @@ import org.chromium.base.ObserverList;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.developer.TracingPreferences;
import org.chromium.content_public.browser.TracingControllerAndroid;
import org.chromium.ui.widget.Toast;
......@@ -194,9 +196,9 @@ public class TracingController {
private void startNativeTrace() {
assert mState == State.STARTING;
// TODO(eseckler): Support configuring these.
String categories = "*";
String options = "record-until-full";
// TODO(eseckler): TracingControllerAndroid currently doesn't support a json trace config.
String categories = TextUtils.join(",", TracingPreferences.getEnabledCategories());
String options = TracingPreferences.getSelectedTracingMode();
if (!mNativeController.startTracing(
mTracingTempFile.getPath(), false, categories, options, true)) {
......
......@@ -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.">
A trace is being recorded. Use the notification to stop and share the result.
</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) -->
<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 = [
"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/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/download/DownloadDirectoryAdapter.java",
"java/src/org/chromium/chrome/browser/preferences/download/DownloadLocationPreference.java",
......
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