summaryrefslogtreecommitdiffstats
path: root/src/src/com/android/browser/preferences
diff options
context:
space:
mode:
Diffstat (limited to 'src/src/com/android/browser/preferences')
-rw-r--r--src/src/com/android/browser/preferences/AboutPreferencesFragment.java228
-rw-r--r--src/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java128
-rw-r--r--src/src/com/android/browser/preferences/AdvancedPreferencesFragment.java225
-rw-r--r--src/src/com/android/browser/preferences/BandwidthPreferencesFragment.java63
-rw-r--r--src/src/com/android/browser/preferences/ContentPreferencesFragment.java113
-rw-r--r--src/src/com/android/browser/preferences/DebugPreferencesFragment.java74
-rw-r--r--src/src/com/android/browser/preferences/FontSizePreview.java56
-rw-r--r--src/src/com/android/browser/preferences/GeneralPreferencesFragment.java393
-rw-r--r--src/src/com/android/browser/preferences/InvertedContrastPreview.java99
-rw-r--r--src/src/com/android/browser/preferences/LegalPreferencesFragment.java121
-rw-r--r--src/src/com/android/browser/preferences/LegalPreviewActivity.java95
-rw-r--r--src/src/com/android/browser/preferences/LegalPreviewFragment.java83
-rw-r--r--src/src/com/android/browser/preferences/NonformattingListPreference.java48
-rw-r--r--src/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java250
-rw-r--r--src/src/com/android/browser/preferences/SWEPreferenceFragment.java114
-rw-r--r--src/src/com/android/browser/preferences/SeekBarSummaryPreference.java90
-rw-r--r--src/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java816
-rw-r--r--src/src/com/android/browser/preferences/WebViewPreview.java93
-rw-r--r--src/src/com/android/browser/preferences/WebsiteSettingsFragment.java388
19 files changed, 3477 insertions, 0 deletions
diff --git a/src/src/com/android/browser/preferences/AboutPreferencesFragment.java b/src/src/com/android/browser/preferences/AboutPreferencesFragment.java
new file mode 100644
index 00000000..7d143205
--- /dev/null
+++ b/src/src/com/android/browser/preferences/AboutPreferencesFragment.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.provider.Browser;
+
+import com.android.browser.BrowserActivity;
+import com.android.browser.BrowserPreferencesPage;
+import com.android.browser.BrowserSwitches;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+import com.android.browser.UpdateNotificationService;
+
+import org.codeaurora.swe.BrowserCommandLine;
+
+public class AboutPreferencesFragment extends PreferenceFragment
+ implements OnPreferenceClickListener {
+
+ final String ABOUT_TEXT_VERSION_KEY = "Version:";
+ final String ABOUT_TEXT_BUILT_KEY = "Built:";
+ final String ABOUT_TEXT_HASH_KEY = "Hash:";
+
+ String mFeedbackRecipient = "";
+ String mHelpURL = "";
+ String mVersion = "";
+ String mBuilt = "";
+ String mHash = "";
+ String mTabTitle = "";
+ String mTabURL = "";
+
+ String mAboutText = "";
+ PreferenceScreen mHeadPref = null;
+
+ private String findValueFromAboutText(String aboutKey) {
+ int start = mAboutText.indexOf(aboutKey);
+ int end = mAboutText.indexOf("\n", start);
+ String value = "";
+
+ if (start != -1 && end != -1) {
+ start += aboutKey.length();
+ value = mAboutText.substring(start, end);
+ }
+ return value;
+ }
+
+ private void setPreference(String prefKey, String value) {
+ Preference pref = findPreference(prefKey);
+ if (pref == null) {
+ return;
+ }
+
+ if (value.isEmpty()) {
+ if (mHeadPref != null)
+ mHeadPref.removePreference(pref);
+ } else {
+ pref.setSummary(value);
+ }
+ }
+
+ private void setOnClickListener(String prefKey, boolean set) {
+ Preference pref = findPreference(prefKey);
+ if (pref == null) {
+ return;
+ }
+
+ if (set) {
+ pref.setOnPreferenceClickListener(this);
+ } else {
+ if (mHeadPref != null)
+ mHeadPref.removePreference(pref);
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ ActionBar bar = getActivity().getActionBar();
+ if (bar != null) {
+ bar.setTitle(R.string.about);
+ }
+
+ mAboutText = getString(R.string.about_text);
+
+ addPreferencesFromResource(R.xml.about_preferences);
+ mHeadPref = (PreferenceScreen) findPreference(PreferenceKeys.PREF_ABOUT);
+
+ mVersion = findValueFromAboutText(ABOUT_TEXT_VERSION_KEY);
+ setPreference(PreferenceKeys.PREF_VERSION, mVersion);
+
+ mBuilt = findValueFromAboutText(ABOUT_TEXT_BUILT_KEY);
+ setPreference(PreferenceKeys.PREF_BUILD_DATE, mBuilt);
+
+ mHash = findValueFromAboutText(ABOUT_TEXT_HASH_KEY);
+ setPreference(PreferenceKeys.PREF_BUILD_HASH, mHash);
+
+ final Bundle arguments = getArguments();
+ String user_agent = "";
+ if (arguments != null) {
+ user_agent = (String) arguments.getCharSequence("UA", "");
+ mTabTitle = (String) arguments.getCharSequence("TabTitle", "");
+ mTabURL = (String) arguments.getCharSequence("TabURL", "");
+ }
+
+ setPreference(PreferenceKeys.PREF_USER_AGENT, user_agent);
+
+ if (BrowserCommandLine.hasSwitch(BrowserSwitches.CMD_LINE_SWITCH_HELPURL)) {
+ mHelpURL = BrowserCommandLine.getSwitchValue(
+ BrowserSwitches.CMD_LINE_SWITCH_HELPURL);
+ }
+
+ setOnClickListener(PreferenceKeys.PREF_HELP, !mHelpURL.isEmpty());
+
+ if (BrowserCommandLine.hasSwitch(BrowserSwitches.CMD_LINE_SWITCH_FEEDBACK)) {
+ mFeedbackRecipient = BrowserCommandLine.getSwitchValue(
+ BrowserSwitches.CMD_LINE_SWITCH_FEEDBACK);
+ }
+
+ setOnClickListener(PreferenceKeys.PREF_FEEDBACK, !mFeedbackRecipient.isEmpty());
+
+ setOnClickListener(PreferenceKeys.PREF_LEGAL, true);
+ if (BrowserCommandLine.hasSwitch(BrowserSwitches.AUTO_UPDATE_SERVER_CMD)) {
+ setPreference(PreferenceKeys.PREF_AUTO_UPDATE,
+ UpdateNotificationService.getLatestVersion(getActivity()));
+ setOnClickListener(PreferenceKeys.PREF_AUTO_UPDATE,
+ UpdateNotificationService.getCurrentVersionCode(getActivity()) <
+ UpdateNotificationService.getLatestVersionCode(getActivity()));
+ } else {
+ Preference pref = findPreference(PreferenceKeys.PREF_AUTO_UPDATE);
+ if (mHeadPref != null)
+ mHeadPref.removePreference(pref);
+ }
+
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ if (preference.getKey().equals(PreferenceKeys.PREF_HELP)) {
+ Intent intent = new Intent(getActivity(), BrowserActivity.class);
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(mHelpURL));
+ getActivity().startActivity(intent);
+ return true;
+ } else if(preference.getKey().equals(PreferenceKeys.PREF_LEGAL)) {
+ Bundle bundle = new Bundle();
+ BrowserPreferencesPage.startPreferenceFragmentExtraForResult(getActivity(),
+ LegalPreferencesFragment.class.getName(), bundle, 0);
+ return true;
+ } else if (preference.getKey().equals(PreferenceKeys.PREF_FEEDBACK)) {
+ Intent intent = new Intent(Intent.ACTION_SEND);
+ intent.setType("message/rfc822");
+ intent.putExtra(Intent.EXTRA_EMAIL, new String[]{mFeedbackRecipient});
+ intent.putExtra(Intent.EXTRA_SUBJECT,"Browser Feedback");
+
+ String message = "";
+ if (!mVersion.isEmpty()) {
+ message += "Version: " + mVersion + "\n";
+ }
+
+ if (!mBuilt.isEmpty()) {
+ message += "Build Date: " + mBuilt + "\n";
+ }
+
+ if (!mHash.isEmpty()) {
+ message += "Build Hash: " + mHash + "\n";
+ }
+
+ if (!mTabTitle.isEmpty()) {
+ message += "Tab Title: " + mTabTitle + "\n";
+ }
+
+ if (!mTabURL.isEmpty()) {
+ message += "Tab URL: " + mTabURL + "\n";
+ }
+
+ message += "\nEnter your feedback here...";
+
+ intent.putExtra(Intent.EXTRA_TEXT, message);
+ startActivity(Intent.createChooser(intent, "Select email application"));
+ return true;
+ } else if (preference.getKey().equals(PreferenceKeys.PREF_AUTO_UPDATE)) {
+ Intent intent = new Intent(getActivity(), BrowserActivity.class);
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.putExtra(Browser.EXTRA_APPLICATION_ID, getActivity().getPackageName());
+ intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
+ intent.setData(Uri.parse(
+ UpdateNotificationService.getLatestDownloadUrl(getActivity())));
+ getActivity().startActivity(intent);
+ }
+ return false;
+ }
+}
diff --git a/src/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java b/src/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java
new file mode 100644
index 00000000..a505836b
--- /dev/null
+++ b/src/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+import android.content.Context;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.util.Log;
+
+import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+
+import java.text.NumberFormat;
+
+public class AccessibilityPreferencesFragment extends SWEPreferenceFragment
+ implements Preference.OnPreferenceChangeListener {
+
+ NumberFormat mFormat;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.accessibility_preferences);
+ BrowserSettings settings = BrowserSettings.getInstance();
+ mFormat = NumberFormat.getPercentInstance();
+
+ Preference e = findPreference(PreferenceKeys.PREF_MIN_FONT_SIZE);
+ e.setOnPreferenceChangeListener(this);
+ updateMinFontSummary(e, settings.getMinimumFontSize());
+ e = findPreference(PreferenceKeys.PREF_TEXT_ZOOM);
+ e.setOnPreferenceChangeListener(this);
+ updateTextZoomSummary(e, settings.getTextZoom());
+
+ /* SWE: Comment out double tap zoom feature
+ e = findPreference(PreferenceKeys.PREF_DOUBLE_TAP_ZOOM);
+ e.setOnPreferenceChangeListener(this);
+ updateDoubleTapZoomSummary(e, settings.getDoubleTapZoom());
+ */
+ /*
+ * SWE_TODO: Commented out functionality for inverted rendering
+ * (as well as corresponding sections below)
+ e = findPreference(PreferenceKeys.PREF_INVERTED_CONTRAST);
+ e.setOnPreferenceChangeListener(this);
+ updateInvertedContrastSummary(e, (int) (settings.getInvertedContrast() * 100));
+ */
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ ActionBar bar = getActivity().getActionBar();
+ if (bar != null) {
+ bar.setTitle(R.string.pref_accessibility_title);
+ bar.setDisplayHomeAsUpEnabled(false);
+ bar.setHomeButtonEnabled(false);
+ }
+ }
+
+ void updateMinFontSummary(Preference pref, int minFontSize) {
+ Context c = getActivity();
+ pref.setSummary(c.getString(R.string.pref_min_font_size_value, minFontSize));
+ }
+
+ void updateTextZoomSummary(Preference pref, int textZoom) {
+ pref.setSummary(mFormat.format(textZoom / 100.0));
+ }
+
+ void updateDoubleTapZoomSummary(Preference pref, int doubleTapZoom) {
+ pref.setSummary(mFormat.format(doubleTapZoom / 100.0));
+ }
+
+ /*
+ void updateInvertedContrastSummary(Preference pref, int contrast) {
+ pref.setSummary(mFormat.format(contrast / 100.0));
+ }
+ */
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object objValue) {
+ if (getActivity() == null) {
+ // We aren't attached, so don't accept preferences changes from the
+ // invisible UI.
+ Log.d("AccessibilityPref", "Activity is null");
+ return false;
+ }
+ Log.d("AccessibilityPref", "User clicked on " + pref.getKey());
+
+ if (PreferenceKeys.PREF_MIN_FONT_SIZE.equals(pref.getKey())) {
+ updateMinFontSummary(pref, BrowserSettings
+ .getAdjustedMinimumFontSize((Integer) objValue));
+ }
+ if (PreferenceKeys.PREF_TEXT_ZOOM.equals(pref.getKey())) {
+ BrowserSettings settings = BrowserSettings.getInstance();
+ updateTextZoomSummary(pref, settings
+ .getAdjustedTextZoom((Integer) objValue));
+ }
+ if (PreferenceKeys.PREF_DOUBLE_TAP_ZOOM.equals(pref.getKey())) {
+ BrowserSettings settings = BrowserSettings.getInstance();
+ updateDoubleTapZoomSummary(pref, settings
+ .getAdjustedDoubleTapZoom((Integer) objValue));
+ }
+ /*
+ if (PreferenceKeys.PREF_INVERTED_CONTRAST.equals(pref.getKey())) {
+ updateInvertedContrastSummary(pref,
+ (int) ((10 + (Integer) objValue) * 10));
+ }
+ */
+
+ return true;
+ }
+
+}
diff --git a/src/src/com/android/browser/preferences/AdvancedPreferencesFragment.java b/src/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
new file mode 100644
index 00000000..3d988947
--- /dev/null
+++ b/src/src/com/android/browser/preferences/AdvancedPreferencesFragment.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.browser.preferences;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.Intent;
+import android.content.SharedPreferences.Editor;
+import android.net.Uri;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+import android.util.Log;
+
+import com.android.browser.BaseUi;
+import com.android.browser.BrowserActivity;
+import com.android.browser.BrowserSettings;
+import com.android.browser.BrowserYesNoPreference;
+import com.android.browser.DownloadHandler;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+
+public class AdvancedPreferencesFragment
+ implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener {
+
+ PreferenceFragment mFragment = null;
+
+ AdvancedPreferencesFragment(PreferenceFragment fragment) {
+ mFragment = fragment;
+
+ Preference e = mFragment.findPreference(PreferenceKeys.PREF_RESET_DEFAULT_PREFERENCES);
+ e.setOnPreferenceChangeListener(this);
+
+ e = mFragment.findPreference(PreferenceKeys.PREF_SEARCH_ENGINE);
+ e.setOnPreferenceChangeListener(this);
+ updateListPreferenceSummary((ListPreference) e);
+
+ e = mFragment.findPreference("privacy_security");
+ e.setOnPreferenceClickListener(this);
+
+ e = mFragment.findPreference(PreferenceKeys.PREF_DEBUG_MENU);
+ if (!BrowserSettings.getInstance().isDebugEnabled()) {
+ PreferenceCategory category = (PreferenceCategory) mFragment.findPreference("advanced");
+ category.removePreference(e);
+ } else {
+ e.setOnPreferenceClickListener(this);
+ }
+
+ e = mFragment.findPreference("accessibility_menu");
+ e.setOnPreferenceClickListener(this);
+
+ // Below are preferences for carrier specific features
+ PreferenceScreen contentSettingsPrefScreen =
+ (PreferenceScreen) mFragment.findPreference("content_settings");
+ contentSettingsPrefScreen.setOnPreferenceClickListener(this);
+
+ ListPreference edgeSwipePref =
+ (ListPreference) mFragment.findPreference("edge_swiping_action");
+ edgeSwipePref.setOnPreferenceChangeListener(this);
+
+ if (BaseUi.isUiLowPowerMode()) {
+ edgeSwipePref.setEnabled(false);
+ } else {
+ String[] options = mFragment.getResources().getStringArray(
+ R.array.pref_edge_swiping_values);
+
+ String value = BrowserSettings.getInstance().getEdgeSwipeAction();
+
+ if (value.equals(mFragment.getString(R.string.value_unknown_edge_swipe))) {
+ edgeSwipePref.setSummary(mFragment.getString(R.string.pref_edge_swipe_unknown));
+ } else {
+ for (int i = 0; i < options.length; i++) {
+ if (value.equals(options[i])) {
+ edgeSwipePref.setValueIndex(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if (requestCode == ContentPreferencesFragment.DOWNLOAD_PATH_RESULT_CODE) {
+ if ( resultCode == Activity.RESULT_OK && intent != null) {
+ final String result_dir_sel =
+ mFragment.getResources().getString(R.string.def_file_manager_result_dir);
+ String downloadPath = intent.getStringExtra(result_dir_sel);
+ // Fallback logic to stock browser
+ if (downloadPath == null) {
+ Uri uri = intent.getData();
+ if(uri != null)
+ downloadPath = uri.getPath();
+ }
+ if (downloadPath != null) {
+ PreferenceScreen downloadPathPreset =
+ (PreferenceScreen) mFragment.findPreference(
+ PreferenceKeys.PREF_DOWNLOAD_PATH);
+ Editor editor = downloadPathPreset.getEditor();
+ editor.putString(PreferenceKeys.PREF_DOWNLOAD_PATH, downloadPath);
+ editor.apply();
+ String downloadPathForUser = DownloadHandler.getDownloadPathForUser(
+ mFragment.getActivity(), downloadPath);
+ downloadPathPreset.setSummary(downloadPathForUser);
+ }
+
+ return;
+ }
+ }
+ return;
+ }
+
+ void updateListPreferenceSummary(ListPreference e) {
+ e.setSummary(e.getEntry());
+ }
+
+ /*
+ * We need to set the PreferenceScreen state in onResume(), as the number of
+ * origins with active features (WebStorage, Geolocation etc) could have
+ * changed after calling the WebsiteSettingsActivity.
+ */
+ public void onResume() {
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object objValue) {
+ if (mFragment.getActivity() == null) {
+ // We aren't attached, so don't accept preferences changes from the
+ // invisible UI.
+ Log.w("PageContentPreferencesFragment", "onPreferenceChange called from detached fragment!");
+ return false;
+ }
+ if(pref.getKey().equals("edge_swiping_action")){
+ ListPreference lp = (ListPreference) pref;
+ lp.setValue((String) objValue);
+ updateListPreferenceSummary(lp);
+ return true;
+ }
+
+ else if (pref.getKey().equals(PreferenceKeys.PREF_RESET_DEFAULT_PREFERENCES)) {
+ Integer value = (Integer) objValue;
+ if (value.intValue() != BrowserYesNoPreference.CANCEL_BTN) {
+ BrowserSettings settings = BrowserSettings.getInstance();
+ if (value.intValue() == BrowserYesNoPreference.OTHER_BTN) {
+ settings.clearCache();
+ settings.clearDatabases();
+ settings.clearCookies();
+ settings.clearHistory();
+ settings.clearFormData();
+ settings.clearPasswords();
+ settings.clearLocationAccess();
+ }
+
+ settings.resetDefaultPreferences();
+ mFragment.startActivity(new Intent(BrowserActivity.ACTION_RESTART, null,
+ mFragment.getActivity(), BrowserActivity.class));
+ return true;
+ }
+
+ } else if (pref.getKey().equals(PreferenceKeys.PREF_SEARCH_ENGINE)) {
+ ListPreference lp = (ListPreference) pref;
+ lp.setValue((String) objValue);
+ updateListPreferenceSummary(lp);
+ return false;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ FragmentManager fragmentManager = mFragment.getFragmentManager();
+
+ if (preference.getKey().equals(PreferenceKeys.PREF_DEBUG_MENU)) {
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ Fragment newFragment = new DebugPreferencesFragment();
+ fragmentTransaction.replace(mFragment.getId(), newFragment);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ return true;
+ } else if (preference.getKey().equals("accessibility_menu")) {
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ Fragment newFragment = new AccessibilityPreferencesFragment();
+ fragmentTransaction.replace(mFragment.getId(), newFragment);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ return true;
+ } else if (preference.getKey().equals("privacy_security")) {
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ Fragment newFragment = new PrivacySecurityPreferencesFragment();
+ fragmentTransaction.replace(mFragment.getId(), newFragment);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ return true;
+ } else if (preference.getKey().equals("content_settings")) {
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ Fragment newFragment = new ContentPreferencesFragment();
+ fragmentTransaction.replace(mFragment.getId(), newFragment);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/src/com/android/browser/preferences/BandwidthPreferencesFragment.java b/src/src/com/android/browser/preferences/BandwidthPreferencesFragment.java
new file mode 100644
index 00000000..0cb064ab
--- /dev/null
+++ b/src/src/com/android/browser/preferences/BandwidthPreferencesFragment.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.browser.preferences;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+
+import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+
+public class BandwidthPreferencesFragment extends PreferenceFragment {
+
+ static final String TAG = "BandwidthPreferencesFragment";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Load the XML preferences file
+ addPreferencesFromResource(R.xml.bandwidth_preferences);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ PreferenceScreen prefScreen = getPreferenceScreen();
+ SharedPreferences sharedPrefs = prefScreen.getSharedPreferences();
+ if (!sharedPrefs.contains(PreferenceKeys.PREF_DATA_PRELOAD)) {
+ // set default value for preload setting
+ ListPreference preload = (ListPreference) prefScreen.findPreference(
+ PreferenceKeys.PREF_DATA_PRELOAD);
+ if (preload != null) {
+ preload.setValue(BrowserSettings.getInstance().getDefaultPreloadSetting());
+ }
+ }
+ if (!sharedPrefs.contains(PreferenceKeys.PREF_LINK_PREFETCH)) {
+ // set default value for link prefetch setting
+ ListPreference prefetch = (ListPreference) prefScreen.findPreference(
+ PreferenceKeys.PREF_LINK_PREFETCH);
+ if (prefetch != null) {
+ prefetch.setValue(BrowserSettings.getInstance().getDefaultLinkPrefetchSetting());
+ }
+ }
+ }
+
+}
diff --git a/src/src/com/android/browser/preferences/ContentPreferencesFragment.java b/src/src/com/android/browser/preferences/ContentPreferencesFragment.java
new file mode 100644
index 00000000..63bae5b9
--- /dev/null
+++ b/src/src/com/android/browser/preferences/ContentPreferencesFragment.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceScreen;
+import android.text.TextUtils;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.browser.BrowserConfig;
+import com.android.browser.BrowserSettings;
+import com.android.browser.DownloadHandler;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+
+public class ContentPreferencesFragment extends SWEPreferenceFragment {
+ public static final int DOWNLOAD_PATH_RESULT_CODE = 1;
+ private final static String LOGTAG = "ContentPreferences";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the XML preferences file
+ addPreferencesFromResource(R.xml.content_preferences);
+
+ PreferenceScreen screen = (PreferenceScreen) findPreference("content_settings");
+
+ if (!BrowserConfig.getInstance(getActivity().getApplicationContext())
+ .hasFeature(BrowserConfig.Feature.CUSTOM_DOWNLOAD_PATH)) {
+ screen.removePreference(findPreference(PreferenceKeys.PREF_DOWNLOAD_PATH));
+ } else {
+ PreferenceScreen downloadPathPreset =
+ (PreferenceScreen) findPreference(PreferenceKeys.PREF_DOWNLOAD_PATH);
+ downloadPathPreset.setOnPreferenceClickListener(onClickDownloadPathSettings());
+
+ String downloadPath = downloadPathPreset.getSharedPreferences().
+ getString(PreferenceKeys.PREF_DOWNLOAD_PATH,
+ BrowserSettings.getInstance().getDownloadPath());
+ String downloadPathForUser = DownloadHandler.getDownloadPathForUser(getActivity(),
+ downloadPath);
+ downloadPathPreset.setSummary(downloadPathForUser);
+ }
+ }
+
+ private Preference.OnPreferenceClickListener onClickDownloadPathSettings() {
+ return new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ final String filemanagerIntent =
+ getResources().getString(R.string.def_intent_file_manager);
+ if (!TextUtils.isEmpty(filemanagerIntent)) {
+ try {
+ Intent i = new Intent(filemanagerIntent);
+ startActivityForResult(i,
+ DOWNLOAD_PATH_RESULT_CODE);
+ } catch (Exception e) {
+ String err_msg = getResources().getString(
+ R.string.activity_not_found,
+ filemanagerIntent);
+ Toast.makeText(getActivity(), err_msg, Toast.LENGTH_LONG).show();
+ }
+ return true;
+ } else {
+ Log.e(LOGTAG, "File Manager intent not defined !!");
+ return true;
+ }
+ }
+ };
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ ActionBar bar = getActivity().getActionBar();
+ if (bar != null) {
+ bar.setTitle(R.string.pref_content_title);
+ bar.setDisplayHomeAsUpEnabled(false);
+ bar.setHomeButtonEnabled(false);
+ }
+ }
+}
diff --git a/src/src/com/android/browser/preferences/DebugPreferencesFragment.java b/src/src/com/android/browser/preferences/DebugPreferencesFragment.java
new file mode 100644
index 00000000..2283fb6a
--- /dev/null
+++ b/src/src/com/android/browser/preferences/DebugPreferencesFragment.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.SwitchPreference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.Preference.OnPreferenceChangeListener;
+
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+
+import org.codeaurora.swe.PermissionsServiceFactory;
+
+public class DebugPreferencesFragment extends SWEPreferenceFragment
+ implements OnPreferenceClickListener, OnPreferenceChangeListener {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the XML preferences file
+ addPreferencesFromResource(R.xml.debug_preferences);
+
+ SwitchPreference pref = (SwitchPreference) findPreference(PreferenceKeys.PREF_DISABLE_PERF);
+ pref.setOnPreferenceChangeListener(this);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object objValue) {
+ if (getActivity() == null) {
+ return false;
+ }
+
+ if (pref.getKey().equals(PreferenceKeys.PREF_DISABLE_PERF)) {
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.WEBREFINER, (Boolean)objValue);
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ return false;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ ActionBar bar = getActivity().getActionBar();
+ if (bar != null) {
+ bar.setTitle(R.string.pref_development_title);
+ bar.setDisplayHomeAsUpEnabled(false);
+ bar.setHomeButtonEnabled(false);
+ }
+ }
+}
diff --git a/src/src/com/android/browser/preferences/FontSizePreview.java b/src/src/com/android/browser/preferences/FontSizePreview.java
new file mode 100644
index 00000000..67d0bd7b
--- /dev/null
+++ b/src/src/com/android/browser/preferences/FontSizePreview.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser.preferences;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import com.android.browser.BrowserSettings;
+import com.android.browser.R;
+
+import org.codeaurora.swe.WebSettings;
+
+public class FontSizePreview extends WebViewPreview {
+
+ //default size for normal sized preview text
+ static final int DEFAULT_FONT_PREVIEW_SIZE = 13;
+
+ public FontSizePreview(
+ Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public FontSizePreview(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public FontSizePreview(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void updatePreview(boolean forceReload) {
+ if (mWebView == null || mTextView == null)
+ return;
+
+ WebSettings ws = mWebView.getSettings();
+ BrowserSettings bs = BrowserSettings.getInstance();
+ ws.setMinimumFontSize(bs.getMinimumFontSize());
+ ws.setTextZoom(bs.getTextZoom());
+ mTextView.setText(R.string.pref_sample_font_size);
+ mTextView.setTextSize(DEFAULT_FONT_PREVIEW_SIZE * bs.getTextZoom() / 100);
+ }
+}
diff --git a/src/src/com/android/browser/preferences/GeneralPreferencesFragment.java b/src/src/com/android/browser/preferences/GeneralPreferencesFragment.java
new file mode 100644
index 00000000..9f610617
--- /dev/null
+++ b/src/src/com/android/browser/preferences/GeneralPreferencesFragment.java
@@ -0,0 +1,393 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceScreen;
+import android.preference.SwitchPreference;
+import android.text.InputType;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.WindowManager;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.TextView.OnEditorActionListener;
+import android.widget.Toast;
+
+import com.android.browser.AutoFillSettingsFragment;
+import com.android.browser.BrowserPreferencesPage;
+import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+import com.android.browser.UrlUtils;
+import com.android.browser.homepages.HomeProvider;
+import com.android.browser.mdm.AutoFillRestriction;
+import com.android.browser.mdm.SearchEngineRestriction;
+
+import org.codeaurora.swe.PermissionsServiceFactory;
+
+public class GeneralPreferencesFragment extends SWEPreferenceFragment
+ implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener {
+
+ static final String TAG = "GeneralPreferencesFragment";
+
+ public static final String EXTRA_CURRENT_PAGE = "currentPage";
+
+ static final String BLANK_URL = "about:blank";
+ static final String CURRENT = "current";
+ static final String BLANK = "blank";
+ static final String DEFAULT = "default";
+ static final String MOST_VISITED = "most_visited";
+ static final String OTHER = "other";
+
+ static final String PREF_HOMEPAGE_PICKER = "homepage_picker";
+ static final String PREF_POWERSAVE = "powersave_enabled";
+
+ String[] mChoices, mValues;
+ String mCurrentPage;
+
+ AdvancedPreferencesFragment mAdvFrag = null;
+ PrivacySecurityPreferencesFragment mPrivFrag = null;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Resources res = getActivity().getResources();
+ mChoices = res.getStringArray(R.array.pref_homepage_choices);
+ mValues = res.getStringArray(R.array.pref_homepage_values);
+ mCurrentPage = getActivity().getIntent().getStringExtra(EXTRA_CURRENT_PAGE);
+
+ // Load the XML preferences file
+ addPreferencesFromResource(R.xml.general_preferences);
+
+ ListPreference pref = (ListPreference) findPreference(PREF_HOMEPAGE_PICKER);
+ pref.setSummary(getHomepageSummary());
+ pref.setPersistent(false);
+ pref.setValue(getHomepageValue());
+ pref.setOnPreferenceChangeListener(this);
+
+ PreferenceScreen autofill = (PreferenceScreen) findPreference(
+ PreferenceKeys.PREF_AUTOFILL_PROFILE);
+ autofill.setOnPreferenceClickListener(this);
+
+ SwitchPreference powersave = (SwitchPreference) findPreference(PREF_POWERSAVE);
+ powersave.setOnPreferenceChangeListener(this);
+
+ SwitchPreference nightmode = (SwitchPreference) findPreference(
+ PreferenceKeys.PREF_NIGHTMODE_ENABLED);
+ nightmode.setOnPreferenceChangeListener(this);
+
+ final Bundle arguments = getArguments();
+ if (arguments != null && arguments.getBoolean("LowPower")) {
+ LowPowerDialogFragment fragment = LowPowerDialogFragment.newInstance();
+ fragment.show(getActivity().getFragmentManager(), "setPowersave dialog");
+ }
+
+ //Disable set search engine preference if SEARCH_ENGINE restriction is enabled
+ if (SearchEngineRestriction.getInstance().isEnabled()) {
+ findPreference("search_engine").setEnabled(false);
+ }
+
+ // Register Preference objects with their MDM restriction handlers
+ AutoFillRestriction.getInstance().
+ registerPreference(findPreference(PreferenceKeys.PREF_AUTOFILL_ENABLED));
+
+ mAdvFrag = new AdvancedPreferencesFragment(this);
+ //mPrivFrag = new PrivacySecurityPreferencesFragment(this);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ // Un-register Preference objects from their MDM restriction handlers
+ AutoFillRestriction.getInstance().registerPreference(null);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object objValue) {
+ if (getActivity() == null) {
+ // We aren't attached, so don't accept preferences changes from the
+ // invisible UI.
+ Log.w("PageContentPreferencesFragment", "onPreferenceChange called from detached fragment!");
+ return false;
+ }
+
+ if (pref.getKey().equals(PREF_HOMEPAGE_PICKER)) {
+ BrowserSettings settings = BrowserSettings.getInstance();
+ if (CURRENT.equals(objValue)) {
+ settings.setHomePage(mCurrentPage);
+ }
+ if (BLANK.equals(objValue)) {
+ settings.setHomePage(BLANK_URL);
+ }
+ if (DEFAULT.equals(objValue)) {
+ settings.setHomePage(BrowserSettings.getFactoryResetHomeUrl(
+ getActivity()));
+ }
+ if (MOST_VISITED.equals(objValue)) {
+ settings.setHomePage(HomeProvider.MOST_VISITED);
+ }
+ if (OTHER.equals(objValue)) {
+ promptForHomepage();
+ return false;
+ }
+ pref.setSummary(getHomepageSummary());
+ ((ListPreference)pref).setValue(getHomepageValue());
+ return false;
+ }
+
+ if (pref.getKey().equals(PREF_POWERSAVE)) {
+ BrowserSettings settings = BrowserSettings.getInstance();
+ settings.setPowerSaveModeEnabled((Boolean)objValue);
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.WEBREFINER, !(Boolean)objValue);
+ showPowerSaveInfo((Boolean) objValue);
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ }
+
+ if (pref.getKey().equals(PreferenceKeys.PREF_NIGHTMODE_ENABLED)) {
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ }
+ return true;
+ }
+
+ void promptForHomepage() {
+ MyAlertDialogFragment fragment = MyAlertDialogFragment.newInstance();
+ fragment.setTargetFragment(this, -1);
+ fragment.show(getActivity().getFragmentManager(), "setHomepage dialog");
+ }
+
+ String getHomepageValue() {
+ BrowserSettings settings = BrowserSettings.getInstance();
+ String homepage = settings.getHomePage();
+ if (TextUtils.isEmpty(homepage) || BLANK_URL.endsWith(homepage)) {
+ return BLANK;
+ }
+ if (HomeProvider.MOST_VISITED.equals(homepage)) {
+ return MOST_VISITED;
+ }
+ String defaultHomepage = BrowserSettings.getFactoryResetHomeUrl(
+ getActivity());
+ if (TextUtils.equals(defaultHomepage, homepage)) {
+ return DEFAULT;
+ }
+ if (TextUtils.equals(mCurrentPage, homepage)) {
+ return CURRENT;
+ }
+ return OTHER;
+ }
+
+ String getHomepageSummary() {
+ BrowserSettings settings = BrowserSettings.getInstance();
+ if (settings.useMostVisitedHomepage()) {
+ return getHomepageLabel(MOST_VISITED);
+ }
+ String homepage = settings.getHomePage();
+ if (TextUtils.isEmpty(homepage) || BLANK_URL.equals(homepage)) {
+ return getHomepageLabel(BLANK);
+ }
+ return homepage;
+ }
+
+ String getHomepageLabel(String value) {
+ for (int i = 0; i < mValues.length; i++) {
+ if (value.equals(mValues[i])) {
+ return mChoices[i];
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ mAdvFrag.onResume();
+ refreshUi();
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ mAdvFrag.onActivityResult(requestCode,resultCode, data);
+ }
+
+ void refreshUi() {
+ ActionBar bar = getActivity().getActionBar();
+ if (bar != null) {
+ bar.setTitle(R.string.menu_preferences);
+ bar.setDisplayHomeAsUpEnabled(true);
+ }
+
+ PreferenceScreen autoFillSettings =
+ (PreferenceScreen)findPreference(PreferenceKeys.PREF_AUTOFILL_PROFILE);
+ autoFillSettings.setDependency(PreferenceKeys.PREF_AUTOFILL_ENABLED);
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ if (preference.getKey().equals(PreferenceKeys.PREF_AUTOFILL_PROFILE)) {
+ FragmentManager fragmentManager = getFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ Fragment newFragment = new AutoFillSettingsFragment();
+ fragmentTransaction.replace(getId(), newFragment);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ return true;
+ }
+ return false;
+ }
+
+ void showPowerSaveInfo(boolean toggle) {
+ String toastInfo;
+ if (toggle)
+ toastInfo = getActivity().getResources().getString(R.string.powersave_dialog_on);
+ else
+ toastInfo = getActivity().getResources().getString(R.string.powersave_dialog_off);
+
+ Toast toast = Toast.makeText(getActivity(), toastInfo, Toast.LENGTH_SHORT);
+ toast.setGravity(Gravity.CENTER, 0, 0);
+ toast.show();
+ }
+
+ /*
+ Add this class to manage AlertDialog lifecycle.
+ */
+ public static class MyAlertDialogFragment extends DialogFragment {
+ private final String HOME_PAGE = "homepage";
+ private EditText editText = null;
+ public static MyAlertDialogFragment newInstance() {
+ MyAlertDialogFragment frag = new MyAlertDialogFragment();
+ return frag;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final BrowserSettings settings = BrowserSettings.getInstance();
+ editText = new EditText(getActivity());
+ String homePage = savedInstanceState != null ?
+ savedInstanceState.getString(HOME_PAGE): settings.getHomePage();
+ editText.setInputType(InputType.TYPE_CLASS_TEXT
+ | InputType.TYPE_TEXT_VARIATION_URI);
+ editText.setText(homePage);
+ editText.setSelectAllOnFocus(true);
+ editText.setSingleLine(true);
+ editText.setImeActionLabel(null, EditorInfo.IME_ACTION_DONE);
+ final AlertDialog dialog = new AlertDialog.Builder(getActivity())
+ .setView(editText)
+ .setPositiveButton(android.R.string.ok, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String homepage = editText.getText().toString().trim();
+ homepage = UrlUtils.smartUrlFilter(homepage);
+ settings.setHomePage(homepage);
+ Fragment frag = getTargetFragment();
+ if (frag == null || !(frag instanceof GeneralPreferencesFragment)) {
+ Log.e("MyAlertDialogFragment", "get target fragment error!");
+ return;
+ }
+ GeneralPreferencesFragment target = (GeneralPreferencesFragment)frag;
+ ListPreference pref = (ListPreference) target.
+ findPreference(PREF_HOMEPAGE_PICKER);
+ pref.setValue(target.getHomepageValue());
+ pref.setSummary(target.getHomepageSummary());
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ })
+ .setTitle(R.string.pref_set_homepage_to)
+ .create();
+
+ editText.setOnEditorActionListener(new OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_DONE) {
+ dialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick();
+ return true;
+ }
+ return false;
+ }
+ });
+
+ dialog.getWindow().setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+
+ return dialog;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState){
+ super.onSaveInstanceState(outState);
+ outState.putString(HOME_PAGE, editText.getText().toString().trim());
+ }
+ }
+ public static class LowPowerDialogFragment extends DialogFragment {
+ public static LowPowerDialogFragment newInstance() {
+ LowPowerDialogFragment frag = new LowPowerDialogFragment();
+ return frag;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final BrowserSettings settings = BrowserSettings.getInstance();
+ final AlertDialog dialog = new AlertDialog.Builder(getActivity())
+ .setPositiveButton(android.R.string.ok, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ settings.setPowerSaveModeEnabled(true);
+ getActivity().finish();
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ getActivity().finish();
+ }
+ })
+ .setTitle(R.string.pref_powersave_enabled_summary)
+ .create();
+
+ dialog.getWindow().setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+
+ return dialog;
+ }
+ }
+}
diff --git a/src/src/com/android/browser/preferences/InvertedContrastPreview.java b/src/src/com/android/browser/preferences/InvertedContrastPreview.java
new file mode 100644
index 00000000..690a529a
--- /dev/null
+++ b/src/src/com/android/browser/preferences/InvertedContrastPreview.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser.preferences;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import org.codeaurora.swe.WebSettings;
+import org.codeaurora.swe.WebView;
+
+import com.android.browser.BrowserSettings;
+import com.android.browser.BrowserWebView;
+import com.android.browser.WebViewProperties;
+
+public class InvertedContrastPreview extends WebViewPreview {
+
+ static final String IMG_ROOT = "content://com.android.browser.home/res/raw/";
+ static final String[] THUMBS = new String[] {
+ "thumb_google",
+ "thumb_amazon",
+ "thumb_cnn",
+ "thumb_espn",
+ "", // break
+ "thumb_bbc",
+ "thumb_nytimes",
+ "thumb_weatherchannel",
+ "thumb_picasa",
+ };
+
+ String mHtml;
+
+ public InvertedContrastPreview(
+ Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public InvertedContrastPreview(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public InvertedContrastPreview(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void init(Context context) {
+ super.init(context);
+ StringBuilder builder = new StringBuilder("<html><body style=\"width: 1000px\">");
+ for (String thumb : THUMBS) {
+ if (TextUtils.isEmpty(thumb)) {
+ builder.append("<br />");
+ continue;
+ }
+ builder.append("<img src=\"");
+ builder.append(IMG_ROOT);
+ builder.append(thumb);
+ builder.append("\" />&nbsp;");
+ }
+ builder.append("</body></html>");
+ mHtml = builder.toString();
+ }
+
+ @Override
+ protected void updatePreview(boolean forceReload) {
+ if (mWebView == null) return;
+
+ /* SWE: This class extends WebViewPreview, however, WebViewPreview has
+ * been modified to use the system webview. Commenting out code for now
+ * which implements the preview as this class requires refactoring
+ * regardless & is currently not in use.
+
+ WebSettings ws = mWebView.getSettings();
+ BrowserSettings bs = BrowserSettings.getInstance();
+ ws.setProperty(WebViewProperties.gfxInvertedScreen,
+ bs.useInvertedRendering() ? "true" : "false");
+ ws.setProperty(WebViewProperties.gfxInvertedScreenContrast,
+ Float.toString(bs.getInvertedContrast()));
+ if (forceReload) {
+ mWebView.loadData(mHtml, "text/html", null);
+ }
+
+ */
+ }
+
+}
diff --git a/src/src/com/android/browser/preferences/LegalPreferencesFragment.java b/src/src/com/android/browser/preferences/LegalPreferencesFragment.java
new file mode 100644
index 00000000..ea3fb17b
--- /dev/null
+++ b/src/src/com/android/browser/preferences/LegalPreferencesFragment.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
+
+import com.android.browser.BrowserSwitches;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+
+import org.codeaurora.swe.BrowserCommandLine;
+
+public class LegalPreferencesFragment extends PreferenceFragment
+ implements OnPreferenceClickListener {
+
+ private static final String creditsUrl = "chrome://credits";
+ PreferenceScreen mHeadPref = null;
+ String mEulaUrl = "";
+ String mPrivacyPolicyUrl = "";
+
+ private void setOnClickListener(String prefKey, boolean set) {
+ Preference pref = findPreference(prefKey);
+ if (pref == null) {
+ return;
+ }
+
+ if (set) {
+ pref.setOnPreferenceClickListener(this);
+ } else {
+ if (mHeadPref != null)
+ mHeadPref.removePreference(pref);
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ActionBar bar = getActivity().getActionBar();
+ if (bar != null) {
+ bar.setTitle(R.string.swe_legal);
+ }
+ addPreferencesFromResource(R.xml.legal_preferences);
+ mHeadPref = (PreferenceScreen) findPreference(PreferenceKeys.PREF_LEGAL);
+
+
+ setOnClickListener(PreferenceKeys.PREF_LEGAL_CREDITS, true);
+
+ if(BrowserCommandLine.hasSwitch(BrowserSwitches.CMD_LINE_SWITCH_EULA_URL)) {
+ mEulaUrl = BrowserCommandLine.getSwitchValue(BrowserSwitches.CMD_LINE_SWITCH_EULA_URL);
+ } else {
+ mEulaUrl = getResources().getString(R.string.swe_eula_url);
+ }
+ setOnClickListener(PreferenceKeys.PREF_LEGAL_EULA, !mEulaUrl.isEmpty());
+
+
+ if(BrowserCommandLine.hasSwitch(BrowserSwitches.CMD_LINE_SWITCH_PRIVACY_POLICY_URL)) {
+ mPrivacyPolicyUrl = BrowserCommandLine.getSwitchValue(
+ BrowserSwitches.CMD_LINE_SWITCH_PRIVACY_POLICY_URL);
+ } else {
+ mPrivacyPolicyUrl = getResources().getString(R.string.swe_privacy_policy_url);
+ }
+ setOnClickListener(PreferenceKeys.PREF_LEGAL_PRIVACY_POLICY, !mPrivacyPolicyUrl.isEmpty());
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ Bundle b = new Bundle();
+ if(preference.getKey().equals(PreferenceKeys.PREF_LEGAL_CREDITS)) {
+ Intent i = new Intent(getActivity(), LegalPreviewActivity.class);
+ i.putExtra(LegalPreviewActivity.URL_INTENT_EXTRA, creditsUrl);
+ startActivity(i);
+ return true;
+ } else if(preference.getKey().equals(PreferenceKeys.PREF_LEGAL_EULA)) {
+ Intent i = new Intent(getActivity(), LegalPreviewActivity.class);
+ i.putExtra(LegalPreviewActivity.URL_INTENT_EXTRA, mEulaUrl);
+ startActivity(i);
+ return true;
+ } else if(preference.getKey().equals(PreferenceKeys.PREF_LEGAL_PRIVACY_POLICY)) {
+ Intent i = new Intent(getActivity(), LegalPreviewActivity.class);
+ i.putExtra(LegalPreviewActivity.URL_INTENT_EXTRA, mPrivacyPolicyUrl);
+ startActivity(i);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/src/com/android/browser/preferences/LegalPreviewActivity.java b/src/src/com/android/browser/preferences/LegalPreviewActivity.java
new file mode 100644
index 00000000..eeaf5589
--- /dev/null
+++ b/src/src/com/android/browser/preferences/LegalPreviewActivity.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.support.v4.app.FragmentActivity;
+import android.view.KeyEvent;
+import android.view.MenuItem;
+
+import com.android.browser.R;
+
+public class LegalPreviewActivity extends FragmentActivity {
+ LegalPreviewFragment mLegalPreviewFragment;
+ protected static final String URL_INTENT_EXTRA = "url";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.credits_tab);
+ ActionBar bar = getActionBar();
+ if (bar != null) {
+ bar.setTitle(R.string.swe_open_source_licenses);
+ bar.setDisplayHomeAsUpEnabled(true);
+ }
+ FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
+ mLegalPreviewFragment = new LegalPreviewFragment();
+ Bundle args = new Bundle();
+ args.putString(URL_INTENT_EXTRA, getIntent().getExtras()
+ .getString(URL_INTENT_EXTRA));
+ mLegalPreviewFragment.setArguments(args);
+ fragmentTransaction.add(R.id.license_layout, mLegalPreviewFragment,
+ "LegalPreviewFragmentTag");
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ }
+
+ private boolean back() {
+ if(!mLegalPreviewFragment.onBackPressed()) {
+ onBackPressed();
+ return true;
+ } else {
+ return false;
+ }
+ }
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ switch(keyCode) {
+ case KeyEvent.KEYCODE_BACK:
+ if (event.isTracking() && !event.isCanceled()) {
+ return back();
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ return back();
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/src/src/com/android/browser/preferences/LegalPreviewFragment.java b/src/src/com/android/browser/preferences/LegalPreviewFragment.java
new file mode 100644
index 00000000..ec60e10c
--- /dev/null
+++ b/src/src/com/android/browser/preferences/LegalPreviewFragment.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015 The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+package com.android.browser.preferences;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.android.browser.R;
+
+import org.codeaurora.swe.WebView;
+
+public class LegalPreviewFragment extends Fragment {
+
+ private WebView mWebView;
+ private String mUrl;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Bundle args = getArguments();
+ mUrl = args.getString(LegalPreviewActivity.URL_INTENT_EXTRA);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ ViewGroup contentContainer = (ViewGroup) inflater.inflate(
+ R.layout.webview_wrapper, container, false);
+ FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT);
+ mWebView = new WebView(getActivity());
+ contentContainer.addView(mWebView.getView(), params);
+ return contentContainer;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle b) {
+ super.onActivityCreated(b);
+ if (mWebView == null) return;
+ mWebView.loadUrl(mUrl);
+ }
+
+ public boolean onBackPressed() {
+ if(mWebView != null && mWebView.canGoBack()) {
+ mWebView.goBack();
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/src/com/android/browser/preferences/NonformattingListPreference.java b/src/src/com/android/browser/preferences/NonformattingListPreference.java
new file mode 100644
index 00000000..51b3231e
--- /dev/null
+++ b/src/src/com/android/browser/preferences/NonformattingListPreference.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.browser.preferences;
+
+import android.content.Context;
+import android.preference.ListPreference;
+import android.util.AttributeSet;
+
+public class NonformattingListPreference extends ListPreference {
+
+ private CharSequence mSummary;
+
+ public NonformattingListPreference(Context context) {
+ super(context);
+ }
+
+ public NonformattingListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public void setSummary(CharSequence summary) {
+ mSummary = summary;
+ super.setSummary(summary);
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ if (mSummary != null) {
+ return mSummary;
+ }
+ return super.getSummary();
+ }
+
+}
diff --git a/src/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java b/src/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
new file mode 100644
index 00000000..d038163f
--- /dev/null
+++ b/src/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.browser.preferences;
+
+import com.android.browser.BrowserLocationSwitchPreference;
+import com.android.browser.BrowserPreferencesPage;
+import com.android.browser.BrowserSettings;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+import com.android.browser.mdm.DoNotTrackRestriction;
+import com.android.browser.mdm.ThirdPartyCookiesRestriction;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.preference.TwoStatePreference;
+
+import org.codeaurora.swe.PermissionsServiceFactory;
+import org.codeaurora.swe.WebRefiner;
+
+public class PrivacySecurityPreferencesFragment extends SWEPreferenceFragment
+ implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener {
+
+ private Preference mClearPref;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.privacy_and_security_preferences);
+
+ PreferenceScreen websiteSettings = (PreferenceScreen) findPreference(
+ PreferenceKeys.PREF_WEBSITE_SETTINGS);
+ websiteSettings.setFragment(WebsiteSettingsFragment.class.getName());
+ websiteSettings.setOnPreferenceClickListener(this);
+
+ mClearPref = findPreference(PreferenceKeys.PREF_CLEAR_SELECTED_DATA);
+ mClearPref.setOnPreferenceChangeListener(this);
+
+ readAndShowPermission("enable_geolocation",
+ PermissionsServiceFactory.PermissionType.GEOLOCATION);
+
+ readAndShowPermission("microphone", PermissionsServiceFactory.PermissionType.VOICE);
+
+ readAndShowPermission("camera", PermissionsServiceFactory.PermissionType.VIDEO);
+
+ Preference pref = findPreference("distracting_contents");
+ if (!BrowserSettings.getInstance().getPreferences()
+ .getBoolean(PreferenceKeys.PREF_WEB_REFINER, false)) {
+ PreferenceCategory category =
+ (PreferenceCategory) findPreference("default_site_settings");
+ if (category != null) {
+ category.removePreference(pref);
+ }
+ } else {
+ // since webrefiner and distracting_contents are paradoxes
+ // the value needs to be flipped
+ pref.setOnPreferenceChangeListener(this);
+ showPermission(pref,
+ !PermissionsServiceFactory.getDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.WEBREFINER));
+ }
+
+ readAndShowPermission("popup_windows", PermissionsServiceFactory.PermissionType.POPUP);
+
+ readAndShowPermission("accept_cookies", PermissionsServiceFactory.PermissionType.COOKIE);
+
+ readAndShowPermission("accept_third_cookies",
+ PermissionsServiceFactory.PermissionType.THIRDPARTYCOOKIES);
+
+ // Register Preference objects with their MDM restriction handlers
+ DoNotTrackRestriction.getInstance().
+ registerPreference(findPreference(PreferenceKeys.PREF_DO_NOT_TRACK));
+ ThirdPartyCookiesRestriction.getInstance().
+ registerPreference(findPreference("accept_third_cookies"));
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ // Un-register Preference objects from their MDM restriction handlers
+ DoNotTrackRestriction.getInstance().registerPreference(null);
+ ThirdPartyCookiesRestriction.getInstance().registerPreference(null);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ PermissionsServiceFactory.flushPendingSettings();
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ FragmentManager fragmentManager = getFragmentManager();
+
+ if (preference.getKey().equals(PreferenceKeys.PREF_WEBSITE_SETTINGS)) {
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ Fragment newFragment = new WebsiteSettingsFragment();
+ fragmentTransaction.replace(getId(), newFragment);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object objValue) {
+ boolean flag = true;
+ if (pref == mClearPref) {
+ Integer value = (Integer) objValue;
+ if (value == 0) {
+ return false;
+ }
+ } else {
+ Boolean bFlag = (Boolean) objValue;
+ flag = bFlag.booleanValue();
+ }
+
+ if (pref.getKey().equals(PreferenceKeys.PREF_CLEAR_SELECTED_DATA)) {
+ if (pref.getPreferenceManager().getDefaultSharedPreferences(
+ (Context) getActivity()).getBoolean(
+ PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY, false)) {
+ // Need to tell the browser to remove the parent/child relationship
+ // between tabs
+ getActivity().setResult(Activity.RESULT_OK,
+ (new Intent()).putExtra(Intent.EXTRA_TEXT, pref.getKey()));
+ }
+ // return true by default for all preferences
+ return true;
+ }
+
+ if (pref.getKey().toString().equalsIgnoreCase("enable_geolocation")) {
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.GEOLOCATION, flag);
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ return true;
+ }
+
+ if (pref.getKey().toString().equalsIgnoreCase("microphone")) {
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.VOICE, flag);
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ return true;
+ }
+
+ if (pref.getKey().toString().equalsIgnoreCase("camera")) {
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.VIDEO, flag);
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ return true;
+ }
+
+ if (pref.getKey().toString().equalsIgnoreCase("distracting_contents")) {
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.WEBREFINER, !flag);
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ return true;
+ }
+
+ if (pref.getKey().toString().equalsIgnoreCase("popup_windows")) {
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.POPUP, flag);
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ return true;
+ }
+
+ if (pref.getKey().toString().equalsIgnoreCase("accept_cookies")) {
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.COOKIE, flag);
+
+ if (!flag) {
+ // Disable third party cookies as well
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.THIRDPARTYCOOKIES, flag);
+ showPermission(findPreference("accept_third_cookies"), flag);
+ }
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ return true;
+ }
+
+ if (pref.getKey().toString().equalsIgnoreCase("accept_third_cookies")) {
+ PermissionsServiceFactory.setDefaultPermissions(
+ PermissionsServiceFactory.PermissionType.THIRDPARTYCOOKIES, flag);
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ return true;
+ }
+
+ return false;
+ }
+
+ private void readAndShowPermission(CharSequence key,
+ PermissionsServiceFactory.PermissionType type) {
+ Preference pref = findPreference(key);
+ pref.setOnPreferenceChangeListener(this);
+ showPermission(pref, PermissionsServiceFactory.getDefaultPermissions(type));
+ }
+
+ private void showPermission(Preference pref, boolean perm) {
+ if (pref instanceof TwoStatePreference) {
+ TwoStatePreference twoStatePreference = (TwoStatePreference) pref;
+ if (twoStatePreference.isChecked() != perm) {
+ twoStatePreference.setChecked(perm);
+ }
+ } else {
+ if (!perm) {
+ pref.setSummary(R.string.pref_security_not_allowed);
+ } else {
+ pref.setSummary(R.string.pref_security_ask_before_using);
+ }
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ ActionBar bar = getActivity().getActionBar();
+ BrowserLocationSwitchPreference pref =
+ (BrowserLocationSwitchPreference) findPreference(PreferenceKeys.PREF_ENABLE_GEOLOCATION);
+ if (bar != null) {
+ bar.setTitle(R.string.pref_privacy_security_title);
+ bar.setDisplayHomeAsUpEnabled(false);
+ bar.setHomeButtonEnabled(false);
+ }
+ if ( pref != null) pref.setEnabled(PermissionsServiceFactory.isSystemLocationEnabled());
+ }
+}
diff --git a/src/src/com/android/browser/preferences/SWEPreferenceFragment.java b/src/src/com/android/browser/preferences/SWEPreferenceFragment.java
new file mode 100644
index 00000000..7bfd0d1e
--- /dev/null
+++ b/src/src/com/android/browser/preferences/SWEPreferenceFragment.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.preference.PreferenceFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.Switch;
+
+import com.android.browser.R;
+
+public abstract class SWEPreferenceFragment extends PreferenceFragment {
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
+ View view = super.onCreateView(inflater, container, bundle);
+
+ ListView list = (ListView) view.findViewById(android.R.id.list);
+
+ if (list == null) {
+ return view;
+ }
+
+ ViewGroup.LayoutParams params = list.getLayoutParams();
+ params.width = ViewGroup.LayoutParams.MATCH_PARENT;
+ list.setLayoutParams(params);
+ list.setPadding(0, list.getPaddingTop(), 0, list.getPaddingBottom());
+ list.setDivider(null);
+ list.setDividerHeight(0);
+
+ list.setOnHierarchyChangeListener(
+ new ViewGroup.OnHierarchyChangeListener() {
+ @Override
+ public void onChildViewAdded(View parent, View child) {
+ onChildViewAddedToHierarchy(parent, child);
+ findAndResizeSwitchPreferenceWidget(child);
+ }
+
+ @Override
+ public void onChildViewRemoved(View parent, View child) {
+ onChildViewRemovedFromHierarchy(parent, child);
+ }
+ }
+ );
+
+ return view;
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ /*ActionBar bar = getActivity().getActionBar();
+ if (bar != null) {
+ bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.accent)));
+ }*/
+ }
+
+ private final void findAndResizeSwitchPreferenceWidget(View parent) {
+ LinearLayout layout = (LinearLayout) parent.findViewById(android.R.id.widget_frame);
+ if (layout != null) {
+ for (int i = 0; i < layout.getChildCount(); i++) {
+ View view = layout.getChildAt(i);
+ if (view instanceof Switch) {
+ Switch switchView = (Switch) view;
+ switchView.setThumbTextPadding(0);
+ int width = switchView.getSwitchMinWidth();
+ switchView.setSwitchMinWidth(width/2);
+ }
+ }
+ }
+ }
+
+ public void onChildViewAddedToHierarchy(View parent, View child) {
+
+ }
+
+ public void onChildViewRemovedFromHierarchy(View parent, View child) {
+
+ }
+}
diff --git a/src/src/com/android/browser/preferences/SeekBarSummaryPreference.java b/src/src/com/android/browser/preferences/SeekBarSummaryPreference.java
new file mode 100644
index 00000000..5cb8ae67
--- /dev/null
+++ b/src/src/com/android/browser/preferences/SeekBarSummaryPreference.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser.preferences;
+
+import android.content.Context;
+
+import com.android.browser.platformsupport.SeekBarPreference;
+
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+
+public class SeekBarSummaryPreference extends SeekBarPreference {
+
+ CharSequence mSummary;
+ TextView mSummaryView;
+
+ public SeekBarSummaryPreference(
+ Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ public SeekBarSummaryPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public SeekBarSummaryPreference(Context context) {
+ super(context);
+ init();
+ }
+
+ void init() {
+ setWidgetLayoutResource(com.android.browser.R.layout.font_size_widget);
+ }
+
+ @Override
+ public void setSummary(CharSequence summary) {
+ mSummary = summary;
+ if (mSummaryView != null) {
+ mSummaryView.setText(mSummary);
+ }
+ }
+
+ @Override
+ public CharSequence getSummary() {
+ return null;
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+ mSummaryView = (TextView) view.findViewById(com.android.browser.R.id.text);
+ if (TextUtils.isEmpty(mSummary)) {
+ mSummaryView.setVisibility(View.GONE);
+ } else {
+ mSummaryView.setVisibility(View.VISIBLE);
+ mSummaryView.setText(mSummary);
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ // Intentionally blank - prevent super.onStartTrackingTouch from running
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ // Intentionally blank - prevent onStopTrackingTouch from running
+ }
+
+}
diff --git a/src/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java b/src/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java
new file mode 100644
index 00000000..b5d748df
--- /dev/null
+++ b/src/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java
@@ -0,0 +1,816 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.http.SslCertificate;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.preference.TwoStatePreference;
+import android.text.Html;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.webkit.ValueCallback;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.browser.BrowserLocationListPreference;
+import com.android.browser.BrowserPreferencesPage;
+import com.android.browser.BrowserSettings;
+import com.android.browser.NavigationBarBase;
+import com.android.browser.PreferenceKeys;
+import com.android.browser.R;
+import com.android.browser.reflect.ReflectHelper;
+
+import org.codeaurora.swe.PermissionsServiceFactory;
+import org.codeaurora.swe.WebRefiner;
+import org.codeaurora.swe.util.ColorUtils;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.Formatter;
+import java.util.List;
+import java.util.Map;
+
+public class SiteSpecificPreferencesFragment extends SWEPreferenceFragment
+ implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
+ View.OnClickListener {
+ public static final String EXTRA_SITE = "website";
+ public static final String EXTRA_ORIGIN = "website_origin";
+ public static final String EXTRA_FAVICON = "website_favicon";
+ public static final String EXTRA_SITE_TITLE = "website_title";
+ public static final String EXTRA_WEB_REFINER_ADS_INFO = "website_refiner_ads_info";
+ public static final String EXTRA_WEB_REFINER_TRACKER_INFO = "website_refiner_tracker_info";
+ public static final String EXTRA_WEB_REFINER_MALWARE_INFO = "website_refiner_malware_info";
+ public static final String EXTRA_SECURITY_CERT = "website_security_cert";
+ public static final String EXTRA_SECURITY_CERT_BAD = "website_security_cert_bad";
+ public static final String EXTRA_SECURITY_CERT_MIXED = "website_security_cert_mixed";
+
+ private PermissionsServiceFactory.PermissionsService.OriginInfo mOriginInfo;
+ private PermissionsServiceFactory.PermissionsService mPermServ;
+ private ActionBar mBar;
+ private List<String> mLocationValues;
+
+ private Preference mSecurityInfoPrefs;
+
+ private boolean mUsingDefaultSettings = true;
+ private int mOriginalActionBarOptions;
+ private int mIconColor = 0;
+
+ private SslCertificate mSslCert;
+ private int mSslState;
+
+ private static class SiteSecurityViewFactory {
+ private class SiteSecurityView {
+ private TextView mTextView;
+ private View mContainer;
+ private String mDisplayText;
+
+ public SiteSecurityView(View parent, int resId, String text) {
+ mContainer = parent.findViewById(resId);
+ mTextView = (TextView) mContainer.findViewById(R.id.security_view_text);
+ mTextView.setText(text);
+ mDisplayText = text;
+ updateVisibility();
+ }
+
+ private void updateVisibility() {
+ if (TextUtils.isEmpty(mDisplayText)) {
+ mContainer.setVisibility(View.GONE);
+ } else {
+ mContainer.setVisibility(View.VISIBLE);
+ }
+ }
+
+ public void setText(String text) {
+ mDisplayText = text;
+ mTextView.setText(mDisplayText);
+ updateVisibility();
+ }
+
+ public void clearText() {
+ mDisplayText = null;
+ updateVisibility();
+ }
+ }
+
+ public enum ViewType{
+ ERROR,
+ WARNING,
+ INFO
+ };
+
+ private Map<ViewType, SiteSecurityView> mViews =
+ new EnumMap<ViewType, SiteSecurityView>(ViewType.class);
+ private Map<ViewType, String> mTexts = new EnumMap<ViewType, String>(ViewType.class);
+
+ private boolean mbEmpty = true;
+
+ public void setText(ViewType type, String text) {
+ mTexts.put(type, text);
+
+ SiteSecurityView view = mViews.get(type);
+ if (view != null) {
+ view.setText(text);
+ }
+
+ mbEmpty = false;
+ }
+
+ public void appendText(ViewType type, String text) {
+ String new_text = mTexts.get(type);
+ if (new_text != null)
+ new_text += text;
+ else
+ new_text = text;
+
+ mTexts.put(type, new_text);
+
+ SiteSecurityView view = mViews.get(type);
+ if (view != null) {
+ view.setText(new_text);
+ }
+
+ mbEmpty = false;
+ }
+
+ public void clearText(ViewType type) {
+ mTexts.remove(type);
+
+ SiteSecurityView view = mViews.get(type);
+ if (view != null) {
+ view.clearText();
+ }
+
+ boolean empty = true;
+ for (Map.Entry<ViewType, String> entry: mTexts.entrySet()) {
+ if (!entry.getValue().isEmpty()) {
+ empty = false;
+ }
+ }
+ mbEmpty = empty;
+ }
+
+ public void setResource(ViewType type, View parent, int resId) {
+ String text = mTexts.get(type);
+ mViews.remove(type);
+ mViews.put(type, new SiteSecurityView(parent, resId, text));
+ }
+ }
+
+ private SiteSecurityViewFactory mSecurityViews;
+
+ private String mOriginText;
+ private String mSiteTitle;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.site_specific_preferences);
+
+ mBar = getActivity().getActionBar();
+
+ mLocationValues = Arrays.asList(
+ getResources().getStringArray(R.array.geolocation_settings_choices));
+
+ mSecurityViews = new SiteSecurityViewFactory();
+
+ Bundle args = getArguments();
+ if (args != null) {
+ mOriginText = args.getString(EXTRA_ORIGIN, null);
+ mSiteTitle = args.getString(EXTRA_SITE_TITLE, null);
+
+ if (mOriginText == null) {
+ mOriginText = args.getString(EXTRA_SITE);
+ }
+ }
+
+ mIconColor = NavigationBarBase.getSiteIconColor(mOriginText);
+
+ PermissionsServiceFactory.getPermissionsService(
+ new ValueCallback<PermissionsServiceFactory.PermissionsService>() {
+ @Override
+ public void onReceiveValue(PermissionsServiceFactory.PermissionsService value) {
+ mPermServ = value;
+ Preference pref = findPreference("site_name");
+
+ pref.setTitle((mSiteTitle != null) ?
+ mSiteTitle :
+ mOriginText);
+
+ try {
+ URL url = new URL(mOriginText);
+ pref.setSummary((mSiteTitle != null) ?
+ mOriginText :
+ "(" + url.getHost() + ")");
+ } catch (MalformedURLException e) {
+ }
+ mOriginInfo = mPermServ.getOriginInfo(mOriginText);
+ setActionBarTitle(PermissionsServiceFactory.getPrettyUrl(mOriginText));
+ updatePreferenceInfo();
+ }
+ }
+ );
+
+ if (!BrowserSettings.getInstance().getPreferences()
+ .getBoolean(PreferenceKeys.PREF_WEB_REFINER, false)) {
+ PreferenceCategory category = (PreferenceCategory) findPreference("site_pref_list");
+ if (category != null) {
+ Preference pref = findPreference("distracting_contents");
+ category.removePreference(pref);
+ }
+ }
+
+ int ads = args.getInt(EXTRA_WEB_REFINER_ADS_INFO, 0);
+ String[] strings = new String[3];
+ int index = 0;
+
+ if (ads > 0) {
+ strings[index++] = getResources().getQuantityString(
+ R.plurals.pref_web_refiner_advertisements, ads, ads);
+ }
+
+ int trackers = args.getInt(EXTRA_WEB_REFINER_TRACKER_INFO, 0);
+ if (trackers > 0) {
+ strings[index++] = getResources().getQuantityString(
+ R.plurals.pref_web_refiner_trackers, trackers, trackers);
+
+ }
+
+ int malware = args.getInt(EXTRA_WEB_REFINER_MALWARE_INFO, 0);
+ if (malware > 0) {
+ strings[index++] = getResources().getQuantityString(
+ R.plurals.pref_web_refiner_malware, malware, malware);
+ }
+
+ if (index > 0) {
+ String[] formats = getResources().getStringArray(R.array.pref_web_refiner_message);
+ Formatter formatter = new Formatter();
+ formatter.format(formats[index - 1], strings[0], strings[1], strings[2]);
+ mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.INFO, formatter.toString());
+ }
+
+ Bundle parcel = args.getParcelable(EXTRA_SECURITY_CERT);
+ mSslCert = (parcel != null) ? SslCertificate.restoreState(parcel) : null;
+
+ if (mSslCert != null) {
+ Preference pref = findPreference("site_security_info");
+ if (pref != null) {
+ pref.setSelectable(true);
+ }
+
+ boolean certBad = args.getBoolean(EXTRA_SECURITY_CERT_BAD, false);
+ boolean certMix = args.getBoolean(EXTRA_SECURITY_CERT_MIXED, false);
+ if (!certBad && !certMix) {
+ final String string = getString(R.string.pref_valid_cert);
+ mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.INFO,
+ string);
+ mSslState = 0;
+ } else if (certMix) {
+ mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.WARNING,
+ getString(R.string.pref_warning_cert));
+ mSslState = 1;
+ } else {
+ mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.ERROR,
+ getString(R.string.pref_invalid_cert));
+ mSslState = 2;
+ }
+ }
+
+ updateSecurityViewVisibility();
+ }
+
+ private AlertDialog.Builder createSslCertificateDialog(Context ctx,
+ SslCertificate certificate) {
+ Object[] params = {ctx};
+ Class[] type = new Class[] {Context.class};
+ View certificateView = (View) ReflectHelper.invokeMethod(certificate,
+ "inflateCertificateView", type, params);
+ Resources res = Resources.getSystem();
+ // load 'android.R.placeholder' via introspection, since it's not a public resource ID
+ int placeholder_id = res.getIdentifier("placeholder", "id", "android");
+ final LinearLayout placeholder =
+ (LinearLayout)certificateView.findViewById(placeholder_id);
+
+ LayoutInflater factory = LayoutInflater.from(ctx);
+ int iconId = R.drawable.ic_cert_trusted;
+ TextView textView;
+
+ switch (mSslState) {
+ case 0:
+ iconId = R.drawable.ic_cert_trusted;
+ LinearLayout table = (LinearLayout)factory.inflate(R.layout.ssl_success, placeholder);
+ textView = (TextView)table.findViewById(R.id.success);
+ textView.setText(R.string.ssl_certificate_is_valid);
+ break;
+ case 1:
+ iconId = R.drawable.ic_cert_untrusted;
+ textView = (TextView) factory.inflate(R.layout.ssl_warning, placeholder, false);
+ textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_sp_level_warning,
+ 0, 0, 0);
+ textView.setText(R.string.ssl_unknown);
+ placeholder.addView(textView);
+ break;
+ case 2:
+ iconId = R.drawable.ic_cert_avoid;
+ textView = (TextView) factory.inflate(R.layout.ssl_warning, placeholder, false);
+ textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_sp_level_severe,
+ 0, 0, 0);
+ textView.setText(R.string.ssl_invalid);
+ placeholder.addView(textView);
+ break;
+ }
+
+ return new AlertDialog.Builder(ctx)
+ .setTitle(R.string.ssl_certificate)
+ .setIcon(iconId)
+ .setView(certificateView);
+ }
+
+ private void setActionBarTitle(String url) {
+ if (mBar != null) {
+ mBar.setTitle(" " + url);
+ }
+ }
+
+ private String getStorage() {
+ if (mOriginInfo == null) {
+ return new String("");
+ }
+
+ long value = mOriginInfo.getStoredData();
+ if (value == 0) {
+ return "Empty";
+ }
+
+ if (value < (1 << 10)) {
+ return value + "B";
+ } else if (value < (1 << 20)) {
+ return (value >> 10) + "KB";
+ } else if (value < (1 << 30)) {
+ return (value >> 20) + "MB";
+ }
+
+ return (value >> 30) + "GB";
+ }
+
+ private long showPermission(CharSequence key, PermissionsServiceFactory.PermissionType type,
+ int defaultOnSummary, int defaultOffSummary) {
+ Preference pref = findPreference(key);
+ long permission = (mOriginInfo != null) ? mOriginInfo.getPermission(type) :
+ PermissionsServiceFactory.Permission.NOTSET;
+
+ pref.setOnPreferenceChangeListener(this);
+
+ if (permission == PermissionsServiceFactory.Permission.ALLOW) {
+ if (pref instanceof TwoStatePreference) {
+ ((TwoStatePreference) pref).setChecked(true);
+ ((TwoStatePreference) pref).setSummaryOn(R.string.pref_security_allowed);
+ } else {
+ pref.setSummary(R.string.pref_security_allowed);
+ }
+ mUsingDefaultSettings = false;
+ } else if (permission == PermissionsServiceFactory.Permission.BLOCK) {
+ if (pref instanceof TwoStatePreference) {
+ ((TwoStatePreference) pref).setChecked(false);
+ } else {
+ pref.setSummary(R.string.pref_security_not_allowed);
+ }
+ mUsingDefaultSettings = false;
+ } else if (permission == PermissionsServiceFactory.Permission.ASK) {
+ if (pref instanceof TwoStatePreference) {
+ ((TwoStatePreference) pref).setChecked(true);
+ ((TwoStatePreference) pref).setSummaryOn(R.string.pref_security_ask_before_using);
+ } else {
+ pref.setSummary(R.string.pref_security_ask_before_using);
+ }
+ mUsingDefaultSettings = false;
+ } else if (permission == PermissionsServiceFactory.Permission.NOTSET) {
+ boolean defaultPerm = PermissionsServiceFactory.getDefaultPermissions(type);
+ if (pref instanceof TwoStatePreference) {
+ if (!defaultPerm) {
+ ((TwoStatePreference) pref).setChecked(false);
+ ((TwoStatePreference) pref).setSummaryOff(defaultOffSummary);
+ return PermissionsServiceFactory.Permission.BLOCK;
+ } else {
+ ((TwoStatePreference) pref).setChecked(true);
+ ((TwoStatePreference) pref).setSummaryOn(defaultOnSummary);
+ return PermissionsServiceFactory.Permission.ASK;
+ }
+ } else {
+ if (!defaultPerm) {
+ pref.setSummary(defaultOffSummary);
+ return PermissionsServiceFactory.Permission.BLOCK;
+ } else {
+ pref.setSummary(defaultOnSummary);
+ return PermissionsServiceFactory.Permission.ASK;
+ }
+ }
+ }
+ return permission;
+ }
+
+ private void updateStorageInfo(Preference pref) {
+ if (mOriginInfo != null) {
+ pref.setTitle(R.string.webstorage_clear_data_title);
+ pref.setSummary("(" + getStorage() + ")");
+ }
+ }
+
+ private void updatePreferenceInfo() {
+ Preference pref = findPreference("clear_data");
+ updateStorageInfo(pref);
+ pref.setOnPreferenceClickListener(this);
+ String warningText = (mSslState == 1) ? getString(R.string.pref_warning_cert) + " " :
+ new String("");
+ boolean setting_warnings = false;
+
+ long permission = showPermission("select_geolocation",
+ PermissionsServiceFactory.PermissionType.GEOLOCATION,
+ R.string.pref_security_ask_before_using, R.string.pref_security_not_allowed);
+
+ if (PermissionsServiceFactory.Permission.ALLOW == permission) {
+ warningText += getString(R.string.pref_privacy_enable_geolocation);
+ setting_warnings = true;
+ }
+
+ ListPreference geolocation_pref = (ListPreference) findPreference("select_geolocation");
+ geolocation_pref.setValueIndex(0);
+ if (permission == PermissionsServiceFactory.Permission.CUSTOM) {
+ pref = findPreference("select_geolocation");
+ long custom = mOriginInfo.getPermissionCustomValue(
+ PermissionsServiceFactory.PermissionType.GEOLOCATION);
+ float customHrs = ((float) custom) / (60 * 60);
+ String customSummary = "Allowed for " + String.format("%.02f", customHrs) + " hours";
+ if (pref instanceof TwoStatePreference) {
+ ((TwoStatePreference) pref).setChecked(true);
+ ((TwoStatePreference) pref).setSummaryOn(customSummary);
+ } else {
+ pref.setSummary(customSummary);
+ }
+ mUsingDefaultSettings = false;
+ warningText += getString(R.string.pref_privacy_enable_geolocation);
+ setting_warnings = true;
+ geolocation_pref.setValueIndex(1);
+ } else if (permission == PermissionsServiceFactory.Permission.ALLOW) {
+ geolocation_pref.setValueIndex(2);
+ }
+
+ permission = showPermission("microphone", PermissionsServiceFactory.PermissionType.VOICE,
+ R.string.pref_security_ask_before_using, R.string.pref_security_not_allowed);
+
+ if (PermissionsServiceFactory.Permission.ALLOW == permission) {
+ if (!warningText.isEmpty() && setting_warnings) {
+ warningText += ", ";
+ }
+ warningText += getString(R.string.pref_security_allow_mic);
+ setting_warnings = true;
+ }
+
+ permission = showPermission("camera", PermissionsServiceFactory.PermissionType.VIDEO,
+ R.string.pref_security_ask_before_using, R.string.pref_security_not_allowed);
+ if (PermissionsServiceFactory.Permission.ALLOW == permission) {
+ if (!warningText.isEmpty() && setting_warnings) {
+ warningText += ", ";
+ }
+ warningText += getString(R.string.pref_security_allow_camera);
+ setting_warnings = true;
+ }
+
+ if (!warningText.isEmpty()) {
+ if (setting_warnings) {
+ warningText += " ";
+ warningText += getResources().getString(R.string.pref_security_access_is_allowed);
+ }
+ mSecurityViews.setText(SiteSecurityViewFactory.ViewType.WARNING, warningText);
+ } else {
+ mSecurityViews.clearText(SiteSecurityViewFactory.ViewType.WARNING);
+ }
+
+ pref = findPreference("distracting_contents");
+ if (pref != null) {
+ permission = showPermission("distracting_contents",
+ PermissionsServiceFactory.PermissionType.WEBREFINER,
+ R.string.pref_security_allowed, R.string.pref_security_not_allowed);
+ if (permission == PermissionsServiceFactory.Permission.BLOCK) {
+ ((TwoStatePreference) pref).setChecked(true);
+ } else {
+ ((TwoStatePreference) pref).setChecked(false);
+ }
+ }
+
+ showPermission("popup_windows", PermissionsServiceFactory.PermissionType.POPUP,
+ R.string.pref_security_allowed, R.string.pref_security_not_allowed);
+
+ showPermission("accept_cookies", PermissionsServiceFactory.PermissionType.COOKIE,
+ R.string.pref_security_allowed, R.string.pref_security_not_allowed);
+
+ if (!mUsingDefaultSettings && mBar != null) {
+ mBar.getCustomView().setVisibility(View.VISIBLE);
+ }
+
+ updateSecurityViewVisibility();
+ }
+
+ private void updateSecurityViewVisibility() {
+ if (mSecurityViews.mbEmpty) {
+ PreferenceScreen screen = (PreferenceScreen)
+ findPreference("site_specific_prefs");
+
+ if (mSecurityInfoPrefs == null) {
+ mSecurityInfoPrefs = findPreference("site_security_info_title");
+ }
+
+ if (mSecurityInfoPrefs != null && screen != null) {
+ screen.removePreference(mSecurityInfoPrefs);
+ }
+ } else {
+ PreferenceScreen screen = (PreferenceScreen)
+ findPreference("site_specific_prefs");
+
+ Preference pref = findPreference("site_security_info_title");
+ if (pref == null && mSecurityInfoPrefs != null) {
+ screen.addPreference(mSecurityInfoPrefs);
+ }
+ }
+
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ BrowserLocationListPreference pref =
+ (BrowserLocationListPreference) findPreference("select_geolocation");
+ if ( pref != null) pref.setEnabled(PermissionsServiceFactory.isSystemLocationEnabled());
+ if (mBar != null) {
+ mOriginalActionBarOptions = mBar.getDisplayOptions();
+ mBar.setDisplayHomeAsUpEnabled(false);
+ mBar.setHomeButtonEnabled(false);
+
+ assignResetButton();
+
+ Bundle args = getArguments();
+ if (args != null) {
+ byte[] data = args.getByteArray(EXTRA_FAVICON);
+ if (data != null) {
+ Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);
+ if (bm != null) {
+ Bitmap bitmap = Bitmap.createScaledBitmap(bm, 150, 150, true);
+ int color = ColorUtils.getDominantColorForBitmap(bitmap);
+
+ appendActionBarDisplayOptions(ActionBar.DISPLAY_SHOW_HOME |
+ ActionBar.DISPLAY_SHOW_TITLE);
+ mBar.setHomeButtonEnabled(true);
+ mBar.setIcon(new BitmapDrawable(getResources(), bitmap));
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mBar != null) {
+ mBar.setDisplayOptions(mOriginalActionBarOptions);
+ }
+
+ // flush all the settings in pause to assure that writes happen
+ // as soon the user leaves the activity
+ PermissionsServiceFactory.flushPendingSettings();
+
+ }
+
+ private void appendActionBarDisplayOptions(int extraOptions) {
+ int options = mBar.getDisplayOptions();
+ options |= extraOptions;
+ mBar.setDisplayOptions(options);
+ }
+
+ private void assignResetButton() {
+ appendActionBarDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
+ mBar.setCustomView(R.layout.swe_preference_custom_actionbar);
+ //mBar.getCustomView().setVisibility(View.GONE);
+ Button btn = (Button) mBar.getCustomView().findViewById(R.id.reset);
+ if (btn == null) {
+ return;
+ }
+
+ btn.setOnClickListener(
+ new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ new AlertDialog.Builder(getActivity())
+ .setMessage(R.string.pref_extras_reset_default_dlg)
+ .setPositiveButton(
+ R.string.ok,
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dlg, int which) {
+ if (mOriginInfo != null) {
+ mOriginInfo.resetSitePermission();
+ Preference e = findPreference("clear_data");
+ e.setSummary("(Empty)");
+ updatePreferenceInfo();
+
+ WebRefiner refiner = WebRefiner.getInstance();
+ if (refiner != null) {
+ String[] origins = new String[1];
+ origins[0] = mOriginInfo.getOrigin();
+ refiner.useDefaultPermissionForOrigins(origins);
+ }
+
+ BrowserPreferencesPage.sResultExtra =
+ PreferenceKeys.ACTION_RELOAD_PAGE;
+ BrowserPreferencesPage.onUrlNeedsReload(mOriginText);
+ finish();
+ }
+ }
+ })
+ .setNegativeButton(
+ R.string.cancel, null)
+ .setIconAttribute(android.R.attr.alertDialogIcon)
+ .show();
+ }
+ }
+ );
+ }
+
+ private void finish() {
+ Activity activity = getActivity();
+ if (activity != null) {
+ getActivity().getFragmentManager().popBackStack();
+ }
+ }
+
+ @Override
+ public void onChildViewAddedToHierarchy(View parent, View child) {
+ if (child.getId() == R.id.site_security_info) {
+ mSecurityViews.setResource(SiteSecurityViewFactory.ViewType.ERROR,
+ child, R.id.site_security_error);
+ mSecurityViews.setResource(SiteSecurityViewFactory.ViewType.WARNING,
+ child, R.id.site_security_warning);
+ mSecurityViews.setResource(SiteSecurityViewFactory.ViewType.INFO,
+ child, R.id.site_security_verbose);
+
+ if (mSslCert != null) {
+ child.setOnClickListener(this);
+ }
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getId() == R.id.site_security_info) {
+ createSslCertificateDialog(getActivity(), mSslCert)
+ .setPositiveButton(R.string.ok, null)
+ .show();
+ }
+ }
+
+ private void updateTwoStatePreference(Preference pref,
+ PermissionsServiceFactory.PermissionType type,
+ boolean state) {
+ if (state) {
+ mOriginInfo.setPermission(type, PermissionsServiceFactory.Permission.ALLOW);
+ ((TwoStatePreference)pref).setSummaryOn(R.string.pref_security_allowed);
+ } else {
+ mOriginInfo.setPermission(type, PermissionsServiceFactory.Permission.BLOCK);
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference pref, Object objValue) {
+ if (mOriginInfo == null) {
+ if (mOriginText != null) {
+ mOriginInfo = mPermServ.addOriginInfo(mOriginText);
+ if (mOriginInfo == null) {
+ mOriginInfo = mPermServ.getOriginInfo(mOriginText);
+ if (mOriginInfo == null) {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+ if (pref.getKey().toString().equalsIgnoreCase("select_geolocation")) {
+ int index = mLocationValues.indexOf(objValue.toString());
+ switch (index) {
+ case 0:
+ mOriginInfo.setPermission(PermissionsServiceFactory.PermissionType.GEOLOCATION,
+ PermissionsServiceFactory.Permission.BLOCK);
+ pref.setSummary(R.string.pref_security_not_allowed);
+ break;
+ case 1:
+ mOriginInfo.setPermission(PermissionsServiceFactory.PermissionType.GEOLOCATION,
+ PermissionsServiceFactory.Permission.CUSTOM);
+ pref.setSummary(R.string.geolocation_permissions_prompt_share_for_limited_time);
+ break;
+ case 2:
+ mOriginInfo.setPermission(PermissionsServiceFactory.PermissionType.GEOLOCATION,
+ PermissionsServiceFactory.Permission.ALLOW);
+ pref.setSummary(R.string.pref_security_allowed);
+ break;
+ default:
+ break;
+ }
+ } else if (pref.getKey().toString().equalsIgnoreCase("microphone")) {
+ updateTwoStatePreference(pref,
+ PermissionsServiceFactory.PermissionType.VOICE, (boolean)objValue);
+ } else if (pref.getKey().toString().equalsIgnoreCase("camera")) {
+ updateTwoStatePreference(pref,
+ PermissionsServiceFactory.PermissionType.VIDEO, (boolean)objValue);
+ } else if (pref.getKey().toString().equalsIgnoreCase("distracting_contents")) {
+ WebRefiner refiner = WebRefiner.getInstance();
+ if (refiner != null) {
+ boolean disable = (boolean) objValue;
+ String[] origins = new String[1];
+ origins[0] = mOriginInfo.getOrigin();
+ refiner.setPermissionForOrigins(origins, !disable);
+ }
+ // Distracting contents and web refiner complimentary of each other
+ updateTwoStatePreference(pref,
+ PermissionsServiceFactory.PermissionType.WEBREFINER, !(boolean)objValue);
+ } else if (pref.getKey().toString().equalsIgnoreCase("popup_windows")) {
+ updateTwoStatePreference(pref,
+ PermissionsServiceFactory.PermissionType.POPUP, (boolean)objValue);
+ } else if (pref.getKey().toString().equalsIgnoreCase("accept_cookies")) {
+ updateTwoStatePreference(pref,
+ PermissionsServiceFactory.PermissionType.COOKIE, (boolean)objValue);
+ }
+ BrowserPreferencesPage.sResultExtra = PreferenceKeys.ACTION_RELOAD_PAGE;
+ BrowserPreferencesPage.onUrlNeedsReload(mOriginText);
+ updatePreferenceInfo();
+ return true;
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference pref) {
+ if (pref.getKey().toString().equalsIgnoreCase("clear_data")) {
+ new AlertDialog.Builder(getActivity())
+ .setMessage(R.string.website_settings_clear_all_dialog_message)
+ .setPositiveButton(R.string.ok,
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dlg, int which) {
+ if (mOriginInfo != null) {
+ mOriginInfo.clearAllStoredData();
+ Preference e = findPreference("clear_data");
+ e.setSummary("(Empty)");
+ BrowserPreferencesPage.sResultExtra =
+ PreferenceKeys.ACTION_RELOAD_PAGE;
+ BrowserPreferencesPage.onUrlNeedsReload(mOriginText);
+ }
+ }
+ })
+ .setNegativeButton(R.string.cancel, null)
+ .setIconAttribute(android.R.attr.alertDialogIcon)
+ .show();
+ }
+ return true;
+ }
+
+}
diff --git a/src/src/com/android/browser/preferences/WebViewPreview.java b/src/src/com/android/browser/preferences/WebViewPreview.java
new file mode 100644
index 00000000..03ffcb24
--- /dev/null
+++ b/src/src/com/android/browser/preferences/WebViewPreview.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser.preferences;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import com.android.browser.BrowserSettings;
+import com.android.browser.R;
+import org.codeaurora.swe.WebView;
+
+public abstract class WebViewPreview extends Preference
+ implements OnSharedPreferenceChangeListener {
+
+ protected TextView mTextView;
+ protected WebView mWebView;
+
+ public WebViewPreview(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context);
+ }
+
+ public WebViewPreview(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public WebViewPreview(Context context) {
+ super(context);
+ init(context);
+ }
+
+ protected void init(Context context) {
+ setLayoutResource(R.layout.webview_preview);
+ BrowserSettings bs = BrowserSettings.getInstance();
+ mWebView = bs.getTopWebView();
+ }
+
+ protected abstract void updatePreview(boolean forceReload);
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+ mTextView = (TextView) view.findViewById(R.id.text_size_preview);
+ // Ignore all touch events & don't show scrollbars
+ mTextView.setFocusable(false);
+ mTextView.setFocusableInTouchMode(false);
+ mTextView.setClickable(false);
+ mTextView.setLongClickable(false);
+ mTextView.setHorizontalScrollBarEnabled(false);
+ mTextView.setVerticalScrollBarEnabled(false);
+ updatePreview(true);
+ }
+
+ @Override
+ protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {
+ super.onAttachedToHierarchy(preferenceManager);
+ getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ protected void onPrepareForRemoval() {
+ getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+ super.onPrepareForRemoval();
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ updatePreview(false);
+ }
+
+}
diff --git a/src/src/com/android/browser/preferences/WebsiteSettingsFragment.java b/src/src/com/android/browser/preferences/WebsiteSettingsFragment.java
new file mode 100644
index 00000000..c9dd04d3
--- /dev/null
+++ b/src/src/com/android/browser/preferences/WebsiteSettingsFragment.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser.preferences;
+
+import android.app.ActionBar;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.app.FragmentTransaction;
+import android.app.ListFragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.ColorDrawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.webkit.ValueCallback;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.browser.R;
+import com.android.browser.SiteTileView;
+import com.android.browser.WebStorageSizeManager;
+
+import java.io.ByteArrayOutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.codeaurora.swe.GeolocationPermissions;
+import org.codeaurora.swe.PermissionsServiceFactory;
+import org.codeaurora.swe.WebRefiner;
+import org.codeaurora.swe.WebStorage;
+
+/**
+ * Manage the settings for an origin.
+ * We use it to keep track of the 'HTML5' settings, i.e. database (webstorage)
+ * and Geolocation.
+ */
+public class WebsiteSettingsFragment extends ListFragment implements OnClickListener {
+ private SiteAdapter mAdapter = null;
+
+ private class Site implements OnClickListener {
+ private String mOrigin;
+ private String mTitle;
+ private Bitmap mIcon;
+ private View mView;
+ private Bitmap mDefaultIcon = mAdapter.mDefaultIcon;
+
+ public Site(String origin) {
+ mOrigin = origin;
+ mTitle = null;
+ mIcon = null;
+ fetchFavicon();
+ }
+
+ private void fetchFavicon() {
+ // Fetch favicon and set it
+ PermissionsServiceFactory.getFavicon(mOrigin, getActivity(),
+ new ValueCallback<Bitmap>() {
+ @Override
+ public void onReceiveValue(Bitmap value) {
+ setIcon(value);
+
+ }
+ });
+ }
+
+ public void updateView(View view){
+ mView = view;
+ fetchFavicon();
+ }
+
+ public String getOrigin() {
+ return mOrigin;
+ }
+
+ public void setTitle(String title) {
+ mTitle = title;
+ }
+
+ public void setIcon(Bitmap image) {
+ mIcon = image;
+ if (mView != null) {
+ SiteTileView icon = (SiteTileView) mView.findViewById(R.id.icon);
+ icon.replaceFavicon((image == null) ? mDefaultIcon : image);
+ icon.setVisibility(View.VISIBLE);
+ icon.setOnClickListener(this);
+ }
+ }
+
+ public Bitmap getIcon() {
+ return mIcon;
+ }
+
+ public String getPrettyOrigin() {
+ return mTitle == null ? null : hideHttp(mOrigin);
+ }
+
+ public String getPrettyTitle() {
+ return mTitle == null ? hideHttp(mOrigin) : mTitle;
+ }
+
+ private String hideHttp(String str) {
+ if (str == null)
+ return null;
+ Uri uri = Uri.parse(str);
+ return "http".equals(uri.getScheme()) ? str.substring(7) : str;
+ }
+
+ @Override
+ public void onClick(View v) {
+ clickHandler(this);
+ }
+ }
+
+ class SiteAdapter extends ArrayAdapter<Site>
+ implements AdapterView.OnItemClickListener {
+ private int mResource;
+ private LayoutInflater mInflater;
+ private Bitmap mDefaultIcon;
+ private PermissionsServiceFactory.PermissionsService mPermServ;
+ private boolean mReady;
+
+ public SiteAdapter(Context context, int rsc) {
+ super(context, rsc);
+ mResource = rsc;
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mDefaultIcon = BitmapFactory.decodeResource(getResources(),
+ R.drawable.ic_deco_favicon_normal);
+ mReady = false;
+ askForOrigins();
+ }
+
+ public void askForOrigins() {
+ if (mPermServ == null) {
+ PermissionsServiceFactory.getPermissionsService(
+ new ValueCallback<PermissionsServiceFactory.PermissionsService>() {
+ @Override
+ public void onReceiveValue(
+ PermissionsServiceFactory.PermissionsService value) {
+ mPermServ = value;
+ Map<String, Site> sites = new HashMap<>();
+
+ Set<String> origins = mPermServ.getOrigins();
+ for (String origin : origins) {
+ if (!TextUtils.isEmpty(origin))
+ sites.put(origin, new Site(origin));
+ }
+
+ // Create a map from host to origin. This is used to add metadata
+ // (title, icon) for this origin from the bookmarks DB. We must do
+ // the DB access on a background thread.
+ //new UpdateFromBookmarksDbTask(ctx, sites).execute();
+
+ populateOrigins(sites);
+ mReady = true;
+ }
+ }
+ );
+ }
+ }
+
+ public void deleteAllOrigins() {
+ if (mPermServ != null) {
+ Set<String> origins = mPermServ.getOrigins();
+ String[] originArray = origins.toArray(new String[origins.size()]);
+
+ for (String origin : originArray) {
+ PermissionsServiceFactory.PermissionsService.OriginInfo info =
+ mPermServ.getOriginInfo(origin);
+ if (info != null) {
+ info.clearAllStoredData();
+ }
+ }
+ // purge the permissionservice since its not needed
+ mPermServ.purge();
+ mPermServ = null;
+
+ // reset all site settings
+ PermissionsServiceFactory.resetSiteSettings();
+
+ WebRefiner refiner = WebRefiner.getInstance();
+ if (refiner != null) {
+ refiner.useDefaultPermissionForOrigins(originArray);
+ }
+ }
+ }
+
+ private void populateOrigins(Map<String, Site> sites) {
+ clear();
+
+ // We can now simply populate our array with Site instances
+ Set<Map.Entry<String, Site>> elements = sites.entrySet();
+ Iterator<Map.Entry<String, Site>> entryIterator = elements.iterator();
+ while (entryIterator.hasNext()) {
+ Map.Entry<String, Site> entry = entryIterator.next();
+ Site site = entry.getValue();
+ add(site);
+ }
+
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View view;
+ final TextView title;
+ final TextView subtitle;
+
+ if (convertView == null) {
+ view = mInflater.inflate(mResource, parent, false);
+ } else {
+ view = convertView;
+ }
+
+ title = (TextView) view.findViewById(R.id.title);
+ subtitle = (TextView) view.findViewById(R.id.subtitle);
+
+ Site site = getItem(position);
+ site.updateView(view);
+ title.setText(site.getPrettyTitle());
+ String subtitleText = site.getPrettyOrigin();
+ if (subtitleText != null) {
+ title.setMaxLines(1);
+ title.setSingleLine(true);
+ subtitle.setVisibility(View.VISIBLE);
+ subtitle.setText(subtitleText);
+ } else {
+ subtitle.setVisibility(View.GONE);
+ title.setMaxLines(2);
+ title.setSingleLine(false);
+ }
+ // We set the site as the view's tag,
+ // so that we can get it in onItemClick()
+ view.setTag(site);
+
+ return view;
+ }
+
+ public void onItemClick(AdapterView<?> parent,
+ View view,
+ int position,
+ long id) {
+ clickHandler((Site) view.getTag());
+ }
+ }
+
+ private void clickHandler(Site site) {
+ Activity activity = getActivity();
+ if (activity != null) {
+ Bundle args = new Bundle();
+ args.putString(SiteSpecificPreferencesFragment.EXTRA_ORIGIN, site.getOrigin());
+ if(site.getIcon() != null) {
+ ByteArrayOutputStream favicon = new ByteArrayOutputStream();
+ site.getIcon().compress(Bitmap.CompressFormat.PNG, 100, favicon);
+ args.putByteArray(SiteSpecificPreferencesFragment.EXTRA_FAVICON,
+ favicon.toByteArray());
+ }
+ FragmentManager fragmentManager = activity.getFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ Fragment newFragment = new SiteSpecificPreferencesFragment();
+ newFragment.setArguments(args);
+ fragmentTransaction.replace(getId(), newFragment);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.swe_website_settings, container, false);
+ View new_site = view.findViewById(R.id.add_new_site);
+ new_site.setVisibility(View.VISIBLE);
+ new_site.setOnClickListener(this);
+ View clear = view.findViewById(R.id.clear_all_button);
+ clear.setVisibility(View.VISIBLE);
+ clear.setOnClickListener(this);
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ mAdapter = new SiteAdapter(getActivity(), R.layout.website_settings_row);
+ getListView().setAdapter(mAdapter);
+ getListView().setOnItemClickListener(mAdapter);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mAdapter.askForOrigins();
+ ActionBar bar = getActivity().getActionBar();
+ if (bar != null) {
+ bar.setTitle(R.string.pref_extras_website_settings);
+ bar.setDisplayHomeAsUpEnabled(false);
+ bar.setHomeButtonEnabled(false);
+ }
+ }
+
+ private void finish() {
+ Activity activity = getActivity();
+ if (activity != null) {
+ getActivity().getFragmentManager().popBackStack();
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.clear_all_button:
+ // Show the prompt to clear all origins of their data and geolocation permissions.
+ new AlertDialog.Builder(getActivity())
+ .setMessage(R.string.website_settings_clear_all_dialog_message)
+ .setPositiveButton(R.string.ok,
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dlg, int which) {
+ mAdapter.deleteAllOrigins();
+ if (GeolocationPermissions.isIncognitoCreated()) {
+ GeolocationPermissions.getIncognitoInstance().clearAll();
+ }
+ WebStorageSizeManager.resetLastOutOfSpaceNotificationTime();
+ mAdapter.askForOrigins();
+ finish();
+ }
+ })
+ .setNegativeButton(R.string.cancel, null)
+ .setIconAttribute(android.R.attr.alertDialogIcon)
+ .show();
+ break;
+ case R.id.add_new_site:
+ final EditText input = new EditText(getActivity());
+ new AlertDialog.Builder(getActivity())
+ .setTitle(R.string.website_settings_add_origin)
+ .setMessage(R.string.pref_security_origin_name)
+ .setView(input)
+ .setPositiveButton(R.string.pref_security_add,
+ new AlertDialog.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ String origin = input.getText().toString();
+ Bundle args = new Bundle();
+ args.putString(SiteSpecificPreferencesFragment.EXTRA_SITE,
+ origin);
+
+ FragmentTransaction fragmentTransaction =
+ getActivity().getFragmentManager().beginTransaction();
+
+ Fragment newFragment = new SiteSpecificPreferencesFragment();
+ newFragment.setArguments(args);
+ fragmentTransaction.replace(getId(), newFragment);
+ fragmentTransaction.addToBackStack(null);
+ fragmentTransaction.commit();
+ }})
+ .setNegativeButton(R.string.cancel, null)
+ .show();
+
+ break;
+ }
+ }
+}