Commit c68d47f7 authored by gayane's avatar gayane Committed by Commit bot

New UMA settings fragment for Chrome on Android.

This CL is part of new UMA upload logic. The change is for getting more usage data for Chrome users who exclusively use wireless networks. For that, a new binary on/off-switch is added instead of previous three-option model. However, the upload logic is changed on Android to reduce the data usage.

The new binary switch is also connected to a different pref then previous switch. For the beginning the new settings UI would be enabled for users assigned to experimental group.

BUG=455847

Review URL: https://codereview.chromium.org/978623002

Cr-Commit-Position: refs/heads/master@{#321575}
parent ddd5dc25
......@@ -45,6 +45,10 @@
android:key="crash_dump_upload_no_cellular"
android:title="@string/crash_dump_upload_title"
android:defaultValue="false" />
<Preference
android:key="usage_and_crash_reports"
android:title="@string/usage_and_crash_reports_title"
android:fragment="org.chromium.chrome.browser.preferences.privacy.UsageAndCrashReportsPreferenceFragment" />
<Preference
android:fragment="org.chromium.chrome.browser.preferences.privacy.DoNotTrackPreference"
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2015 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. -->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:chrome="http://schemas.android.com/apk/res-auto">
<org.chromium.chrome.browser.preferences.ChromeSwitchPreference
android:key="usage_and_crash_reports_switch"
android:summaryOn="@string/text_on"
android:summaryOff="@string/text_off"/>
<org.chromium.chrome.browser.preferences.TextMessagePreference
android:title="@string/usage_and_crash_reports_description"/>
<org.chromium.chrome.browser.preferences.HyperlinkPreference
android:key="usage_and_crash_reports_learn_more"
android:title="@string/learn_more"
chrome:url="@string/usage_and_crash_reports_learn_more_url"
chrome:imitateWebLink="true" />
</PreferenceScreen>
......@@ -28,7 +28,7 @@ public class FirstRunGlueImpl implements FirstRunGlue {
@Override
public boolean isNeverUploadCrashDump(Context appContext) {
return PrivacyPreferencesManager.getInstance(appContext).isNeverUploadCrashDump();
return !PrivacyPreferencesManager.getInstance(appContext).isUsageAndCrashReportingEnabled();
}
@Override
......@@ -55,4 +55,4 @@ public class FirstRunGlueImpl implements FirstRunGlue {
public void openAccountAdder(Fragment fragment) {
AccountAdder.getInstance().addAccount(fragment, AccountAdder.ADD_ACCOUNT_RESULT);
}
}
\ No newline at end of file
}
......@@ -151,8 +151,8 @@ public class UmaSessionStats implements NetworkChangeNotifier.ConnectionTypeObse
* Updates the state of the MetricsService to account for the user's preferences.
*/
public void updateMetricsServiceState() {
boolean mayRecordStats = !PrivacyPreferencesManager.getInstance(mContext)
.isNeverUploadCrashDump();
boolean mayRecordStats =
PrivacyPreferencesManager.getInstance(mContext).isUsageAndCrashReportingEnabled();
boolean mayUploadStats = mReportingPermissionManager.isUploadPermitted();
// Re-start the MetricsService with the given parameters.
......
......@@ -12,6 +12,7 @@ import android.util.Log;
import org.chromium.base.CalledByNative;
import org.chromium.base.ThreadUtils;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.ContentSetting;
import org.chromium.chrome.browser.preferences.website.JavaScriptExceptionInfo;
import org.chromium.chrome.browser.preferences.website.PopupExceptionInfo;
......@@ -25,8 +26,7 @@ import java.util.List;
* preferences should be grouped with their relevant functionality but this is a grab-bag for other
* preferences.
*/
public final class PrefServiceBridge {
public class PrefServiceBridge {
// Does not need sync with native; used for the popup settings check
public static final String EXCEPTION_SETTING_ALLOW = "allow";
public static final String EXCEPTION_SETTING_BLOCK = "block";
......@@ -104,7 +104,15 @@ public final class PrefServiceBridge {
}
private PrefServiceBridge() {
TemplateUrlService.getInstance().load();
this(true);
}
/**
* Constructor used for mock PrefServiceBridge without accessing TemplateUrlService.
*/
@VisibleForTesting
protected PrefServiceBridge(boolean loadTemplateUrlService) {
if (loadTemplateUrlService) TemplateUrlService.getInstance().load();
}
private static PrefServiceBridge sInstance;
......@@ -118,6 +126,23 @@ public final class PrefServiceBridge {
return sInstance;
}
/**
* @return The singleton preferences object without initiating it even if it is null.
*/
@VisibleForTesting
public static PrefServiceBridge getInstanceForTesting() {
return sInstance;
}
/**
* Sets the PrefServiceBridge instance with the passed instance. Used in
* testing to reset the instance to its previous value.
*/
@VisibleForTesting
public static void setInstanceForTesting(PrefServiceBridge instance) {
sInstance = instance;
}
/**
* @return Whether the preferences have been initialized.
*/
......@@ -780,6 +805,30 @@ public final class PrefServiceBridge {
return nativeGetSupervisedUserSecondCustodianProfileImageURL();
}
/**
* @return whether Metrics reporting is enabled.
*/
@VisibleForTesting
public boolean isMetricsReportingEnabled() {
return nativeGetMetricsReportingEnabled();
}
/**
* Sets whether the metrics reporting should be enabled.
*/
@VisibleForTesting
public void setMetricsReportingEnabled(boolean enabled) {
nativeSetMetricsReportingEnabled(enabled);
}
/**
* @return whether the metrics reporting preference has been set by user.
*/
@VisibleForTesting
public boolean hasSetMetricsReporting() {
return nativeHasSetMetricsReporting();
}
private native boolean nativeGetAcceptCookiesEnabled();
private native boolean nativeGetAcceptCookiesManaged();
private native boolean nativeGetBlockThirdPartyCookiesEnabled();
......@@ -864,4 +913,7 @@ public final class PrefServiceBridge {
private native String nativeGetSupervisedUserSecondCustodianName();
private native String nativeGetSupervisedUserSecondCustodianEmail();
private native String nativeGetSupervisedUserSecondCustodianProfileImageURL();
private native boolean nativeGetMetricsReportingEnabled();
private native void nativeSetMetricsReportingEnabled(boolean enabled);
private native boolean nativeHasSetMetricsReporting();
}
......@@ -10,6 +10,7 @@ import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
......@@ -46,6 +47,7 @@ public class PrivacyPreferences extends PreferenceFragment
"crash_dump_upload_no_cellular";
private static final String PREF_DO_NOT_TRACK = "do_not_track";
private static final String PREF_CLEAR_BROWSING_DATA = "clear_browsing_data";
private static final String PREF_USAGE_AND_CRASH_REPORTING = "usage_and_crash_reports";
private ClearBrowsingDataDialogFragment mClearBrowsingDataDialogFragment;
private ManagedPreferenceDelegate mManagedPreferenceDelegate;
......@@ -53,12 +55,16 @@ public class PrivacyPreferences extends PreferenceFragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PrivacyPreferencesManager.getInstance(getActivity()).migrateNetworkPredictionPreferences();
PrivacyPreferencesManager privacyPrefManager =
PrivacyPreferencesManager.getInstance(getActivity());
privacyPrefManager.migrateNetworkPredictionPreferences();
addPreferencesFromResource(R.xml.privacy_preferences);
getActivity().setTitle(R.string.prefs_privacy);
setHasOptionsMenu(true);
mManagedPreferenceDelegate = createManagedPreferenceDelegate();
PreferenceScreen preferenceScreen = getPreferenceScreen();
NetworkPredictionPreference networkPredictionPref =
(NetworkPredictionPreference) findPreference(PREF_NETWORK_PREDICTIONS);
......@@ -67,15 +73,14 @@ public class PrivacyPreferences extends PreferenceFragment
NetworkPredictionOptions networkPredictionOptions = PrefServiceBridge.getInstance()
.getNetworkPredictionOptions();
boolean isMobileNetworkCapable =
PrivacyPreferencesManager.getInstance(getActivity()).isMobileNetworkCapable();
boolean isMobileNetworkCapable = privacyPrefManager.isMobileNetworkCapable();
if (isMobileNetworkCapable) {
getPreferenceScreen().removePreference(networkPredictionNoCellularPref);
preferenceScreen.removePreference(networkPredictionNoCellularPref);
networkPredictionPref.setValue(networkPredictionOptions.enumToString());
networkPredictionPref.setOnPreferenceChangeListener(this);
networkPredictionPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
} else {
getPreferenceScreen().removePreference(networkPredictionPref);
preferenceScreen.removePreference(networkPredictionPref);
networkPredictionNoCellularPref.setChecked(
networkPredictionOptions != NetworkPredictionOptions.NETWORK_PREDICTION_NEVER);
networkPredictionNoCellularPref.setOnPreferenceChangeListener(this);
......@@ -87,15 +92,21 @@ public class PrivacyPreferences extends PreferenceFragment
(CrashDumpUploadPreference) findPreference(PREF_CRASH_DUMP_UPLOAD);
ChromeBaseCheckBoxPreference uploadCrashDumpNoCellularPref =
(ChromeBaseCheckBoxPreference) findPreference(PREF_CRASH_DUMP_UPLOAD_NO_CELLULAR);
if (isMobileNetworkCapable) {
getPreferenceScreen().removePreference(uploadCrashDumpNoCellularPref);
uploadCrashDumpPref.setOnPreferenceChangeListener(this);
uploadCrashDumpPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
if (privacyPrefManager.isCellularUploadingEnabled()) {
preferenceScreen.removePreference(uploadCrashDumpNoCellularPref);
preferenceScreen.removePreference(uploadCrashDumpPref);
} else {
getPreferenceScreen().removePreference(uploadCrashDumpPref);
uploadCrashDumpNoCellularPref.setOnPreferenceChangeListener(this);
uploadCrashDumpNoCellularPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
preferenceScreen.removePreference(findPreference(PREF_USAGE_AND_CRASH_REPORTING));
if (isMobileNetworkCapable) {
preferenceScreen.removePreference(uploadCrashDumpNoCellularPref);
uploadCrashDumpPref.setOnPreferenceChangeListener(this);
uploadCrashDumpPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
} else {
preferenceScreen.removePreference(uploadCrashDumpPref);
uploadCrashDumpNoCellularPref.setOnPreferenceChangeListener(this);
uploadCrashDumpNoCellularPref.setManagedPreferenceDelegate(
mManagedPreferenceDelegate);
}
}
ChromeBaseCheckBoxPreference navigationErrorPref =
......@@ -109,7 +120,7 @@ public class PrivacyPreferences extends PreferenceFragment
searchSuggestionsPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
if (!((Preferences) getActivity()).isContextualSearchEnabled()) {
getPreferenceScreen().removePreference(findPreference(PREF_CONTEXTUAL_SEARCH));
preferenceScreen.removePreference(findPreference(PREF_CONTEXTUAL_SEARCH));
}
ButtonPreference clearBrowsingData =
......@@ -204,6 +215,17 @@ public class PrivacyPreferences extends PreferenceFragment
contextualPref.setSummary(getActivity().getResources().getText(R.string.text_on));
}
}
Preference usageAndCrashReportingPref = findPreference(PREF_USAGE_AND_CRASH_REPORTING);
if (usageAndCrashReportingPref != null) {
if (PrivacyPreferencesManager.getInstance(getActivity())
.isUsageAndCrashReportingEnabled()) {
usageAndCrashReportingPref.setSummary(
getActivity().getResources().getText(R.string.text_on));
} else {
usageAndCrashReportingPref.setSummary(
getActivity().getResources().getText(R.string.text_off));
}
}
}
private ManagedPreferenceDelegate createManagedPreferenceDelegate() {
......
......@@ -11,6 +11,7 @@ import android.net.NetworkInfo;
import android.preference.PreferenceManager;
import org.chromium.base.CommandLine;
import org.chromium.base.FieldTrialList;
import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.ChromeSwitches;
import org.chromium.chrome.R;
......@@ -41,6 +42,10 @@ public class PrivacyPreferencesManager implements CrashReportingPermissionManage
private final String mCrashDumpWifiOnlyUpload;
private final String mCrashDumpAlwaysUpload;
// Using Boolean class type here for distinguishing set and unset modes. Helps to for testing
// and also for querying user experiments once.
private Boolean mIsCellularUploadingEnabled;
@VisibleForTesting
PrivacyPreferencesManager(Context context) {
mContext = context;
......@@ -51,6 +56,14 @@ public class PrivacyPreferencesManager implements CrashReportingPermissionManage
mCrashDumpAlwaysUpload = context.getString(R.string.crash_dump_always_upload_value);
}
/*
* Sets whether cellular experiment is enabled or not. Used for testing.
*/
@VisibleForTesting
public void setCellularExperimentForTesting(boolean isCellularUploadingEnabled) {
mIsCellularUploadingEnabled = Boolean.valueOf(isCellularUploadingEnabled);
}
public static PrivacyPreferencesManager getInstance(Context context) {
if (sInstance == null) {
sInstance = new PrivacyPreferencesManager(context);
......@@ -207,17 +220,75 @@ public class PrivacyPreferencesManager implements CrashReportingPermissionManage
* Check whether to allow uploading crash dump. The option should be either
* "always upload", or "wifi only" with current connection being wifi/ethernet.
*
* @return boolean to whether to allow uploading crash dump.
* @return boolean whether to allow uploading crash dump.
*/
private boolean allowUploadCrashDump() {
if (!isMobileNetworkCapable()) {
return mSharedPreferences.getBoolean(PREF_CRASH_DUMP_UPLOAD_NO_CELLULAR, false);
} else {
PrefServiceBridge prefServiceBridge = PrefServiceBridge.getInstance();
if (isCellularUploadingEnabled() && prefServiceBridge.hasSetMetricsReporting()) {
return prefServiceBridge.isMetricsReportingEnabled();
}
if (isMobileNetworkCapable()) {
String option =
mSharedPreferences.getString(PREF_CRASH_DUMP_UPLOAD, mCrashDumpNeverUpload);
return option.equals(mCrashDumpAlwaysUpload)
|| (option.equals(mCrashDumpWifiOnlyUpload) && isWiFiOrEthernetNetwork());
}
return mSharedPreferences.getBoolean(PREF_CRASH_DUMP_UPLOAD_NO_CELLULAR, false);
}
/**
* Checks whether uploads are allowed by new preference or old preference
* based on the experiment assigned to the user. Also sets the new pref if it
* needs to be set.
*
* @return boolean whether uploads are allowed at all or not.
*/
public boolean isUsageAndCrashReportingEnabled() {
boolean isCellularEnabledByExperiment = isCellularUploadingEnabled();
PrefServiceBridge prefServiceBridge = PrefServiceBridge.getInstance();
if (isCellularEnabledByExperiment && prefServiceBridge.hasSetMetricsReporting()) {
return prefServiceBridge.isMetricsReportingEnabled();
}
boolean isEnabled = isUploadCrashDumpEnabled();
if (isCellularEnabledByExperiment && !prefServiceBridge.hasSetMetricsReporting()) {
prefServiceBridge.setMetricsReportingEnabled(isEnabled);
}
return isEnabled;
}
/**
* Checks whether old Crash_dump_upload pref allows any (e.g. always on or
* only wifi) uploads or not.
*
* @return boolean whether uploads are enabled by old pref.
*/
public boolean isUploadCrashDumpEnabled() {
if (isMobileNetworkCapable()) {
String option =
mSharedPreferences.getString(PREF_CRASH_DUMP_UPLOAD, mCrashDumpNeverUpload);
if (option.equals(mCrashDumpNeverUpload)) return false;
return true;
}
return mSharedPreferences.getBoolean(PREF_CRASH_DUMP_UPLOAD_NO_CELLULAR, false);
}
/**
* Checks whether user is assigned to experimental group for enabling new cellular uploads
* functionality or returns the value explicitly set by tests.
*
* @return boolean whether user is assigned to experimental group.
*/
public boolean isCellularUploadingEnabled() {
if (mIsCellularUploadingEnabled == null) {
String group_name = FieldTrialList.findFullName("UMA_EnableCellularLogUpload");
mIsCellularUploadingEnabled = Boolean.valueOf(group_name.equals("Enabled"));
}
return mIsCellularUploadingEnabled;
}
/**
......@@ -241,22 +312,6 @@ public class PrivacyPreferencesManager implements CrashReportingPermissionManage
mCrashUploadingEnabled = false;
}
/**
* Check whether crash dump upload preference is set to NEVER only.
*
* @return boolean {@code true} if the option is set to NEVER
*/
public boolean isNeverUploadCrashDump() {
boolean option;
if (isMobileNetworkCapable()) {
option = mSharedPreferences.getString(PREF_CRASH_DUMP_UPLOAD, mCrashDumpNeverUpload)
.equals(mCrashDumpNeverUpload);
} else {
option = !mSharedPreferences.getBoolean(PREF_CRASH_DUMP_UPLOAD_NO_CELLULAR, false);
}
return option;
}
/**
* Sets the initial value for whether crash stacks may be uploaded.
* This should be called only once, the first time Chrome is launched.
......
// Copyright 2015 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.privacy;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceFragment;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.ChromeSwitchPreference;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
/**
* Fragment to manage the Usage and crash reports preference and to explain to
* the user what it does.
*/
public class UsageAndCrashReportsPreferenceFragment extends PreferenceFragment {
private static final String PREF_USAGE_AND_CRASH_REPORTS_SWITCH =
"usage_and_crash_reports_switch";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.usage_and_crash_reports_preferences);
getActivity().setTitle(R.string.usage_and_crash_reports_title);
initUsageAndCrashReportsSwitch();
}
private void initUsageAndCrashReportsSwitch() {
ChromeSwitchPreference usageAndCrashReportsSwitch =
(ChromeSwitchPreference) findPreference(PREF_USAGE_AND_CRASH_REPORTS_SWITCH);
boolean isEnabled = PrivacyPreferencesManager.getInstance(getActivity())
.isUsageAndCrashReportingEnabled();
usageAndCrashReportsSwitch.setChecked(isEnabled);
usageAndCrashReportsSwitch.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean isEnabled = (boolean) newValue;
PrefServiceBridge.getInstance().setMetricsReportingEnabled(isEnabled);
PrivacyPreferencesManager.getInstance(getActivity())
.initCrashUploadPreference(isEnabled);
return true;
}
});
}
}
......@@ -366,6 +366,17 @@ For example, some websites may respond to this request by showing you ads that a
<message name="IDS_CAN_NOT_CLEAR_BROWSING_HISTORY_TOAST" desc="Message on the toast explaining that child account users can not clear their browsing history.">
Browsing history can't be cleared with accounts for kids
</message>
<message name="IDS_USAGE_AND_CRASH_REPORTS_TITLE" desc="Title for 'Usage and crash reports' preference">
Usage and crash reports
</message>
<message name="IDS_USAGE_AND_CRASH_REPORTS_DESCRIPTION" desc="Description for 'Usage and crash reports' preference">
Help us prioritize the features and improvements we should work on by sending Google information about the files, applications, and services running whenever you experience a crash.
Usage statistics include information such as preferences, button clicks, and memory usage. They do not include webpage URLs or any personal information. Crash reports contain system information at the time of the crash, and may contain web page URLs or personal information, depending on what was happening at the time of the crash.
</message>
<message name="IDS_USAGE_AND_CRASH_REPORTS_LEARN_MORE_URL" desc="URL for learning more about 'Usage and crash reports' preference" translateable="false">
https://support.google.com/chrome/answer/96817
</message>
<!-- Accessibility preferences -->
<message name="IDS_PREFS_ACCESSIBILITY" desc="Title of Accessibility settings, which allows the user to change webpage font sizes. [CHAR-LIMIT=32]">
......@@ -1434,7 +1445,7 @@ Drag from top to exit.
<message name="IDS_ACCESSIBILITY_FRE_ACCOUNT_SPINNER" desc="Content description for the first run account drop down spinner.">
Choose account
</message>
<!-- External Navigation Strings -->
<message name="IDS_EXTERNAL_APP_LEAVE_INCOGNITO_WARNING" desc="Alert dialog text warning that user that incognito mode does not continue into external apps.">
Leaving incognito mode if this link is opened in an external application. Continue?
......
......@@ -305,6 +305,23 @@ static jboolean GetIncognitoModeManaged(JNIEnv* env, jobject obj) {
prefs::kIncognitoModeAvailability);
}
static jboolean GetMetricsReportingEnabled(JNIEnv* env, jobject obj) {
PrefService* local_state = g_browser_process->local_state();
return local_state->GetBoolean(prefs::kMetricsReportingEnabled);
}
static void SetMetricsReportingEnabled(JNIEnv* env,
jobject obj,
jboolean enabled) {
PrefService* local_state = g_browser_process->local_state();
local_state->SetBoolean(prefs::kMetricsReportingEnabled, enabled);
}
static jboolean HasSetMetricsReporting(JNIEnv* env, jobject obj) {
PrefService* local_state = g_browser_process->local_state();
return local_state->HasPrefPath(prefs::kMetricsReportingEnabled);
}
namespace {
// Redirects a BrowsingDataRemover completion callback back into 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