Commit d700c0f0 authored by newt's avatar newt Committed by Commit bot

Upstream privacy settings.

This upstreams the privacy screen in settings, which includes navigation
error suggestions, omnibox suggestions, prefetching, crash report
uploading, do not track, and clearing data.

BUG=428869

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

Cr-Commit-Position: refs/heads/master@{#317086}
parent e270ad29
<?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. -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="start|bottom"
style="@style/AlertDialogContent">
<org.chromium.ui.widget.TextViewWithClickableSpans
android:id="@+id/summary"
android:bufferType="spannable"
style="@style/AlertDialogSummaryViewItem" />
</LinearLayout>
...@@ -85,6 +85,7 @@ ...@@ -85,6 +85,7 @@
<item name="colorAccent">@color/pref_accent_color</item> <item name="colorAccent">@color/pref_accent_color</item>
</style> </style>
<!-- Alert dialogs -->
<style name="AlertDialogContent"> <style name="AlertDialogContent">
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
...@@ -100,6 +101,13 @@ ...@@ -100,6 +101,13 @@
<item name="android:singleLine">true</item> <item name="android:singleLine">true</item>
<item name="android:paddingTop">10dp</item> <item name="android:paddingTop">10dp</item>
</style> </style>
<style name="AlertDialogSummaryViewItem" parent="@android:style/TextAppearance.Small">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textAlignment">viewStart</item>
<item name="android:paddingTop">10dp</item>
</style>
<style name="BoldTextFieldLabel" parent="@android:style/TextAppearance.Medium"> <style name="BoldTextFieldLabel" parent="@android:style/TextAppearance.Medium">
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
......
...@@ -10,8 +10,33 @@ ...@@ -10,8 +10,33 @@
<item>@string/serif</item> <item>@string/serif</item>
<item>@string/monospace</item> <item>@string/monospace</item>
</string-array> </string-array>
<!-- Site settings -->
<string-array name="website_settings_permission_options"> <string-array name="website_settings_permission_options">
<item>@string/website_settings_permissions_allow</item> <item>@string/website_settings_permissions_allow</item>
<item>@string/website_settings_permissions_block</item> <item>@string/website_settings_permissions_block</item>
</string-array> </string-array>
<!-- Privacy preferences -->
<string-array name="bandwidth_entries">
<item>@string/always_prefetch_bandwidth_entry</item>
<item>@string/wifi_prefetch_bandwidth_entry</item>
<item>@string/never_prefetch_bandwidth_entry</item>
</string-array>
<string-array name="bandwidth_entry_values">
<item>@string/network_prediction_always_value</item>
<item>@string/network_prediction_wifi_only_value</item>
<item>@string/network_prediction_never_value</item>
</string-array>
<string-array name="crash_upload_entries">
<item>@string/crash_dump_always_upload</item>
<item>@string/crash_dump_only_with_wifi</item>
<item>@string/crash_dump_never_upload</item>
</string-array>
<string-array name="crash_upload_values">
<item>@string/crash_dump_always_upload_value</item>
<item>@string/crash_dump_only_with_wifi_value</item>
<item>@string/crash_dump_never_upload_value</item>
</string-array>
</resources> </resources>
...@@ -35,5 +35,7 @@ ...@@ -35,5 +35,7 @@
<!-- Menu items IDs in Settings --> <!-- Menu items IDs in Settings -->
<item type="id" name="menu_id_translate_help" /> <item type="id" name="menu_id_translate_help" />
<item type="id" name="menu_id_help_privacy" />
<item type="id" name="menu_id_contextual_search_learn" />
</resources> </resources>
<?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" >
<org.chromium.chrome.browser.preferences.ChromeSwitchPreference
android:key="contextual_search_switch"
android:summaryOn="@string/text_on"
android:summaryOff="@string/text_off" />
<org.chromium.chrome.browser.preferences.TextMessagePreference
android:title="@string/contextual_search_description" />
</PreferenceScreen>
<?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="do_not_track_switch"
android:summaryOn="@string/text_on"
android:summaryOff="@string/text_off" />
<org.chromium.chrome.browser.preferences.TextMessagePreference
android:title="@string/do_not_track_description" />
<org.chromium.chrome.browser.preferences.HyperlinkPreference
android:key="do_not_track_learn_more"
android:title="@string/learn_more"
chrome:url="@string/do_not_track_learn_more_url"
chrome:imitateWebLink="true" />
</PreferenceScreen>
\ No newline at end of file
<?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">
<org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
android:key="navigation_error"
android:title="@string/navigation_error_title"
android:summary="@string/navigation_error_summary"
android:defaultValue="true" />
<org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
android:key="search_suggestions"
android:title="@string/search_suggestions_title"
android:summary="@string/search_suggestions_summary"
android:defaultValue="true" />
<Preference
android:key="contextual_search"
android:title="@string/contextual_search_title"
android:fragment="org.chromium.chrome.browser.preferences.privacy.ContextualSearchPreferenceFragment" />
<!-- Only one of these network prediction preferences will be shown, depending on whether
the device has cellular support. -->
<org.chromium.chrome.browser.preferences.privacy.NetworkPredictionPreference
android:key="network_predictions"
android:title="@string/network_predictions_title"
android:entries="@array/bandwidth_entries"
android:entryValues="@array/bandwidth_entry_values"
android:defaultValue="@string/network_prediction_wifi_only_value" />
<org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
android:key="network_predictions_no_cellular"
android:title="@string/network_predictions_title"
android:summary="@string/network_predictions_summary"
android:defaultValue="true" />
<!-- Only one of these "Usage and crash reports" preferences will be shown, depending on whether
the device has cellular support. -->
<org.chromium.chrome.browser.preferences.privacy.CrashDumpUploadPreference
android:key="crash_dump_upload"
android:title="@string/crash_dump_upload_title"
android:entries="@array/crash_upload_entries"
android:entryValues="@array/crash_upload_values"
android:defaultValue="@string/crash_dump_never_upload_value" />
<org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference
android:key="crash_dump_upload_no_cellular"
android:title="@string/crash_dump_upload_title"
android:defaultValue="false" />
<Preference
android:fragment="org.chromium.chrome.browser.preferences.privacy.DoNotTrackPreference"
android:key="do_not_track"
android:title="@string/do_not_track_title" />
<org.chromium.chrome.browser.preferences.ButtonPreference
android:key="clear_browsing_data"
android:title="@string/clear_browsing_data_title" />
</PreferenceScreen>
...@@ -6,17 +6,23 @@ package org.chromium.chrome.browser; ...@@ -6,17 +6,23 @@ package org.chromium.chrome.browser;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import org.chromium.base.CalledByNative; import org.chromium.base.CalledByNative;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
import org.chromium.base.library_loader.LibraryProcessType;; import org.chromium.base.library_loader.LibraryProcessType;;
import org.chromium.base.library_loader.ProcessInitException; import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations;
import org.chromium.chrome.browser.preferences.LocationSettings; import org.chromium.chrome.browser.preferences.LocationSettings;
import org.chromium.chrome.browser.preferences.Preferences;
import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.preferences.PreferencesLauncher;
import org.chromium.chrome.browser.preferences.ProtectedContentPreferences; import org.chromium.chrome.browser.preferences.ProtectedContentPreferences;
import org.chromium.chrome.browser.preferences.autofill.AutofillPreferences; import org.chromium.chrome.browser.preferences.autofill.AutofillPreferences;
import org.chromium.chrome.browser.preferences.password.ManageSavedPasswordsPreferences; import org.chromium.chrome.browser.preferences.password.ManageSavedPasswordsPreferences;
import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferences;
import org.chromium.content.app.ContentApplication; import org.chromium.content.app.ContentApplication;
import org.chromium.content.browser.BrowserStartupController; import org.chromium.content.browser.BrowserStartupController;
...@@ -26,6 +32,8 @@ import org.chromium.content.browser.BrowserStartupController; ...@@ -26,6 +32,8 @@ import org.chromium.content.browser.BrowserStartupController;
*/ */
public abstract class ChromiumApplication extends ContentApplication { public abstract class ChromiumApplication extends ContentApplication {
private static final String TAG = "ChromiumApplication";
/** /**
* Returns whether the Activity is being shown in multi-window mode. * Returns whether the Activity is being shown in multi-window mode.
*/ */
...@@ -96,14 +104,29 @@ public abstract class ChromiumApplication extends ContentApplication { ...@@ -96,14 +104,29 @@ public abstract class ChromiumApplication extends ContentApplication {
* @param tab The tab that triggered the request. * @param tab The tab that triggered the request.
*/ */
@CalledByNative @CalledByNative
protected void openClearBrowsingData(Tab tab) {} protected void openClearBrowsingData(Tab tab) {
Activity activity = tab.getWindowAndroid().getActivity().get();
if (activity == null) {
Log.e(TAG,
"Attempting to open clear browsing data for a tab without a valid activity");
return;
}
Intent intent = PreferencesLauncher.createIntentForSettingsPage(activity,
PrivacyPreferences.class.getName());
Bundle arguments = new Bundle();
arguments.putBoolean(PrivacyPreferences.SHOW_CLEAR_BROWSING_DATA_EXTRA, true);
intent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, arguments);
activity.startActivity(intent);
}
/** /**
* @return Whether parental controls are enabled. Returning true will disable * @return Whether parental controls are enabled. Returning true will disable
* incognito mode. * incognito mode.
*/ */
@CalledByNative @CalledByNative
protected abstract boolean areParentalControlsEnabled(); protected boolean areParentalControlsEnabled() {
return PartnerBrowserCustomizations.isIncognitoDisabled();
}
// TODO(yfriedman): This is too widely available. Plumb this through ChromeNetworkDelegate // TODO(yfriedman): This is too widely available. Plumb this through ChromeNetworkDelegate
// instead. // instead.
......
...@@ -70,6 +70,8 @@ public abstract class Preferences extends ActionBarActivity implements ...@@ -70,6 +70,8 @@ public abstract class Preferences extends ActionBarActivity implements
* Opens a URL in a new activity. * Opens a URL in a new activity.
* @param titleResId The resource ID of the title to show above the web page. * @param titleResId The resource ID of the title to show above the web page.
* @param urlResId The resource ID of the URL to load. * @param urlResId The resource ID of the URL to load.
*
* TODO(newt): remove this method when EmbedContentViewActivity is upstreamed.
*/ */
public abstract void showUrl(int titleResId, int urlResId); public abstract void showUrl(int titleResId, int urlResId);
...@@ -78,6 +80,35 @@ public abstract class Preferences extends ActionBarActivity implements ...@@ -78,6 +80,35 @@ public abstract class Preferences extends ActionBarActivity implements
*/ */
public void showGoogleTranslateHelp() {} public void showGoogleTranslateHelp() {}
/**
* Launches the help page for privacy settings.
*/
public void showPrivacyPreferencesHelp() {}
/**
* Called when user changes the contextual search preference.
* @param newValue Whether contextual search is now enabled.
*
* TODO(newt): remove this method when contextual search is upstreamed.
*/
public void logContextualSearchToggled(boolean newValue) {}
/**
* Returns whether contextual search is enabled.
*
* TODO(newt): remove this method when contextual search is upstreamed.
*/
public boolean isContextualSearchEnabled() {
return false;
}
/**
* Notifies the precache launcher that the user has changed the network prediction preference.
*
* TODO(newt): remove this method when precache logic is upstreamed.
*/
public void updatePrecachingEnabled() {}
@SuppressFBWarnings("DM_EXIT") @SuppressFBWarnings("DM_EXIT")
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")
@Override @Override
......
// 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.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.preferences.Preferences;
import org.chromium.chrome.browser.signin.AccountManagementFragment;
import org.chromium.sync.signin.ChromeSigninController;
import org.chromium.ui.text.SpanApplier;
import java.util.Arrays;
import java.util.EnumSet;
/**
* Modal dialog with options for selection the type of browsing data
* to clear (history, cookies), triggered from a preference.
*/
public class ClearBrowsingDataDialogFragment extends DialogFragment implements
PrefServiceBridge.OnClearBrowsingDataListener,
DialogInterface.OnMultiChoiceClickListener, DialogInterface.OnClickListener {
/** The tag used when showing the clear browsing fragment. */
public static final String FRAGMENT_TAG = "ClearBrowsingDataDialogFragment";
/**
* Enum for Dialog options to be displayed in the dialog.
*/
public enum DialogOption {
CLEAR_HISTORY(R.string.clear_history_title),
CLEAR_CACHE(R.string.clear_cache_title),
CLEAR_COOKIES_AND_SITE_DATA(R.string.clear_cookies_and_site_data_title),
CLEAR_PASSWORDS(R.string.clear_passwords_title),
CLEAR_FORM_DATA(R.string.clear_formdata_title),
// Clear bookmarks is only used by ClearSyncData dialog.
CLEAR_BOOKMARKS_DATA(R.string.clear_bookmarks_title);
private final int mResourceId;
private DialogOption(int resourceId) {
mResourceId = resourceId;
}
/**
* @return resource id of the Dialog option.
*/
public int getResourceId() {
return mResourceId;
}
}
private EnumSet<DialogOption> mSelectedOptions;
private DialogOption[] mOptions;
private AlertDialog mDialog;
private ProgressDialog mProgressDialog;
protected final void clearBrowsingData(EnumSet<DialogOption> selectedOptions) {
PrefServiceBridge.getInstance().clearBrowsingData(this,
selectedOptions.contains(DialogOption.CLEAR_HISTORY),
selectedOptions.contains(DialogOption.CLEAR_CACHE),
selectedOptions.contains(DialogOption.CLEAR_COOKIES_AND_SITE_DATA),
selectedOptions.contains(DialogOption.CLEAR_PASSWORDS),
selectedOptions.contains(DialogOption.CLEAR_FORM_DATA));
}
protected void dismissProgressDialog() {
android.util.Log.i(FRAGMENT_TAG, "in dismissProgressDialog");
if (mProgressDialog != null && mProgressDialog.isShowing()) {
android.util.Log.i(FRAGMENT_TAG, "progress dialog dismissed");
mProgressDialog.dismiss();
}
mProgressDialog = null;
}
/**
* Returns the Array of dialog options. Options are displayed in the same
* order as they appear in the array.
*/
protected DialogOption[] getDialogOptions() {
return new DialogOption[] {
DialogOption.CLEAR_HISTORY,
DialogOption.CLEAR_CACHE,
DialogOption.CLEAR_COOKIES_AND_SITE_DATA,
DialogOption.CLEAR_PASSWORDS,
DialogOption.CLEAR_FORM_DATA};
}
/**
* Get the default selections for the dialog.
* @return EnumSet containing dialog options to be selected.
*/
protected EnumSet<DialogOption> getDefaultDialogOptionsSelections() {
return EnumSet.of(DialogOption.CLEAR_HISTORY, DialogOption.CLEAR_CACHE,
DialogOption.CLEAR_COOKIES_AND_SITE_DATA);
}
// Called when "clear browsing data" completes.
// Implements the ChromePreferences.OnClearBrowsingDataListener interface.
@Override
public void onBrowsingDataCleared() {
dismissProgressDialog();
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == AlertDialog.BUTTON_POSITIVE) {
dismissProgressDialog();
onOptionSelected(mSelectedOptions);
}
}
/**
* Disable the "Clear" button if none of the options are selected. Otherwise, enable it.
*/
private void updateButtonState() {
Button clearButton = mDialog.getButton(AlertDialog.BUTTON_POSITIVE);
if (clearButton != null) clearButton.setEnabled(!mSelectedOptions.isEmpty());
}
@Override
public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) {
if (isChecked) {
mSelectedOptions.add(mOptions[whichButton]);
} else {
mSelectedOptions.remove(mOptions[whichButton]);
}
updateButtonState();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
DialogOption[] options = getDialogOptions();
mOptions = Arrays.copyOf(options, options.length);
mSelectedOptions = getDefaultDialogOptionsSelections();
String[] items = new String[mOptions.length];
boolean[] itemsChecked = new boolean[mOptions.length];
Resources resources = getResources();
for (int i = 0; i < mOptions.length; i++) {
items[i] = resources.getString(mOptions[i].getResourceId());
itemsChecked[i] = mSelectedOptions.contains(mOptions[i]);
}
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(R.string.clear_browsing_data_title)
.setPositiveButton(R.string.clear_data_delete, this)
.setNegativeButton(R.string.cancel, this)
.setMultiChoiceItems(items, itemsChecked, this);
if (ChromeSigninController.get(getActivity()).isSignedIn()) {
final String message = getString(R.string.clear_cookies_no_sign_out_summary);
final SpannableString messageWithLink = SpanApplier.applySpans(message,
new SpanApplier.SpanInfo("<link>", "</link>", new ClickableSpan() {
@Override
public void onClick(View widget) {
dismiss();
Preferences prefActivity = (Preferences) getActivity();
prefActivity.startFragment(AccountManagementFragment.class.getName(),
null);
}
// Change link formatting to use no underline
@Override
public void updateDrawState(TextPaint textPaint) {
textPaint.setColor(textPaint.linkColor);
textPaint.setUnderlineText(false);
}
}));
View view = getActivity().getLayoutInflater().inflate(
R.layout.single_line_bottom_text_dialog, null);
TextView summaryView = (TextView) view.findViewById(R.id.summary);
summaryView.setText(messageWithLink);
summaryView.setMovementMethod(LinkMovementMethod.getInstance());
builder.setView(view);
}
mDialog = builder.create();
return mDialog;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Now that the dialog's view has been created, update the button state.
updateButtonState();
}
/**
* Called when PositiveButton is clicked for the dialog.
*
* @param selectedOptions options which were selected.
*/
protected void onOptionSelected(final EnumSet<DialogOption> selectedOptions) {
showProgressDialog();
clearBrowsingData(selectedOptions);
}
protected final void showProgressDialog() {
if (getActivity() == null) return;
android.util.Log.i(FRAGMENT_TAG, "progress dialog shown");
mProgressDialog = ProgressDialog.show(getActivity(),
getActivity().getString(R.string.clear_browsing_data_progress_title),
getActivity().getString(R.string.clear_browsing_data_progress_message), true,
false);
}
}
// 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 android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.ChromeSwitchPreference;
import org.chromium.chrome.browser.preferences.ManagedPreferenceDelegate;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.preferences.Preferences;
/**
* Fragment to manage the Contextual Search preference and to explain to the user what it does.
*/
public class ContextualSearchPreferenceFragment extends PreferenceFragment {
private static final String PREF_CONTEXTUAL_SEARCH_SWITCH = "contextual_search_switch";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.contextual_search_preferences);
getActivity().setTitle(R.string.contextual_search_title);
setHasOptionsMenu(true);
initContextualSearchSwitch();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
menu.add(Menu.NONE, R.id.menu_id_contextual_search_learn, Menu.NONE, R.string.learn_more);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() != R.id.menu_id_contextual_search_learn) {
return false;
}
((Preferences) getActivity()).showUrl(R.string.learn_more,
R.string.contextual_search_learn_more_url);
return true;
}
private void initContextualSearchSwitch() {
ChromeSwitchPreference contextualSearchSwitch =
(ChromeSwitchPreference) findPreference(PREF_CONTEXTUAL_SEARCH_SWITCH);
boolean isContextualSearchEnabled =
!PrefServiceBridge.getInstance().isContextualSearchDisabled();
contextualSearchSwitch.setChecked(isContextualSearchEnabled);
contextualSearchSwitch.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
PrefServiceBridge.getInstance().setContextualSearchState((boolean) newValue);
((Preferences) getActivity()).logContextualSearchToggled((boolean) newValue);
return true;
}
});
contextualSearchSwitch.setManagedPreferenceDelegate(new ManagedPreferenceDelegate() {
@Override
public boolean isPreferenceControlledByPolicy(Preference preference) {
return PrefServiceBridge.getInstance().isContextualSearchDisabledByPolicy();
}
});
}
}
// 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.content.Context;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.util.AttributeSet;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.ChromeBaseListPreference;
/**
* Crash upload bandwidth preference.
*/
public class CrashDumpUploadPreference extends ChromeBaseListPreference
implements OnPreferenceChangeListener {
private Context mContext;
public CrashDumpUploadPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setOnPreferenceChangeListener(this);
String currentCrashPreference =
PrivacyPreferencesManager.getInstance(context).getPrefCrashDumpUploadPreference();
setSummary(getSummaryText(currentCrashPreference));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
setSummary(getSummaryText((String) newValue));
return true;
}
/**
* Text to display in the summary of the preference.
* @param currentCrashPreference current value OR selected value if exists.
* @return resource of the text.
*/
public int getSummaryText(String currentCrashPreference) {
if (currentCrashPreference.equals(mContext.getString(
R.string.crash_dump_always_upload_value))) {
return R.string.crash_dump_always_upload;
} else if (currentCrashPreference.equals(mContext.getString(
R.string.crash_dump_only_with_wifi_value))) {
return R.string.crash_dump_only_with_wifi;
} else {
return R.string.crash_dump_never_upload;
}
}
}
// 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 'Do Not Track' preference and to explain to the user what it does.
*/
public class DoNotTrackPreference extends PreferenceFragment {
private static final String PREF_DO_NOT_TRACK_SWITCH = "do_not_track_switch";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.do_not_track_preferences);
getActivity().setTitle(R.string.do_not_track_title);
ChromeSwitchPreference doNotTrackSwitch =
(ChromeSwitchPreference) findPreference(PREF_DO_NOT_TRACK_SWITCH);
boolean isDoNotTrackEnabled = PrefServiceBridge.getInstance().isDoNotTrackEnabled();
doNotTrackSwitch.setChecked(isDoNotTrackEnabled);
doNotTrackSwitch.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
PrefServiceBridge.getInstance().setDoNotTrackEnabled((boolean) newValue);
return true;
}
});
}
}
// 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.content.Context;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.util.AttributeSet;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.preferences.ChromeBaseListPreference;
import org.chromium.chrome.browser.preferences.NetworkPredictionOptions;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
/**
* Fragment to set and retrieve the prerender preference.
*/
public class NetworkPredictionPreference extends ChromeBaseListPreference
implements OnPreferenceChangeListener {
private final Context mContext;
public NetworkPredictionPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
String[] networkPredictionPrefs = context.getResources().getStringArray(
R.array.bandwidth_entries);
assert networkPredictionPrefs.length == NetworkPredictionOptions.choiceCount();
setOnPreferenceChangeListener(this);
setSummary(context.getString(
PrefServiceBridge.getInstance().getNetworkPredictionOptions().getDisplayTitle()));
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
setSummary(mContext.getString(
NetworkPredictionOptions.stringToEnum((String) newValue).getDisplayTitle()));
return true;
}
}
...@@ -247,6 +247,114 @@ ...@@ -247,6 +247,114 @@
Default Default
</message> </message>
<!-- Privacy preferences -->
<message name="IDS_PREFS_PRIVACY" desc="Title for the Privacy preferences. [CHAR-LIMIT=32]">
Privacy
</message>
<message name="IDS_NAVIGATION_ERROR_TITLE" desc="Title for checkbox to enable or disable navigation error suggestions.">
Navigation error suggestions
</message>
<message name="IDS_NAVIGATION_ERROR_SUMMARY" desc="Summary for navigation error suggestions.">
Show suggestions when a web address does not resolve or a connection cannot be made
</message>
<message name="IDS_SEARCH_SUGGESTIONS_TITLE" desc="Title for search and url suggestions.">
Search and URL suggestions
</message>
<message name="IDS_SEARCH_SUGGESTIONS_SUMMARY" desc="Summary for search and url suggestions.">
Use a prediction service to show related queries and popular websites as you type in the address bar
</message>
<message name="IDS_NETWORK_PREDICTIONS_TITLE" desc="Title for Prefetch page resources.">
Prefetch page resources
</message>
<message name="IDS_NETWORK_PREDICTIONS_SUMMARY" desc="Summary for Prefetch page resources.">
Improve page load performance
</message>
<message name="IDS_NETWORK_PREDICTION_ALWAYS_VALUE" desc="Internal value for prefetch page resources preference" translateable="false">
network_prediction_always
</message>
<message name="IDS_NETWORK_PREDICTION_WIFI_ONLY_VALUE" desc="Internal value for prefetch page resources preference" translateable="false">
network_prediction_wifi_only
</message>
<message name="IDS_NETWORK_PREDICTION_NEVER_VALUE" desc="Internal value for prefetch page resources preference" translateable="false">
network_prediction_never
</message>
<message name="IDS_CONTEXTUAL_SEARCH_TITLE" desc="Name for the Contextual Search feature, which allows users to search for a term in a web page by tapping on it.">
Touch to Search
</message>
<message name="IDS_CONTEXTUAL_SEARCH_DESCRIPTION" desc="Description for Contextual Search preference">
Learn about topics on websites without leaving the page. Touch to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results, and other details.
To adjust your search term, long press to select. To refine your search, slide the panel all the way up and touch the search box.
</message>
<message name="IDS_CONTEXTUAL_SEARCH_LEARN_MORE_URL" desc="URL for learning more about Contextual Search preference" translateable="false">
https://support.google.com/chrome/answer/95440#android
</message>
<message name="IDS_CRASH_DUMP_UPLOAD_TITLE" desc="Title for crash upload upload preference">
Usage and crash reports
</message>
<message name="IDS_CRASH_DUMP_NEVER_UPLOAD" desc="Settings option never to upload crash reports [CHAR-LIMIT=32]">
Never send
</message>
<message name="IDS_CRASH_DUMP_ALWAYS_UPLOAD" desc="Settings option to upload crash reports only anytime (when on Wi-Fi or mobile data) [CHAR-LIMIT=32]">
Always send
</message>
<message name="IDS_CRASH_DUMP_ONLY_WITH_WIFI" desc="Settings option to upload crash reports only over Wi-Fi [CHAR-LIMIT=32]">
Only send on Wi-Fi
</message>
<message name="IDS_CRASH_DUMP_NEVER_UPLOAD_VALUE" desc="Internal value for crash uploading preference." translateable="false">
crash_dump_never_upload
</message>
<message name="IDS_CRASH_DUMP_ALWAYS_UPLOAD_VALUE" desc="Internal value for crash uploading preference." translateable="false">
crash_dump_always_upload
</message>
<message name="IDS_CRASH_DUMP_ONLY_WITH_WIFI_VALUE" desc="Internal value for crash uploading preference." translateable="false">
crash_dump_only_with_wifi
</message>
<message name="IDS_DO_NOT_TRACK_TITLE" desc="Title for 'Do Not Track' preference">
‘Do Not Track’
</message>
<message name="IDS_DO_NOT_TRACK_DESCRIPTION" desc="Description for 'Do Not Track' preference">
Enabling ‘Do Not Track’ means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request, and how the request is interpreted.
For example, some websites may respond to this request by showing you ads that aren’t based on other websites you’ve visited. Many websites will still collect and use your browsing data - for example to improve security, to provide content, ads and recommendations on their websites, and to generate reporting statistics.
</message>
<message name="IDS_DO_NOT_TRACK_LEARN_MORE_URL" desc="URL for learning more about 'Do Not Track' preference" translateable="false">
https://support.google.com/chrome/?p=settings_do_not_track
</message>
<message name="IDS_CLEAR_BROWSING_DATA_TITLE" desc="Button to Clear Browsing Data [CHAR-LIMIT=24]">
Clear browsing data
</message>
<message name="IDS_CLEAR_CACHE_TITLE" desc="Title for Clear Cache in Clear Browsing Data dialog">
Clear the cache
</message>
<message name="IDS_CLEAR_HISTORY_TITLE" desc="Title for Clear History in Clear Browsing Data dialog">
Clear browsing history
</message>
<message name="IDS_CLEAR_COOKIES_AND_SITE_DATA_TITLE" desc="Title for Clear Cookies and site data in Clear Browsing Data dialog">
Clear cookies, site data
</message>
<message name="IDS_CLEAR_COOKIES_NO_SIGN_OUT_SUMMARY" desc="Text at the bottom of the Clear Browsing Data dialog informing that clearing cookies wouldn't sign the user out of Google Accounts. Dialog also contains a link which opens the Account Management screen.">
You won't be signed out of your <ph name="BEGIN_LINK">&lt;link&gt;</ph>Google Accounts<ph name="END_LINK">&lt;/link&gt;</ph>
</message>
<message name="IDS_CLEAR_PASSWORDS_TITLE" desc="Title for Clear Passwords in Clear Browsing Data preference">
Clear saved passwords
</message>
<message name="IDS_CLEAR_FORMDATA_TITLE" desc="Title for Clear Form Data in Clear Browsing Data preference">
Clear autofill data
</message>
<message name="IDS_CLEAR_BOOKMARKS_TITLE" desc="Title for Clear Bookmarks data in Clear Synced Data dialog">
Clear bookmarks
</message>
<message name="IDS_CLEAR_BROWSING_DATA_PROGRESS_TITLE" desc='Title for the progress dialog used when waiting for "clear browsing data" to complete.'>
Clearing browsing data
</message>
<message name="IDS_CLEAR_DATA_DELETE" desc="Button that allows the user to clear their browsing data. [CHAR-LIMIT=20]">
Clear
</message>
<message name="IDS_CLEAR_BROWSING_DATA_PROGRESS_MESSAGE" desc='Message on the progress dialog used when waiting for "clear browsing data" to complete.'>
Please wait…
</message>
<!-- Accessibility preferences --> <!-- Accessibility preferences -->
<message name="IDS_PREFS_ACCESSIBILITY" desc="Title of Accessibility settings, which allows the user to change webpage font sizes. [CHAR-LIMIT=32]"> <message name="IDS_PREFS_ACCESSIBILITY" desc="Title of Accessibility settings, which allows the user to change webpage font sizes. [CHAR-LIMIT=32]">
Accessibility Accessibility
......
// 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.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.test.InstrumentationTestCase;
import android.test.UiThreadTest;
import android.test.suitebuilder.annotation.SmallTest;
import org.chromium.base.CommandLine;
import org.chromium.base.test.util.AdvancedMockContext;
import org.chromium.base.test.util.Feature;
import org.chromium.chrome.R;
public class PrivacyPreferencesManagerTest extends InstrumentationTestCase {
private static final boolean CELLULAR_DEVICE = true;
private static final boolean WIFI_DEVICE = false;
private static final boolean CONNECTED = true;
private static final boolean DISCONNECTED = false;
private static final boolean WIFI_ON = true;
private static final boolean WIFI_OFF = false;
private static final boolean UPLOAD_OK = true;
private static final boolean UPLOAD_NOT_PERMITTED = false;
private static final UserUploadPreference UPLOAD_ALWAYS = UserUploadPreference.ALWAYS;
private static final UserUploadPreference UPLOAD_WIFI_ONLY = UserUploadPreference.WIFI_ONLY;
private static final UserUploadPreference UPLOAD_NEVER = UserUploadPreference.NEVER;
// Perform the same test a few times to make sure any sort of
// caching still works.
private static final int REPS = 3;
/**
* Enum used to specify user upload preference that is easy to read.
*/
private static enum UserUploadPreference {
ALWAYS(R.string.crash_dump_always_upload_value),
WIFI_ONLY(R.string.crash_dump_only_with_wifi_value),
NEVER(R.string.crash_dump_never_upload_value);
private final int mValueId;
UserUploadPreference(int valueId) {
mValueId = valueId;
}
public String toStringValue(Context context) {
return context.getString(mValueId);
}
public boolean toBooleanValue() {
return !equals(NEVER); // return true for WIFI_ONLY for now
}
}
@SmallTest
@Feature({"Android-AppBase"})
@UiThreadTest
public void testAllowCrashDumpUploadNowCellDev() {
CommandLine.init(null);
runTest(CELLULAR_DEVICE, UPLOAD_ALWAYS, CONNECTED, WIFI_ON, UPLOAD_OK);
runTest(CELLULAR_DEVICE, UPLOAD_ALWAYS, DISCONNECTED, WIFI_ON, UPLOAD_NOT_PERMITTED);
runTest(CELLULAR_DEVICE, UPLOAD_ALWAYS, CONNECTED, WIFI_OFF, UPLOAD_OK);
runTest(CELLULAR_DEVICE, UPLOAD_ALWAYS, DISCONNECTED, WIFI_OFF, UPLOAD_NOT_PERMITTED);
runTest(CELLULAR_DEVICE, UPLOAD_WIFI_ONLY, CONNECTED, WIFI_ON, UPLOAD_OK);
runTest(CELLULAR_DEVICE, UPLOAD_WIFI_ONLY, DISCONNECTED, WIFI_ON, UPLOAD_NOT_PERMITTED);
runTest(CELLULAR_DEVICE, UPLOAD_WIFI_ONLY, CONNECTED, WIFI_OFF, UPLOAD_NOT_PERMITTED);
runTest(CELLULAR_DEVICE, UPLOAD_WIFI_ONLY, DISCONNECTED, WIFI_OFF, UPLOAD_NOT_PERMITTED);
runTest(CELLULAR_DEVICE, UPLOAD_NEVER, CONNECTED, WIFI_ON, UPLOAD_NOT_PERMITTED);
runTest(CELLULAR_DEVICE, UPLOAD_NEVER, DISCONNECTED, WIFI_ON, UPLOAD_NOT_PERMITTED);
runTest(CELLULAR_DEVICE, UPLOAD_NEVER, CONNECTED, WIFI_OFF, UPLOAD_NOT_PERMITTED);
runTest(CELLULAR_DEVICE, UPLOAD_NEVER, DISCONNECTED, WIFI_OFF, UPLOAD_NOT_PERMITTED);
}
@SmallTest
@Feature({"Android-AppBase"})
@UiThreadTest
public void testAllowCrashDumpUploadNowWifiDev() {
CommandLine.init(null);
runTest(WIFI_DEVICE, UPLOAD_ALWAYS, CONNECTED, WIFI_ON, UPLOAD_OK);
runTest(WIFI_DEVICE, UPLOAD_ALWAYS, DISCONNECTED, WIFI_OFF, UPLOAD_NOT_PERMITTED);
runTest(WIFI_DEVICE, UPLOAD_NEVER, CONNECTED, WIFI_ON, UPLOAD_NOT_PERMITTED);
runTest(WIFI_DEVICE, UPLOAD_NEVER, DISCONNECTED, WIFI_OFF, UPLOAD_NOT_PERMITTED);
}
private void runTest(boolean mobileCapable, UserUploadPreference userPreference,
boolean isConnected, boolean wifiOn, boolean uploadPermitted) {
PermissionContext context = new PermissionContext(getInstrumentation().getTargetContext());
PrivacyPreferencesManager preferenceManager =
new MockPrivacyPreferencesManager(context, mobileCapable, isConnected, wifiOn);
for (int i = 0; i < REPS; i++) {
setUpUserPreferences(context, userPreference);
String state = String.format(
"[cellular = %b, preference = %b, connected = %b, wifi = %b]",
mobileCapable, userPreference.toBooleanValue(), isConnected, wifiOn);
boolean res = preferenceManager.allowUploadCrashDumpNow();
if (uploadPermitted) {
assertTrue("Upload should be permitted for " + state, res);
} else {
assertFalse("Upload should NOT be permitted for " + state, res);
}
}
}
private void setUpUserPreferences(Context context, UserUploadPreference userPreference) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor ed = pref.edit()
.putString(PrivacyPreferencesManager.PREF_CRASH_DUMP_UPLOAD,
userPreference.toStringValue(context))
.putBoolean(PrivacyPreferencesManager.PREF_CRASH_DUMP_UPLOAD_NO_CELLULAR,
userPreference.toBooleanValue());
ed.apply();
}
private static class MockPrivacyPreferencesManager extends PrivacyPreferencesManager {
private final boolean mIsMobileCapable;
private final boolean mIsConnected;
private final boolean mIsWifi;
MockPrivacyPreferencesManager(Context context, boolean isMobileCapable, boolean isConnected,
boolean isWifi) {
super(context);
mIsMobileCapable = isMobileCapable;
mIsConnected = isConnected;
mIsWifi = isWifi;
}
@Override
public boolean isMobileNetworkCapable() {
return mIsMobileCapable;
}
@Override
public boolean isNetworkAvailable() {
return mIsConnected;
}
@Override
public boolean isWiFiOrEthernetNetwork() {
return mIsWifi;
}
}
private static class PermissionContext extends AdvancedMockContext {
public PermissionContext(Context targetContext) {
super(targetContext);
}
@Override
public Object getSystemService(String name) {
if (Context.CONNECTIVITY_SERVICE.equals(name)) {
return null;
}
fail("Should not ask for any other service than the ConnectionManager.");
return super.getSystemService(name);
}
}
}
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