diff options
author | Pankaj Garg <pgarg@codeaurora.org> | 2015-06-03 18:13:24 -0700 |
---|---|---|
committer | jrizzoli <joey@cyanogenmoditalia.it> | 2015-08-28 13:15:45 +0200 |
commit | 32e1b940b71a96d55bd7b9cedf31fc4aacdbfec1 (patch) | |
tree | b988b99456730b9d3b0a48f8b197bff903e61803 | |
parent | 53ef89355c4cd8511d3dfc2bc5a336f7d60ad4a9 (diff) | |
download | android_packages_apps_Gello-32e1b940b71a96d55bd7b9cedf31fc4aacdbfec1.tar.gz android_packages_apps_Gello-32e1b940b71a96d55bd7b9cedf31fc4aacdbfec1.tar.bz2 android_packages_apps_Gello-32e1b940b71a96d55bd7b9cedf31fc4aacdbfec1.zip |
Security and Privacy UI
- new panel for site specific settings
- hooked up favicon to site settings
- new images for security icons
- revamped settings panels to match the new
ui layouts
Change-Id: I1e872ce353e66f78e2b0530901fcbb7de69e28b4
68 files changed, 2647 insertions, 896 deletions
diff --git a/res/drawable-xxhdpi/ic_action_trash_active.png b/res/drawable-xxhdpi/ic_action_trash_active.png Binary files differnew file mode 100644 index 00000000..bb949ef0 --- /dev/null +++ b/res/drawable-xxhdpi/ic_action_trash_active.png diff --git a/res/drawable-xxhdpi/ic_action_trash_disabled.png b/res/drawable-xxhdpi/ic_action_trash_disabled.png Binary files differnew file mode 100644 index 00000000..08d10320 --- /dev/null +++ b/res/drawable-xxhdpi/ic_action_trash_disabled.png diff --git a/res/drawable-xxhdpi/ic_action_trash_normal.png b/res/drawable-xxhdpi/ic_action_trash_normal.png Binary files differindex a06804b0..cfcc525b 100644 --- a/res/drawable-xxhdpi/ic_action_trash_normal.png +++ b/res/drawable-xxhdpi/ic_action_trash_normal.png diff --git a/res/drawable-xxhdpi/ic_fav_overlay_good.png b/res/drawable-xxhdpi/ic_fav_overlay_good.png Binary files differnew file mode 100644 index 00000000..e5211a92 --- /dev/null +++ b/res/drawable-xxhdpi/ic_fav_overlay_good.png diff --git a/res/drawable-xxhdpi/ic_fav_overlay_normal.png b/res/drawable-xxhdpi/ic_fav_overlay_normal.png Binary files differnew file mode 100644 index 00000000..acab304b --- /dev/null +++ b/res/drawable-xxhdpi/ic_fav_overlay_normal.png diff --git a/res/drawable-xxhdpi/ic_fav_overlay_severe.png b/res/drawable-xxhdpi/ic_fav_overlay_severe.png Binary files differnew file mode 100644 index 00000000..4be624a5 --- /dev/null +++ b/res/drawable-xxhdpi/ic_fav_overlay_severe.png diff --git a/res/drawable-xxhdpi/ic_fav_overlay_warning.png b/res/drawable-xxhdpi/ic_fav_overlay_warning.png Binary files differnew file mode 100644 index 00000000..d3d52550 --- /dev/null +++ b/res/drawable-xxhdpi/ic_fav_overlay_warning.png diff --git a/res/drawable-xxhdpi/ic_sp_camera.png b/res/drawable-xxhdpi/ic_sp_camera.png Binary files differnew file mode 100644 index 00000000..4542530d --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_camera.png diff --git a/res/drawable-xxhdpi/ic_sp_cookies.png b/res/drawable-xxhdpi/ic_sp_cookies.png Binary files differnew file mode 100644 index 00000000..9ec2d0c0 --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_cookies.png diff --git a/res/drawable-xxhdpi/ic_sp_level_good.png b/res/drawable-xxhdpi/ic_sp_level_good.png Binary files differnew file mode 100644 index 00000000..b6040998 --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_level_good.png diff --git a/res/drawable-xxhdpi/ic_sp_level_severe.png b/res/drawable-xxhdpi/ic_sp_level_severe.png Binary files differnew file mode 100644 index 00000000..699b0f3d --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_level_severe.png diff --git a/res/drawable-xxhdpi/ic_sp_level_warning.png b/res/drawable-xxhdpi/ic_sp_level_warning.png Binary files differnew file mode 100644 index 00000000..5351e245 --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_level_warning.png diff --git a/res/drawable-xxhdpi/ic_sp_location.png b/res/drawable-xxhdpi/ic_sp_location.png Binary files differnew file mode 100644 index 00000000..5ef0b873 --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_location.png diff --git a/res/drawable-xxhdpi/ic_sp_microphone.png b/res/drawable-xxhdpi/ic_sp_microphone.png Binary files differnew file mode 100644 index 00000000..5c0ac083 --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_microphone.png diff --git a/res/drawable-xxhdpi/ic_sp_multi_choice.png b/res/drawable-xxhdpi/ic_sp_multi_choice.png Binary files differnew file mode 100644 index 00000000..3525b380 --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_multi_choice.png diff --git a/res/drawable-xxhdpi/ic_sp_popups.png b/res/drawable-xxhdpi/ic_sp_popups.png Binary files differnew file mode 100644 index 00000000..ad835032 --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_popups.png diff --git a/res/drawable-xxhdpi/ic_sp_revert.png b/res/drawable-xxhdpi/ic_sp_revert.png Binary files differnew file mode 100644 index 00000000..7e20c342 --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_revert.png diff --git a/res/drawable-xxhdpi/ic_sp_secwarnings.png b/res/drawable-xxhdpi/ic_sp_secwarnings.png Binary files differnew file mode 100644 index 00000000..6295586b --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_secwarnings.png diff --git a/res/drawable-xxhdpi/ic_sp_storage.png b/res/drawable-xxhdpi/ic_sp_storage.png Binary files differnew file mode 100644 index 00000000..e0b821b8 --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_storage.png diff --git a/res/drawable-xxhdpi/ic_sp_thirdcookies.png b/res/drawable-xxhdpi/ic_sp_thirdcookies.png Binary files differnew file mode 100644 index 00000000..833c00ee --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_thirdcookies.png diff --git a/res/drawable-xxhdpi/ic_sp_webrefiner.png b/res/drawable-xxhdpi/ic_sp_webrefiner.png Binary files differnew file mode 100644 index 00000000..f9ad396c --- /dev/null +++ b/res/drawable-xxhdpi/ic_sp_webrefiner.png diff --git a/res/drawable-xxhdpi/img_deco_dropshadow.png b/res/drawable-xxhdpi/img_deco_dropshadow.png Binary files differnew file mode 100644 index 00000000..1168599e --- /dev/null +++ b/res/drawable-xxhdpi/img_deco_dropshadow.png diff --git a/res/drawable-xxhdpi/img_deco_intrapanel.png b/res/drawable-xxhdpi/img_deco_intrapanel.png Binary files differnew file mode 100644 index 00000000..211dbf2e --- /dev/null +++ b/res/drawable-xxhdpi/img_deco_intrapanel.png diff --git a/res/drawable/ic_action_trash.xml b/res/drawable/ic_action_trash.xml new file mode 100644 index 00000000..061b3396 --- /dev/null +++ b/res/drawable/ic_action_trash.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <item android:state_enabled="true" android:state_pressed="true" + android:drawable="@drawable/ic_action_trash_active" /> + + <item android:state_enabled="true" android:state_selected="true" + android:drawable="@drawable/ic_action_trash_active" /> + + <item android:state_enabled="false" + android:drawable="@drawable/ic_action_trash_disabled" /> + + <item android:drawable="@drawable/ic_action_trash_normal" /> + +</selector> diff --git a/res/layout-v17/swe_preference_category.xml b/res/layout-v17/swe_preference_category.xml new file mode 100644 index 00000000..865e0a61 --- /dev/null +++ b/res/layout-v17/swe_preference_category.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <ImageView + android:layout_width="fill_parent" + android:layout_height="8dp" /> + + <ImageView + android:background="@drawable/img_deco_intrapanel" + android:layout_width="fill_parent" + android:layout_height="8dp" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="@style/PreferenceCategoryWithButtonStyle" + android:gravity="center_vertical" > + + <TextView + android:id="@android:id/title" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:textAppearance="@style/PreferenceCategoryTextStyle" + android:textColor="@color/accent" + /> + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/res/layout-v17/swe_preference_category_first.xml b/res/layout-v17/swe_preference_category_first.xml new file mode 100644 index 00000000..fa71affe --- /dev/null +++ b/res/layout-v17/swe_preference_category_first.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="@style/PreferenceCategoryWithButtonStyle" + android:gravity="center_vertical" > + + <TextView + android:id="@android:id/title" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:textAppearance="@style/PreferenceCategoryTextStyle" + android:textColor="@color/accent" + /> + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/res/layout-v21/swe_preference_category.xml b/res/layout-v21/swe_preference_category.xml new file mode 100644 index 00000000..6ab34e2e --- /dev/null +++ b/res/layout-v21/swe_preference_category.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <ImageView + android:layout_width="fill_parent" + android:layout_height="8dp" /> + + <ImageView + android:background="@drawable/img_deco_intrapanel" + android:layout_width="fill_parent" + android:layout_height="8dp" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + style="@style/PreferenceCategoryWithButtonStyle" + android:gravity="center_vertical" > + + <TextView + android:id="@android:id/title" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:textAppearance="@style/PreferenceCategoryTextStyle" + android:textColor="@color/accent" + /> + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/res/layout-v21/swe_preference_category_first.xml b/res/layout-v21/swe_preference_category_first.xml new file mode 100644 index 00000000..39cc118f --- /dev/null +++ b/res/layout-v21/swe_preference_category_first.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <ImageView + android:layout_width="fill_parent" + android:layout_height="8dp" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + style="@style/PreferenceCategoryWithButtonStyle" + android:gravity="center_vertical" > + + <TextView + android:id="@android:id/title" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="wrap_content" + android:textAppearance="@style/PreferenceCategoryTextStyle" + android:textColor="@color/accent" + /> + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/site_specific_security_info.xml b/res/layout/site_specific_security_info.xml new file mode 100644 index 00000000..31560df4 --- /dev/null +++ b/res/layout/site_specific_security_info.xml @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/site_security_info" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingStart="?android:attr/scrollbarSize" + android:paddingEnd="?android:attr/scrollbarSize" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:gravity="center_vertical" + android:background="?android:attr/selectableItemBackground" + android:layout_gravity="fill_horizontal"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + <LinearLayout + android:id="@+id/site_security_error" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:gravity="center_vertical" + > + <ImageView + android:gravity="center" + android:src="@drawable/ic_sp_level_severe" + android:minWidth="40dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <TextView + android:id="@+id/security_view_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="start" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/site_security_warning" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:gravity="center_vertical" + > + <ImageView + android:gravity="center" + android:src="@drawable/ic_sp_level_warning" + android:minWidth="40dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <TextView + android:id="@id/security_view_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="start" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/site_security_verbose" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:gravity="center_vertical" + > + <ImageView + android:src="@drawable/ic_sp_level_good" + android:gravity="center" + android:minWidth="40dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <TextView + android:id="@id/security_view_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="start" /> + </LinearLayout> + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/swe_preference.xml b/res/layout/swe_preference.xml new file mode 100644 index 00000000..41356ce1 --- /dev/null +++ b/res/layout/swe_preference.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingEnd="?android:attr/scrollbarSize" + android:minHeight="?android:attr/listPreferredItemHeightSmall" + android:gravity="center_vertical" > + <!--android:background="?android:attr/selectableItemBackgroundBorderless"--> + + <!--Padding--> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="20dip" /> + + <!--Icon for preference--> + <ImageView + android:id="@+android:id/icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" /> + + <!--Preference title and summary--> + <RelativeLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="10dip" + android:layout_marginEnd="6dip" + android:layout_marginTop="6dip" + android:layout_marginBottom="6dip" + android:layout_weight="1"> + + <TextView android:id="@+android:id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceListItemSmall" + android:textColor="?android:attr/textColorPrimary" + android:ellipsize="marquee" + android:fadingEdge="horizontal" /> + + <TextView android:id="@+android:id/summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@android:id/title" + android:layout_alignStart="@android:id/title" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:attr/textColorSecondary" + android:maxLines="4" /> + </RelativeLayout> + + <!--Widget if any--> + <LinearLayout android:id="@+android:id/widget_frame" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:orientation="vertical" /> + +</LinearLayout> diff --git a/res/layout/swe_preference_button.xml b/res/layout/swe_preference_button.xml new file mode 100644 index 00000000..41ad8868 --- /dev/null +++ b/res/layout/swe_preference_button.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<Button xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+android:id/title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" /> diff --git a/res/layout/swe_preference_custom_actionbar.xml b/res/layout/swe_preference_custom_actionbar.xml new file mode 100644 index 00000000..9dca94df --- /dev/null +++ b/res/layout/swe_preference_custom_actionbar.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<Button xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/reset" + android:drawableEnd="@drawable/ic_sp_revert" + android:text="@string/pref_extras_reset_default" + android:background="@android:color/transparent" + android:layout_gravity="end" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:clickable="true" + /> diff --git a/res/layout/swe_preference_list_widget.xml b/res/layout/swe_preference_list_widget.xml new file mode 100644 index 00000000..b7cf7a0f --- /dev/null +++ b/res/layout/swe_preference_list_widget.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<ImageView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:background="@drawable/ic_sp_multi_choice" />
\ No newline at end of file diff --git a/res/layout/swe_preference_storage_widget.xml b/res/layout/swe_preference_storage_widget.xml new file mode 100644 index 00000000..b00fe69c --- /dev/null +++ b/res/layout/swe_preference_storage_widget.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<ImageView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:background="@drawable/ic_sp_storage" /> diff --git a/res/layout/swe_preference_trashcan_widget.xml b/res/layout/swe_preference_trashcan_widget.xml new file mode 100644 index 00000000..77db4ff5 --- /dev/null +++ b/res/layout/swe_preference_trashcan_widget.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<ImageView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:background="@drawable/ic_action_trash" /> diff --git a/res/layout/swe_website_settings.xml b/res/layout/swe_website_settings.xml index ed951481..50d593c1 100644 --- a/res/layout/swe_website_settings.xml +++ b/res/layout/swe_website_settings.xml @@ -30,12 +30,27 @@ android:clipToPadding="false" android:drawSelectorOnTop="false" android:cacheColorHint="@android:color/transparent" + android:divider="@null" + android:dividerHeight="0dp" android:scrollbarAlwaysDrawVerticalTrack="true" /> - <Button android:id="@+id/clear_all_button" + <LinearLayout + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <Button android:id="@+id/add_new_site" + android:layout_width="150dip" + android:layout_height="wrap_content" + android:layout_margin="5dip" + android:text="@string/website_settings_add_origin" + android:visibility="gone" /> + + <Button android:id="@+id/clear_all_button" android:layout_width="150dip" android:layout_height="wrap_content" android:layout_margin="5dip" android:text="@string/website_settings_clear_all" android:visibility="gone" /> + </LinearLayout> </LinearLayout> diff --git a/res/layout/title_bar_nav.xml b/res/layout/title_bar_nav.xml index d7ab2b11..d12c4ff9 100644 --- a/res/layout/title_bar_nav.xml +++ b/res/layout/title_bar_nav.xml @@ -52,6 +52,12 @@ android:contentDescription="@string/page_info"> <ImageView + android:id="@+id/favicon_badge" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center"/> + + <ImageView android:id="@+id/favicon" android:layout_width="32dip" android:layout_height="32dip" diff --git a/res/layout/website_settings_row.xml b/res/layout/website_settings_row.xml index 19e998e7..68c38d9c 100644 --- a/res/layout/website_settings_row.xml +++ b/res/layout/website_settings_row.xml @@ -30,35 +30,6 @@ android:background="@drawable/bookmark_list_favicon_bg" android:padding="2dip" /> - <LinearLayout android:id="@+id/features" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_alignParentTop="true" - android:layout_alignParentBottom="true" - android:layout_alignParentEnd="true" - android:gravity="center" - android:padding="0dip" - android:layout_marginEnd="2dip"> - - <ImageView android:id="@+id/location_icon" - android:layout_width="32dip" - android:layout_height="32dip" - android:padding="2dip" /> - - <ImageView android:id="@+id/usage_icon" - android:layout_width="32dip" - android:layout_height="32dip" - android:padding="2dip" /> - - <ImageView android:id="@+id/feature_icon" - android:layout_width="32dip" - android:layout_height="32dip" - android:padding="2dip" - android:layout_centerVertical="true" - android:layout_alignParentEnd="true" - android:visibility="gone" /> - </LinearLayout> - <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/res/values/strings.xml b/res/values/strings.xml index db717a7c..d00e8532 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -311,6 +311,7 @@ <string name="menu_preferences">Settings</string> <!-- Settings screen, section title --> <string name="pref_content_title">Content settings</string> + <string name="pref_content_title_summary">Web content setting</string> <!-- Settings label [CHAR LIMIT=45]--> <string name="pref_allow_apptabs">Allow multiple tabs per app</string> <!-- Settings label --> @@ -319,6 +320,7 @@ <string name="pref_content_load_images_summary">Display images on web pages</string> <!-- Settings label [CHAR LIMIT=30] --> <string name="pref_content_block_popups">Block pop-ups</string> + <string name="pref_security_allow_popups">Pop ups</string> <!-- Settings label --> <string name="pref_content_javascript">Enable JavaScript</string> <!-- Settings label --> @@ -375,6 +377,9 @@ <!-- Settings screen & section title for "General settings". These include things like configuring bookmark syncing to Google servers and form auto fill settings. [CHAR-LIMIT=32] --> <string name="pref_general_title">General</string> + <string name="pref_default_site_settings_title">Default Site Settings</string> + <string name="pref_site_settings_title">Site Settings</string> + <string name="pref_site_settings_info_panel">Security Information</string> <!-- Settings category for sync under general settings. This includes bookmark sync with Chrome [CHAR-LIMIT=50] --> <string name="pref_general_sync_title">Sync</string> <!-- Settings category for autofill under general. [CHAR-LIMIT=50] --> @@ -398,6 +403,8 @@ <string name="pref_web_refiner_enabled">Web Refiner</string> <!-- Settings summary for the WebRefiner --> <string name="pref_web_refiner_enabled_summary">Block advertisements and tracking</string> + <string name="pref_web_refiner_blocked">Blocked</string> + <string name="pref_web_refiner_advertisements">advertisements</string> <!-- Label for option that when clicked opens the AutoFill settings screen. Also used as the title of that AutoFill Settings screen. [CHAR-LIMIT=32] --> <string name="pref_autofill_profile_editor">Auto-fill text</string> <!-- Summary for the AutoFill Settings preference [CHAR-LIMIT=none] --> @@ -452,6 +459,7 @@ <!-- Settings screen, section title [CHAR-LIMIT=50] --> <string name="pref_privacy_security_title">Privacy & security</string> + <string name="pref_privacy_security_title_summary">Browser security and privacy settings</string> <!-- Popup dialog --> <string name="pref_select_items">Select items to be cleared</string> <!-- Settings label --> @@ -469,9 +477,9 @@ <!-- Cookie settings category [CHAR-LIMIT=50] --> <string name="pref_privacy_cookies_title">Cookies</string> <!-- Settings label --> - <string name="pref_privacy_clear_cookies">Cookies</string> + <string name="pref_privacy_clear_cookies">Cookies and Site Data</string> <!-- Settings summary --> - <string name="pref_privacy_clear_cookies_summary">Clear all browser cookies</string> + <string name="pref_privacy_clear_cookies_summary">Clear all browser cookies and site data</string> <!-- Confirmation dialog message --> <string name="pref_privacy_clear_cookies_dlg">Delete all cookies?</string> <!-- Settings label --> @@ -497,7 +505,7 @@ <!-- Location settings category [CHAR-LIMIT=50] --> <string name="pref_privacy_location_title">Location</string> <!-- Settings label --> - <string name="pref_privacy_enable_geolocation">Enable location</string> + <string name="pref_privacy_enable_geolocation">Location</string> <!-- Settings summary --> <string name="pref_privacy_enable_geolocation_summary">Allow sites to request access to your location</string> <!-- Settings label --> @@ -528,6 +536,22 @@ <string name="pref_security_accept_cookies">Accept cookies</string> <!-- Settings summary --> <string name="pref_security_accept_cookies_summary">Allow sites to save and read cookie data</string> + + <string name="pref_security_allow_mic">Microphone</string> + <string name="pref_security_allow_camera">Camera</string> + <string name="pref_security_web_refiner">Ads and Distracting Content</string> + <string name="pref_security_accept_third_party_cookies">Third Party Cookies</string> + <string name="pref_security_ask_before_using">Ask before using</string> + <string name="pref_security_allowed">Allowed</string> + <string name="pref_security_not_allowed">Not allowed</string> + <string name="pref_security_remember">Remember</string> + <string name="pref_security_protect">Protect by default</string> + <string name="pref_website_title">Website</string> + <string name="pref_security_add">Add</string> + <string name="pref_security_cancel">Cancel</string> + <string name="pref_security_origin_name">Site Origin</string> + <string name="pref_security_access_is_allowed">access is allowed</string> + <!-- Settings text size options - displays sample font size in settings --> <string name="pref_sample_font_size">Drag the slider to adjust the font size to set the desired comfortable reading size.</string> <!-- Label for minimum font size [CHAR LIMIT=30] --> @@ -573,7 +597,7 @@ <!-- Settings screen, section title [CHAR LIMIT=50] --> <string name="pref_extras_title">Advanced</string> <!-- Settings label --> - <string name="pref_extras_website_settings">Website settings</string> + <string name="pref_extras_website_settings">Per Site Settings</string> <!-- Settings summary --> <string name="pref_extras_website_settings_summary">Advanced settings for individual websites</string> <!-- Settings category label [CHAR-LIMIT=50] --> @@ -675,6 +699,7 @@ <!-- Title for accessibility settings [CHAR LIMIT=25] --> <string name="pref_accessibility_title">Accessibility</string> + <string name="pref_accessibility_title_summary">Text size and zooming</string> <!-- Font size settings category under accessibility settings [CHAR LIMIT=50] --> <string name="pref_font_size_category">Text size</string> <!-- Title for lab settings [CHAR LIMIT=25] --> @@ -863,7 +888,8 @@ <string name="webstorage_outofspace_notification_title">Browser storage full</string> <string name="webstorage_outofspace_notification_text">Touch to free up space.</string> <!-- Used in the Browser Settings --> - <string name="webstorage_clear_data_title">Clear stored data</string> + <string name="webstorage_clear_data_title">Storage</string> + <string name="webstorage_private_data_title">Private Data</string> <!-- Confirmation dialog when the user ask to clear all data for an origin --> <string name="webstorage_clear_data_dialog_message">Delete all data stored by this website?</string> @@ -894,11 +920,11 @@ <item>Deny forever</item> <item>Allow for 24 hours</item> <item>Allow forever</item> - <item>Always ask</item> </string-array> <string name="geolocation_settings_page_dialog_ok_button">OK</string> <string name="geolocation_settings_page_dialog_cancel_button">Cancel</string> + <string name="website_settings_add_origin">New Site</string> <!-- Label for the menu item in the website settings activity used to clear data stored by all websites --> <string name="website_settings_clear_all">Clear all</string> <string name="website_settings_clear_all_dialog_message">Delete all website data and location permissions?</string> diff --git a/res/xml/accessibility_preferences.xml b/res/xml/accessibility_preferences.xml index 68bc4840..506a9ed2 100644 --- a/res/xml/accessibility_preferences.xml +++ b/res/xml/accessibility_preferences.xml @@ -17,7 +17,9 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> - <PreferenceCategory android:title="@string/pref_font_size_category"> + <PreferenceCategory + android:layout="@layout/swe_preference_category_first" + android:title="@string/pref_font_size_category"> <com.android.browser.preferences.FontSizePreview android:title="@string/preview" /> <com.android.browser.preferences.SeekBarSummaryPreference android:defaultValue="10" @@ -31,7 +33,7 @@ android:max="20" android:title="@string/pref_min_font_size" /> - <CheckBoxPreference + <SwitchPreference android:defaultValue="false" android:key="force_userscalable" android:summary="@string/pref_force_userscalable_summary" diff --git a/res/xml/bandwidth_preferences.xml b/res/xml/bandwidth_preferences.xml index 9946b48d..a31d0e84 100644 --- a/res/xml/bandwidth_preferences.xml +++ b/res/xml/bandwidth_preferences.xml @@ -32,7 +32,7 @@ android:entryValues="@array/pref_link_prefetch_values" android:dialogTitle="@string/pref_link_prefetch_dialogtitle" /> - <CheckBoxPreference + <SwitchPreference android:key="load_images" android:defaultValue="true" android:title="@string/pref_content_load_images" diff --git a/res/xml/content_preferences.xml b/res/xml/content_preferences.xml new file mode 100644 index 00000000..68fc90ab --- /dev/null +++ b/res/xml/content_preferences.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:key="content_settings"> + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="false" + android:key="open_in_background" + android:summary="@string/pref_content_open_in_background_summary" + android:title="@string/pref_content_open_in_background" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:key="enable_javascript" + android:title="@string/pref_content_javascript" /> + + <PreferenceScreen + android:key="download_path_setting_screen" + android:title="@string/pref_download_path_setting_screen_title"/> + + <ListPreference + android:layout="@layout/swe_preference" + android:widgetLayout="@layout/swe_preference_list_widget" + android:defaultValue="@string/pref_default_text_encoding_default" + android:dialogTitle="@string/pref_default_text_encoding_dialogtitle" + android:entries="@array/pref_default_text_encoding_choices" + android:entryValues="@array/pref_default_text_encoding_values" + android:key="default_text_encoding" + android:title="@string/pref_default_text_encoding" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:key="load_images" + android:defaultValue="true" + android:title="@string/pref_content_load_images" + android:summary="@string/pref_content_load_images_summary" /> + +</PreferenceScreen> diff --git a/res/xml/debug_preferences.xml b/res/xml/debug_preferences.xml index dc6b7230..f23ce121 100644 --- a/res/xml/debug_preferences.xml +++ b/res/xml/debug_preferences.xml @@ -17,58 +17,69 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="enable_hardware_accel" android:defaultValue="true" android:title="@string/pref_development_hardware_accel" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="enable_hardware_accel_skia" android:defaultValue="false" android:title="@string/pref_development_hardware_accel_skia" android:enabled="false" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="enable_visual_indicator" android:defaultValue="false" android:title="@string/pref_development_visual_indicator" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="enable_cpu_upload_path" android:defaultValue="false" android:title="@string/pref_development_cpu_upload_path" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="small_screen" android:defaultValue="false" android:title="@string/pref_development_single_column_rendering" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="wide_viewport" android:defaultValue="true" android:title="@string/pref_development_viewport" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="normal_layout" android:defaultValue="false" android:title="@string/pref_development_normal_rendering" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="enable_tracing" android:defaultValue="false" android:title="@string/pref_development_trace" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="enable_light_touch" android:defaultValue="false" android:title="Enable light touch" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="enable_nav_dump" android:defaultValue="false" android:title="@string/pref_development_nav_dump" /> <EditTextPreference + android:layout="@layout/swe_preference" android:key="js_engine_flags" android:title="@string/js_engine_flags" android:singleLine="true" /> diff --git a/res/xml/download_settings_preferences.xml b/res/xml/download_settings_preferences.xml index 0cd99a98..91a1859c 100644 --- a/res/xml/download_settings_preferences.xml +++ b/res/xml/download_settings_preferences.xml @@ -31,9 +31,10 @@ xmlns:android="http://schemas.android.com/apk/res/android" > <PreferenceCategory - android:title="@string/pref_download_title" - android:key="download_path_setting_category"> - <PreferenceScreen + android:layout="@layout/swe_preference_category_first" + android:title="@string/pref_download_title" + android:key="download_path_setting_category"> + <PreferenceScreen android:key="download_path_setting_screen" android:title="@string/pref_download_path_setting_screen_title"/> diff --git a/res/xml/general_preferences.xml b/res/xml/general_preferences.xml index 816503b2..7571a6a1 100644 --- a/res/xml/general_preferences.xml +++ b/res/xml/general_preferences.xml @@ -16,204 +16,94 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> - <PreferenceCategory android:title="@string/pref_general_title"> + <PreferenceCategory + android:layout="@layout/swe_preference_category_first" + android:title="@string/pref_general_title"> <com.android.browser.preferences.NonformattingListPreference + android:layout="@layout/swe_preference" + android:widgetLayout="@layout/swe_preference_list_widget" android:key="homepage_picker" android:entries="@array/pref_homepage_choices" android:entryValues="@array/pref_homepage_values" android:title="@string/pref_content_homepage" /> <com.android.browser.search.SearchEnginePreference + android:layout="@layout/swe_preference" + android:widgetLayout="@layout/swe_preference_list_widget" android:defaultValue="@string/default_search_engine_value" android:dialogTitle="@string/pref_content_search_engine" android:key="search_engine" android:summary="@string/pref_content_search_engine_summary" android:title="@string/pref_content_search_engine" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:defaultValue="false" android:key="fullscreen" android:summary="@string/pref_lab_fullscreen_summary" android:title="@string/pref_lab_fullscreen" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:defaultValue="false" android:key="powersave_enabled" android:summary="@string/pref_powersave_enabled_summary" android:title="@string/pref_powersave_enabled" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:defaultValue="false" android:key="nightmode_enabled" android:summary="@string/pref_nightmode_enabled_summary" android:title="@string/pref_nightmode_enabled" /> - <CheckBoxPreference + <SwitchPreference + android:layout="@layout/swe_preference" android:key="autofill_enabled" android:title="@string/pref_autofill_enabled" android:summary="@string/pref_autofill_enabled_summary" android:defaultValue="true" /> - <CheckBoxPreference - android:key="web_refiner_enabled" - android:title="@string/pref_web_refiner_enabled" - android:summary="@string/pref_web_refiner_enabled_summary" - android:defaultValue="true" /> - <PreferenceScreen + android:layout="@layout/swe_preference" android:key="autofill_profile" android:title="@string/pref_autofill_profile_editor" android:summary="@string/pref_autofill_profile_editor_summary" /> </PreferenceCategory> <PreferenceCategory android:title="@string/pref_extras_title" + android:layout="@layout/swe_preference_category" android:key="advanced"> <PreferenceScreen android:title="@string/pref_privacy_security_title" - android:key="privacy_security"> - <PreferenceScreen android:title="@string/webstorage_clear_data_title" - android:key="clear_data"> - <com.android.browser.BrowserYesNoPreference - android:dialogIcon="@android:drawable/ic_dialog_alert" - android:dialogMessage="@string/pref_privacy_clear_selected_dlg" - android:key="privacy_clear_selected" - android:summary="@string/pref_privacy_clear_selected_summary" - android:title="@string/pref_privacy_clear_selected" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="privacy_clear_history" - android:summary="@string/pref_privacy_clear_history_summary" - android:title="@string/pref_privacy_clear_history" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="privacy_clear_cache" - android:summary="@string/pref_privacy_clear_cache_summary" - android:title="@string/pref_privacy_clear_cache" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="privacy_clear_cookies" - android:summary="@string/pref_privacy_clear_cookies_summary" - android:title="@string/pref_privacy_clear_cookies" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="privacy_clear_form_data" - android:summary="@string/pref_privacy_clear_form_data_summary" - android:title="@string/pref_privacy_clear_form_data" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="privacy_clear_passwords" - android:summary="@string/pref_privacy_clear_passwords_summary" - android:title="@string/pref_privacy_clear_passwords" /> - - <CheckBoxPreference - android:defaultValue="true" - android:dependency="enable_geolocation" - android:key="privacy_clear_geolocation_access" - android:summary="@string/pref_privacy_clear_geolocation_access_summary" - android:title="@string/pref_privacy_clear_geolocation_access" /> - - </PreferenceScreen> - - <CheckBoxPreference - android:defaultValue="true" - android:key="show_security_warnings" - android:summary="@string/pref_security_show_security_warning_summary" - android:title="@string/pref_security_show_security_warning" /> - - <com.android.browser.mdm.MdmCheckBoxPreference - android:defaultValue="true" - android:key="do_not_track" - android:summary="@string/pref_do_not_track_summary" - android:title="@string/pref_do_not_track" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="accept_cookies" - android:summary="@string/pref_security_accept_cookies_summary" - android:title="@string/pref_security_accept_cookies" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="save_formdata" - android:summary="@string/pref_security_save_form_data_summary" - android:title="@string/pref_security_save_form_data" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="enable_geolocation" - android:summary="@string/pref_privacy_enable_geolocation_summary" - android:title="@string/pref_privacy_enable_geolocation" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="remember_passwords" - android:summary="@string/pref_security_remember_passwords_summary" - android:title="@string/pref_security_remember_passwords" /> - - </PreferenceScreen> + android:summary="@string/pref_privacy_security_title_summary" + android:layout="@layout/swe_preference" + android:key="privacy_security" /> <PreferenceScreen + android:layout="@layout/swe_preference" android:key="accessibility_menu" - android:title="@string/pref_accessibility_title" /> + android:summary="@string/pref_accessibility_title_summary" + android:title="@string/pref_accessibility_title"/> <PreferenceScreen android:title="@string/pref_content_title" - android:key="content_settings"> - <CheckBoxPreference - android:defaultValue="true" - android:key="block_popup_windows" - android:title="@string/pref_content_block_popups" /> - - <CheckBoxPreference - android:defaultValue="false" - android:key="open_in_background" - android:summary="@string/pref_content_open_in_background_summary" - android:title="@string/pref_content_open_in_background" /> - - <CheckBoxPreference - android:defaultValue="true" - android:key="enable_javascript" - android:title="@string/pref_content_javascript" /> - - <PreferenceScreen - android:key="download_path_setting_screen" - android:title="@string/pref_download_path_setting_screen_title"/> - - <ListPreference - android:defaultValue="@string/pref_default_text_encoding_default" - android:dialogTitle="@string/pref_default_text_encoding_dialogtitle" - android:entries="@array/pref_default_text_encoding_choices" - android:entryValues="@array/pref_default_text_encoding_values" - android:key="default_text_encoding" - android:title="@string/pref_default_text_encoding" /> - - <CheckBoxPreference - android:key="load_images" - android:defaultValue="true" - android:title="@string/pref_content_load_images" - android:summary="@string/pref_content_load_images_summary" /> - - </PreferenceScreen> - - - <PreferenceScreen - android:key="website_settings" - android:summary="@string/pref_extras_website_settings_summary" - android:title="@string/pref_extras_website_settings" /> + android:summary="@string/pref_content_title_summary" + android:layout="@layout/swe_preference" + android:key="content_settings" /> <ListPreference + android:layout="@layout/swe_preference" + android:widgetLayout="@layout/swe_preference_list_widget" android:dialogTitle="@string/pref_edge_swipe_option_msg" android:entries="@array/pref_edge_swiping_choices" android:entryValues="@array/pref_edge_swiping_values" + android:summary="%s" android:key="edge_swiping_action" android:title="@string/pref_edge_swipe_title" /> <com.android.browser.BrowserYesNoPreference + android:layout="@layout/swe_preference" android:key="reset_default_preferences" android:title="@string/pref_extras_reset_default" android:summary="@string/pref_extras_reset_default_summary" @@ -221,6 +111,7 @@ android:dialogIcon="@android:drawable/ic_dialog_alert" /> <PreferenceScreen + android:layout="@layout/swe_preference" android:key="debug_menu" android:title="@string/pref_development_title" /> </PreferenceCategory> diff --git a/res/xml/privacy_and_security_preferences.xml b/res/xml/privacy_and_security_preferences.xml new file mode 100644 index 00000000..d5b2f9a1 --- /dev/null +++ b/res/xml/privacy_and_security_preferences.xml @@ -0,0 +1,184 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <PreferenceCategory + android:layout="@layout/swe_preference_category_first" + android:title="@string/pref_general_title"> + <com.android.browser.mdm.MdmCheckBoxPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:key="do_not_track" + android:summaryOn="@string/pref_security_protect" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_do_not_track" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:key="remember_passwords" + android:summaryOn="@string/pref_security_remember" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_remember_passwords" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:key="save_formdata" + android:summaryOn="@string/pref_security_remember" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_save_form_data" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:key="accept_third_cookies" + android:summaryOn="@string/pref_security_allowed" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_accept_third_party_cookies" /> + + <PreferenceScreen android:title="@string/webstorage_private_data_title" + android:layout="@layout/swe_preference" + android:widgetLayout="@layout/swe_preference_storage_widget" + > + <CheckBoxPreference + android:defaultValue="true" + android:key="privacy_clear_history" + android:summary="@string/pref_privacy_clear_history_summary" + android:title="@string/pref_privacy_clear_history" /> + + <CheckBoxPreference + android:defaultValue="true" + android:key="privacy_clear_cache" + android:summary="@string/pref_privacy_clear_cache_summary" + android:title="@string/pref_privacy_clear_cache" /> + + <CheckBoxPreference + android:defaultValue="true" + android:key="privacy_clear_cookies" + android:summary="@string/pref_privacy_clear_cookies_summary" + android:title="@string/pref_privacy_clear_cookies" /> + + <CheckBoxPreference + android:defaultValue="true" + android:key="privacy_clear_form_data" + android:summary="@string/pref_privacy_clear_form_data_summary" + android:title="@string/pref_privacy_clear_form_data" /> + + <CheckBoxPreference + android:defaultValue="true" + android:key="privacy_clear_passwords" + android:summary="@string/pref_privacy_clear_passwords_summary" + android:title="@string/pref_privacy_clear_passwords" /> + + <CheckBoxPreference + android:defaultValue="true" + android:dependency="enable_geolocation" + android:key="privacy_clear_geolocation_access" + android:summary="@string/pref_privacy_clear_geolocation_access_summary" + android:title="@string/pref_privacy_clear_geolocation_access" /> + + <com.android.browser.BrowserYesNoPreference + android:layout="@layout/swe_preference_button" + android:dialogIcon="@android:drawable/ic_dialog_alert" + android:dialogMessage="@string/pref_privacy_clear_selected_dlg" + android:key="privacy_clear_selected" + android:summary="@string/pref_privacy_clear_selected_summary" + android:title="@string/pref_privacy_clear_selected" /> + + </PreferenceScreen> + + <PreferenceScreen + android:layout="@layout/swe_preference" + android:key="website_settings" + android:summary="@string/pref_extras_website_settings_summary" + android:title="@string/pref_extras_website_settings" /> + + </PreferenceCategory> + + <PreferenceCategory + android:layout="@layout/swe_preference_category" + android:title="@string/pref_default_site_settings_title"> + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:icon="@drawable/ic_sp_location" + android:key="enable_geolocation" + android:summaryOn="@string/pref_security_ask_before_using" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_privacy_enable_geolocation" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:icon="@drawable/ic_sp_microphone" + android:key="microphone" + android:summaryOn="@string/pref_security_ask_before_using" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_allow_mic" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:icon="@drawable/ic_sp_camera" + android:key="camera" + android:summaryOn="@string/pref_security_ask_before_using" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_allow_camera" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="false" + android:icon="@drawable/ic_sp_webrefiner" + android:key="distracting_contents" + android:summaryOn="@string/pref_security_allowed" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_web_refiner" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="false" + android:icon="@drawable/ic_sp_popups" + android:key="popup_windows" + android:summaryOn="@string/pref_security_allowed" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_allow_popups" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:icon="@drawable/ic_sp_thirdcookies" + android:key="accept_cookies" + android:summaryOn="@string/pref_security_allowed" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_accept_cookies" /> + + </PreferenceCategory> +</PreferenceScreen> diff --git a/res/xml/site_specific_preferences.xml b/res/xml/site_specific_preferences.xml new file mode 100644 index 00000000..19aac5cd --- /dev/null +++ b/res/xml/site_specific_preferences.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:key="site_specific_prefs"> + + <PreferenceCategory + android:layout="@layout/swe_preference_category_first" + android:title="@string/pref_website_title" > + <Preference + android:layout="@layout/swe_preference" + android:key="site_name"/> + </PreferenceCategory> + + <PreferenceCategory + android:layout="@layout/swe_preference_category" + android:key="site_security_info_title" + android:title="@string/pref_site_settings_info_panel" > + + <PreferenceScreen + android:key="site_security_info" + android:layout="@layout/site_specific_security_info"/> + </PreferenceCategory> + + <PreferenceCategory + android:title="@string/pref_site_settings_title" + android:layout="@layout/swe_preference_category" + android:key="reset_default"> + + <ListPreference + android:layout="@layout/swe_preference" + android:widgetLayout="@layout/swe_preference_list_widget" + android:icon="@drawable/ic_sp_location" + android:key="select_geolocation" + android:dialogTitle="@string/pref_privacy_clear_geolocation_access" + android:entries="@array/geolocation_settings_choices" + android:entryValues="@array/geolocation_settings_choices" + android:title="@string/pref_privacy_enable_geolocation" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:icon="@drawable/ic_sp_microphone" + android:key="microphone" + android:summaryOn="@string/pref_security_allowed" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_allow_mic" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:icon="@drawable/ic_sp_camera" + android:key="camera" + android:summaryOn="@string/pref_security_allowed" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_allow_camera" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="false" + android:icon="@drawable/ic_sp_webrefiner" + android:key="distracting_contents" + android:summaryOn="@string/pref_security_allowed" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_web_refiner" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="false" + android:icon="@drawable/ic_sp_popups" + android:key="popup_windows" + android:summaryOn="@string/pref_security_allowed" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_allow_popups" /> + + <SwitchPreference + android:layout="@layout/swe_preference" + android:defaultValue="true" + android:icon="@drawable/ic_sp_thirdcookies" + android:key="accept_cookies" + android:summaryOn="@string/pref_security_allowed" + android:summaryOff="@string/pref_security_not_allowed" + android:title="@string/pref_security_accept_cookies" /> + + <Preference + android:layout="@layout/swe_preference" + android:widgetLayout="@layout/swe_preference_trashcan_widget" + android:icon="@drawable/ic_sp_storage" + android:key="clear_data" + android:title="@string/webstorage_clear_data_title" /> + </PreferenceCategory> +</PreferenceScreen> diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java index 2d7c0b38..c12b5811 100644 --- a/src/com/android/browser/BaseUi.java +++ b/src/com/android/browser/BaseUi.java @@ -733,7 +733,7 @@ public abstract class BaseUi implements UI { // See http://b/5403800 d = getLockIconMixed(); } - mNavigationBar.setLock(d); + mNavigationBar.setLock(d, securityState); } protected void setUrlTitle(Tab tab) { diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java index 4a138c14..eb360233 100644 --- a/src/com/android/browser/BrowserSettings.java +++ b/src/com/android/browser/BrowserSettings.java @@ -26,11 +26,9 @@ import android.net.NetworkInfo; import android.os.Build; import android.preference.PreferenceManager; import android.provider.Settings; -import android.text.TextUtils; import android.util.DisplayMetrics; import android.webkit.WebStorage; -import com.android.browser.R; import com.android.browser.homepages.HomeProvider; import com.android.browser.mdm.DoNotTrackRestriction; import com.android.browser.mdm.ProxyRestriction; @@ -43,16 +41,14 @@ import com.android.browser.search.SearchEngines; import java.lang.ref.WeakReference; import java.util.Iterator; import java.util.LinkedList; -import java.util.WeakHashMap; import org.codeaurora.swe.AutoFillProfile; import org.codeaurora.swe.CookieManager; import org.codeaurora.swe.GeolocationPermissions; +import org.codeaurora.swe.PermissionsServiceFactory; import org.codeaurora.swe.WebRefiner; import org.codeaurora.swe.WebSettings.LayoutAlgorithm; -import org.codeaurora.swe.WebSettings.PluginState; import org.codeaurora.swe.WebSettings.TextSize; -import org.codeaurora.swe.WebSettings.ZoomDensity; import org.codeaurora.swe.WebSettings; import org.codeaurora.swe.WebView; import org.codeaurora.swe.WebViewDatabase; @@ -385,9 +381,6 @@ public class BrowserSettings implements OnSharedPreferenceChangeListener, } } else if (PREF_LINK_PREFETCH.equals(key)) { updateConnectionType(); - } else if (PREF_WEB_REFINER_ENABLED.equals(key)) { - if (WebRefiner.isInitialized()) - WebRefiner.getInstance().setRulesEnabled(WebRefiner.CATEGORY_ALL, isWebRefinerEnabled()); } } @@ -755,7 +748,7 @@ public class BrowserSettings implements OnSharedPreferenceChangeListener, } public boolean blockPopupWindows() { - return mPrefs.getBoolean(PREF_BLOCK_POPUP_WINDOWS, true); + return !mPrefs.getBoolean(PREF_POPUP_WINDOWS, false); } public boolean loadImages() { @@ -814,14 +807,6 @@ public class BrowserSettings implements OnSharedPreferenceChangeListener, mPrefs.edit().putBoolean(PREF_POWERSAVE_ENABLED, value).apply(); } - public boolean isWebRefinerEnabled() { - return mPrefs.getBoolean(PREF_WEB_REFINER_ENABLED, true); - } - - public void setWebRefinerEnabled(boolean value) { - mPrefs.edit().putBoolean(PREF_WEB_REFINER_ENABLED, value).apply(); - } - public boolean isNightModeEnabled() { return mPrefs.getBoolean(PREF_NIGHTMODE_ENABLED, false); } @@ -955,7 +940,8 @@ public class BrowserSettings implements OnSharedPreferenceChangeListener, } public boolean acceptCookies() { - return mPrefs.getBoolean(PREF_ACCEPT_COOKIES, true); + return PermissionsServiceFactory.getDefaultPermissions( + PermissionsServiceFactory.PermissionType.COOKIE); } public boolean saveFormdata() { diff --git a/src/com/android/browser/BrowserYesNoPreference.java b/src/com/android/browser/BrowserYesNoPreference.java index 6fdde2cf..f47ff3d8 100644 --- a/src/com/android/browser/BrowserYesNoPreference.java +++ b/src/com/android/browser/BrowserYesNoPreference.java @@ -25,6 +25,8 @@ import android.preference.PreferenceManager; import android.util.AttributeSet; import android.util.Log; import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; class BrowserYesNoPreference extends DialogPreference { private SharedPreferences mPrefs; @@ -38,6 +40,31 @@ class BrowserYesNoPreference extends DialogPreference { } @Override + protected View onCreateView(ViewGroup group) { + View child = super.onCreateView(group); + View titleView = child.findViewById(android.R.id.title); + if (titleView instanceof Button) { + Button btn = (Button) titleView; + final BrowserYesNoPreference pref = this; + btn.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + pref.onClick(); + } + } + ); + } + + return child; + } + + @Override + protected void onClick() { + super.onClick(); + } + + @Override protected View onCreateDialogView() { if (PreferenceKeys.PREF_CLEAR_SELECTED_DATA.equals(getKey())) { String dialogMessage = mContext.getString(R.string.pref_privacy_clear_selected_dlg); diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java index 2f8db527..3f5319a0 100644 --- a/src/com/android/browser/Controller.java +++ b/src/com/android/browser/Controller.java @@ -88,14 +88,14 @@ import org.codeaurora.swe.CookieManager; import org.codeaurora.swe.CookieSyncManager; import org.codeaurora.swe.Engine; import org.codeaurora.swe.HttpAuthHandler; +import org.codeaurora.swe.PermissionsServiceFactory; import org.codeaurora.swe.SslErrorHandler; +import org.codeaurora.swe.WebRefiner; import org.codeaurora.swe.WebSettings; import org.codeaurora.swe.WebView; import org.codeaurora.swe.WebBackForwardList; import org.codeaurora.swe.WebHistoryItem; -import com.android.browser.AppAdapter; -import com.android.browser.R; import com.android.browser.IntentHandler.UrlData; import com.android.browser.UI.ComboViews; import com.android.browser.mdm.EditBookmarksRestriction; @@ -127,6 +127,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; /** * Controller for browser @@ -296,6 +297,45 @@ public class Controller mNetworkHandler = new NetworkStateHandler(mActivity, this); mHomepageHandler = new HomepageHandler(browser, this); mAppMenuHandler = new AppMenuHandler(browser, this, R.menu.browser); + + final WebRefiner refiner = WebRefiner.getInstance(); + if (refiner != null) { + refiner.setRulesEnabled(WebRefiner.CATEGORY_ALL, + !PermissionsServiceFactory.getDefaultPermissions( + PermissionsServiceFactory.PermissionType.WEBREFINER)); + + PermissionsServiceFactory.getPermissionsService( + new ValueCallback<PermissionsServiceFactory.PermissionsService>() { + @Override + public void onReceiveValue( + PermissionsServiceFactory.PermissionsService value) { + Set<String> origins = value.getOrigins(); + ArrayList<String> allowList = new ArrayList<>(); + ArrayList<String> blockList = new ArrayList<>(); + for (String origin : origins) { + PermissionsServiceFactory.PermissionsService.OriginInfo + info = value.getOriginInfo(origin); + int perm = info.getPermission( + PermissionsServiceFactory.PermissionType.WEBREFINER); + if (perm == PermissionsServiceFactory.Permission.ALLOW) { + allowList.add(origin); + } else if (perm == PermissionsServiceFactory.Permission.BLOCK) { + blockList.add(origin); + } + } + if (!allowList.isEmpty()) { + refiner.enableRulesForDomains(WebRefiner.CATEGORY_ALL, + allowList.toArray(new String[allowList.size()])); + } + + if (!blockList.isEmpty()) { + refiner.disableRulesForDomains(WebRefiner.CATEGORY_ALL, + blockList.toArray(new String[blockList.size()])); + } + } + } + ); + } } @Override diff --git a/src/com/android/browser/NavigationBarBase.java b/src/com/android/browser/NavigationBarBase.java index ebeae651..753e3626 100644 --- a/src/com/android/browser/NavigationBarBase.java +++ b/src/com/android/browser/NavigationBarBase.java @@ -15,14 +15,21 @@ */ package com.android.browser; +import android.animation.ArgbEvaluator; +import android.animation.ValueAnimator; import android.app.Activity; import android.app.SearchManager; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.graphics.Bitmap; +import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.net.http.SslCertificate; +import android.net.http.SslError; +import android.os.Build; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; @@ -40,14 +47,19 @@ import android.widget.LinearLayout; import android.widget.PopupMenu; import android.widget.Toast; -import com.android.browser.R; import com.android.browser.UrlInputView.UrlInputListener; +import com.android.browser.preferences.SiteSpecificPreferencesFragment; +import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; import java.net.URISyntaxException; +import java.net.URL; import org.codeaurora.swe.Engine; +import org.codeaurora.swe.WebRefiner; import org.codeaurora.swe.WebView; +import org.codeaurora.swe.util.ColorUtils; public class NavigationBarBase extends LinearLayout implements OnClickListener, UrlInputListener, OnFocusChangeListener, @@ -61,6 +73,8 @@ public class NavigationBarBase extends LinearLayout implements protected UiController mUiController; protected UrlInputView mUrlInput; + protected ImageView mFaviconBadge; + private ImageView mFavicon; private ImageView mLockIcon; @@ -69,6 +83,11 @@ public class NavigationBarBase extends LinearLayout implements private boolean mOverflowMenuShowing; private boolean mNeedsMenu; + private int mStatusBarColor; + private static int mDefaultStatusBarColor = -1; + + private Tab.SecurityState mSecurityState = Tab.SecurityState.SECURITY_STATE_NOT_SECURE; + public NavigationBarBase(Context context) { super(context); } @@ -94,6 +113,7 @@ public class NavigationBarBase extends LinearLayout implements mMore = findViewById(R.id.more_browser_settings); mMore.setOnClickListener(this); mNeedsMenu = !ViewConfiguration.get(getContext()).hasPermanentMenuKey(); + mFaviconBadge = (ImageView) findViewById(R.id.favicon_badge); } public void setTitleBar(TitleBar titleBar) { @@ -103,7 +123,22 @@ public class NavigationBarBase extends LinearLayout implements mUrlInput.setController(mUiController); } - public void setLock(Drawable d) { + public void setLock(Drawable d, Tab.SecurityState securityState) { + mSecurityState = securityState; + switch (mSecurityState) { + case SECURITY_STATE_SECURE: + mFaviconBadge.setImageResource(R.drawable.ic_fav_overlay_good); + break; + case SECURITY_STATE_MIXED: + mFaviconBadge.setImageResource(R.drawable.ic_fav_overlay_warning); + break; + case SECURITY_STATE_BAD_CERTIFICATE: + mFaviconBadge.setImageResource(R.drawable.ic_fav_overlay_severe); + break; + case SECURITY_STATE_NOT_SECURE: + default: + mFaviconBadge.setImageResource(R.drawable.ic_fav_overlay_normal); + } if (mLockIcon == null) return; if (d == null) { mLockIcon.setVisibility(View.GONE); @@ -113,11 +148,157 @@ public class NavigationBarBase extends LinearLayout implements } } + public static int adjustColor(int color, float hueMultiplier, + float saturationMultiplier, float valueMultiplier) { + float[] hsv = new float[3]; + Color.colorToHSV(color, hsv); + hsv[0] *= hueMultiplier; + hsv[1] *= saturationMultiplier; + hsv[2] *= valueMultiplier; + return Color.HSVToColor(Color.alpha(color), hsv); + } + + public static void setStatusAndNavigationBarColor(final Activity activity, int color) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + int currentColor = activity.getWindow().getStatusBarColor(); + Integer from = currentColor; + Integer to = color; + ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(), from, to); + + if (mDefaultStatusBarColor == -1) { + mDefaultStatusBarColor = activity.getWindow().getStatusBarColor(); + } + + animator.addUpdateListener( + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + Integer value = (Integer) animation.getAnimatedValue(); + activity.getWindow().setStatusBarColor(value.intValue()); + //activity.getWindow().setNavigationBarColor(value.intValue()); + } + } + ); + animator.start(); + } + } + + private void updateSiteIconColor(String urlString, int color) { + try { + URL url = new URL(urlString); + String host = url.getHost(); + SharedPreferences prefs = BrowserSettings.getInstance().getPreferences(); + int currentColor = prefs.getInt(host + ":color", 0); + if (currentColor != color) { + SharedPreferences.Editor editor = prefs.edit(); + editor.remove(host + ":color"); + editor.putInt(host + ":color", color); + editor.commit(); + } + } catch (MalformedURLException e) { + } + } + + public static int getSiteIconColor(String urlString) { + try { + URL url = new URL(urlString); + String host = url.getHost(); + SharedPreferences prefs = BrowserSettings.getInstance().getPreferences(); + return prefs.getInt(host + ":color", 0); + } catch (MalformedURLException e) { + return 0; + } + } + + public static int getDefaultStatusBarColor() { + return mDefaultStatusBarColor; + } + public void setFavicon(Bitmap icon) { + int color = ColorUtils.getDominantColorForBitmap(icon); + Tab tab = mUiController.getCurrentTab(); + + if (tab != null) { + if (tab.hasFavicon()) { + updateSiteIconColor(tab.getUrl(), color); + setStatusAndNavigationBarColor(mUiController.getActivity(), + adjustColor(color, 1, 1, 0.7f)); + } else { + color = getSiteIconColor(tab.getUrl()); + if (color != 0) { + setStatusAndNavigationBarColor(mUiController.getActivity(), + adjustColor(color, 1, 1, 0.7f)); + } else { + setStatusAndNavigationBarColor(mUiController.getActivity(), + mDefaultStatusBarColor); + } + } + } else { + setStatusAndNavigationBarColor(mUiController.getActivity(), mDefaultStatusBarColor); + } + if (mFavicon == null) return; mFavicon.setImageDrawable(mBaseUi.getFaviconDrawable(icon)); } + protected void showSiteSpecificSettings() { + WebView wv = mUiController.getCurrentTopWebView(); + int count = 0; + + if (wv != null && WebRefiner.getInstance() != null) { + count = WebRefiner.getInstance().getBlockedURLCount(wv); + } + + Bundle bundle = new Bundle(); + bundle.putCharSequence(SiteSpecificPreferencesFragment.EXTRA_SITE, + mUiController.getCurrentTab().getUrl()); + bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_WEB_REFINER_INFO, count); + + bundle.putParcelable(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT, + SslCertificate.saveState(wv.getCertificate())); + + SslError error = mUiController.getCurrentTab().getSslCertificateError(); + if (error != null) { + int certError = 0; + if (error.hasError(SslError.SSL_DATE_INVALID)) { + certError |= (1 << SslError.SSL_DATE_INVALID); + } + + if (error.hasError(SslError.SSL_EXPIRED)) { + certError |= (1 << SslError.SSL_EXPIRED); + } + + if (error.hasError(SslError.SSL_IDMISMATCH)) { + certError |= (1 << SslError.SSL_IDMISMATCH); + } + + if (error.hasError(SslError.SSL_INVALID)) { + certError |= (1 << SslError.SSL_INVALID); + } + + if (error.hasError(SslError.SSL_NOTYETVALID)) { + certError |= (1 << SslError.SSL_NOTYETVALID); + } + + if (error.hasError(SslError.SSL_UNTRUSTED)) { + certError |= (1 << SslError.SSL_UNTRUSTED); + } + + bundle.putInt(SiteSpecificPreferencesFragment.EXTRA_SECURITY_CERT_ERR, certError); + } + + Bitmap favicon = mUiController.getCurrentTab().getFavicon(); + if (favicon != null) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + favicon.compress(Bitmap.CompressFormat.PNG, 50, baos); + bundle.putByteArray(SiteSpecificPreferencesFragment.EXTRA_FAVICON, + baos.toByteArray()); + } + BrowserPreferencesPage.startPreferenceFragmentExtraForResult( + mUiController.getActivity(), + SiteSpecificPreferencesFragment.class.getName(), bundle, 0); + } + @Override public void onClick(View v) { if (mMore == v) { @@ -422,6 +603,8 @@ public class NavigationBarBase extends LinearLayout implements } public void onProgressStarted() { + mFaviconBadge.setImageResource(R.drawable.ic_fav_overlay_normal); + mSecurityState = Tab.SecurityState.SECURITY_STATE_NOT_SECURE; } public void onProgressStopped() { diff --git a/src/com/android/browser/NavigationBarPhone.java b/src/com/android/browser/NavigationBarPhone.java index cb6f7fc6..e5f76ff8 100644 --- a/src/com/android/browser/NavigationBarPhone.java +++ b/src/com/android/browser/NavigationBarPhone.java @@ -17,13 +17,16 @@ package com.android.browser; import android.content.Context; import android.content.res.Resources; +import android.graphics.Bitmap; import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; +import org.codeaurora.swe.Engine; import org.codeaurora.swe.WebRefiner; import org.codeaurora.swe.WebView; import org.codeaurora.swe.util.Activator; @@ -32,6 +35,10 @@ import org.codeaurora.swe.util.Observable; import android.widget.ImageView; import android.widget.TextView; import com.android.browser.UrlInputView.StateListener; +import com.android.browser.preferences.AboutPreferencesFragment; +import com.android.browser.preferences.SiteSpecificPreferencesFragment; + +import java.io.ByteArrayOutputStream; public class NavigationBarPhone extends NavigationBarBase implements StateListener { @@ -149,6 +156,7 @@ public class NavigationBarPhone extends NavigationBarBase implements mStopButton.setVisibility(View.VISIBLE); } }*/ + mFaviconBadge.setImageResource(R.drawable.ic_fav_overlay_normal); mNotificationCounter.setVisibility(View.INVISIBLE); mHandler.removeMessages(MSG_UPDATE_NOTIFICATION_COUNTER); mHandler.sendEmptyMessageDelayed(MSG_UPDATE_NOTIFICATION_COUNTER, NOTIFICATION_COUNTER_UPDATE_DELAY); @@ -207,7 +215,7 @@ public class NavigationBarPhone extends NavigationBarBase implements } else if (mClearButton == v) { mUrlInput.setText(""); } else if (mComboIcon == v) { - mUiController.showPageInfo(); + showSiteSpecificSettings(); } else if (mVoiceButton == v) { mUiController.startVoiceRecognizer(); } else { diff --git a/src/com/android/browser/NavigationBarTablet.java b/src/com/android/browser/NavigationBarTablet.java index 31edce90..c6c88cd3 100644 --- a/src/com/android/browser/NavigationBarTablet.java +++ b/src/com/android/browser/NavigationBarTablet.java @@ -25,6 +25,7 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; @@ -33,6 +34,12 @@ import android.widget.ImageView; import com.android.browser.UI.ComboViews; import com.android.browser.UrlInputView.StateListener; +import com.android.browser.preferences.SiteSpecificPreferencesFragment; + +import org.codeaurora.swe.WebRefiner; +import org.codeaurora.swe.WebView; + +import java.io.ByteArrayOutputStream; public class NavigationBarTablet extends NavigationBarBase implements StateListener { @@ -105,6 +112,7 @@ public class NavigationBarTablet extends NavigationBarBase implements StateListe mVoiceButton.setOnClickListener(this); mUrlInput.setContainer(mUrlContainer); mUrlInput.setStateListener(this); + mUrlIcon.setOnClickListener(this); } public void onConfigurationChanged(Configuration config) { @@ -171,6 +179,8 @@ public class NavigationBarTablet extends NavigationBarBase implements StateListe clearOrClose(); } else if (mVoiceButton == v) { mUiController.startVoiceRecognizer(); + } else if (mUrlIcon == v) { + showSiteSpecificSettings(); } else { super.onClick(v); } @@ -188,6 +198,7 @@ public class NavigationBarTablet extends NavigationBarBase implements StateListe @Override public void setFavicon(Bitmap icon) { + super.setFavicon(icon); mFaviconDrawable = mBaseUi.getFaviconDrawable(icon); updateUrlIcon(); } diff --git a/src/com/android/browser/PageDialogsHandler.java b/src/com/android/browser/PageDialogsHandler.java index b92add9c..af54000f 100644 --- a/src/com/android/browser/PageDialogsHandler.java +++ b/src/com/android/browser/PageDialogsHandler.java @@ -353,23 +353,17 @@ public class PageDialogsHandler { return (View)ReflectHelper.invokeMethod(certificate, "inflateCertificateView",type, params); } - /* - * Creates an AlertDialog to display the given certificate. If error is - * null, text is added to state that the certificae is valid and the icon - * is set accordingly. If error is non-null, it must relate to the supplied - * certificate. In this case, error is used to add text describing the - * problems with the certificate and a different icon is used. - */ - private AlertDialog.Builder createSslCertificateDialog(SslCertificate certificate, - SslError error) { - View certificateView = inflateCertificateView(certificate, mContext); + public static AlertDialog.Builder createSslCertificateDialog(Context ctx, + SslCertificate certificate, + SslError error) { + View certificateView = inflateCertificateView(certificate, ctx); 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(mContext); + LayoutInflater factory = LayoutInflater.from(ctx); int iconId; if (error == null) { @@ -407,13 +401,25 @@ public class PageDialogsHandler { } } - return new AlertDialog.Builder(mContext) + return new AlertDialog.Builder(ctx) .setTitle(R.string.ssl_certificate) .setIcon(iconId) .setView(certificateView); } - private void addError(LayoutInflater inflater, LinearLayout parent, int error) { + /* + * Creates an AlertDialog to display the given certificate. If error is + * null, text is added to state that the certificae is valid and the icon + * is set accordingly. If error is non-null, it must relate to the supplied + * certificate. In this case, error is used to add text describing the + * problems with the certificate and a different icon is used. + */ + private AlertDialog.Builder createSslCertificateDialog(SslCertificate certificate, + SslError error) { + return createSslCertificateDialog(mContext, certificate, error); + } + + private static void addError(LayoutInflater inflater, LinearLayout parent, int error) { TextView textView = (TextView) inflater.inflate(R.layout.ssl_warning, parent, false); textView.setText(error); diff --git a/src/com/android/browser/PreferenceKeys.java b/src/com/android/browser/PreferenceKeys.java index 951a658a..7c7c2864 100644 --- a/src/com/android/browser/PreferenceKeys.java +++ b/src/com/android/browser/PreferenceKeys.java @@ -36,7 +36,7 @@ public interface PreferenceKeys { // Keys for advanced_preferences.xml // ---------------------- static final String PREF_AUTOFIT_PAGES = "autofit_pages"; - static final String PREF_BLOCK_POPUP_WINDOWS = "block_popup_windows"; + static final String PREF_POPUP_WINDOWS = "popup_windows"; static final String PREF_DEFAULT_TEXT_ENCODING = "default_text_encoding"; static final String PREF_ENABLE_JAVASCRIPT = "enable_javascript"; static final String PREF_ENABLE_MEMORY_MONITOR = "enable_memory_monitor"; @@ -59,7 +59,6 @@ public interface PreferenceKeys { // ---------------------- static final String PREF_AUTOFILL_ENABLED = "autofill_enabled"; static final String PREF_AUTOFILL_PROFILE = "autofill_profile"; - static final String PREF_WEB_REFINER_ENABLED = "web_refiner_enabled"; static final String PREF_HOMEPAGE = "homepage"; static final String PREF_POWERSAVE_ENABLED = "powersave_enabled"; static final String PREF_NIGHTMODE_ENABLED = "nightmode_enabled"; diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java index 99d57a88..a7157d07 100644 --- a/src/com/android/browser/Tab.java +++ b/src/com/android/browser/Tab.java @@ -1726,6 +1726,10 @@ class Tab implements PictureListener { return getDefaultFavicon(mContext); } + public boolean hasFavicon() { + return mCurrentState.mFavicon != null; + } + public boolean isBookmarkedSite() { return mCurrentState.mIsBookmarkedSite; } diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java index ec62a23e..addbf72b 100644 --- a/src/com/android/browser/XLargeUi.java +++ b/src/com/android/browser/XLargeUi.java @@ -21,6 +21,7 @@ import android.app.Activity; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.PaintDrawable; @@ -36,6 +37,7 @@ import android.view.ViewStub; import android.webkit.WebChromeClient; import org.codeaurora.swe.WebView; +import org.codeaurora.swe.util.ColorUtils; import com.android.browser.R; @@ -266,6 +268,13 @@ public class XLargeUi extends BaseUi { public void setFavicon(Tab tab) { super.setFavicon(tab); mTabBar.onFavicon(tab, tab.getFavicon()); + if (mActiveTab == tab) { + int color = NavigationBarBase.getSiteIconColor(tab.getUrl()); + if (tab.hasFavicon()) { + color = ColorUtils.getDominantColorForBitmap(tab.getFavicon()); + } + mActionBar.setBackgroundDrawable(new ColorDrawable(color)); + } } @Override diff --git a/src/com/android/browser/mdm/MdmCheckBoxPreference.java b/src/com/android/browser/mdm/MdmCheckBoxPreference.java index c235d522..91f9e038 100644 --- a/src/com/android/browser/mdm/MdmCheckBoxPreference.java +++ b/src/com/android/browser/mdm/MdmCheckBoxPreference.java @@ -32,6 +32,7 @@ package com.android.browser.mdm; import android.content.Context; import android.preference.CheckBoxPreference; import android.preference.Preference; +import android.preference.SwitchPreference; import android.util.AttributeSet; //import android.util.Log; import android.view.View; @@ -39,7 +40,7 @@ import android.widget.Toast; import com.android.browser.R; -public class MdmCheckBoxPreference extends CheckBoxPreference { +public class MdmCheckBoxPreference extends SwitchPreference { View mView = null; OnPreferenceClickListener mOrigClickListener = null; diff --git a/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java b/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java index 46fdd426..a505836b 100644 --- a/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java +++ b/src/com/android/browser/preferences/AccessibilityPreferencesFragment.java @@ -18,10 +18,8 @@ package com.android.browser.preferences; import android.app.ActionBar; import android.content.Context; -import android.content.res.Resources; import android.os.Bundle; import android.preference.Preference; -import android.preference.PreferenceFragment; import android.util.Log; import com.android.browser.BrowserSettings; @@ -30,7 +28,7 @@ import com.android.browser.R; import java.text.NumberFormat; -public class AccessibilityPreferencesFragment extends PreferenceFragment +public class AccessibilityPreferencesFragment extends SWEPreferenceFragment implements Preference.OnPreferenceChangeListener { NumberFormat mFormat; diff --git a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java index 98531284..36413802 100644 --- a/src/com/android/browser/preferences/AdvancedPreferencesFragment.java +++ b/src/com/android/browser/preferences/AdvancedPreferencesFragment.java @@ -21,7 +21,6 @@ import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.content.Intent; -import android.content.res.Resources; import android.content.SharedPreferences.Editor; import android.net.Uri; import android.preference.ListPreference; @@ -30,38 +29,21 @@ import android.preference.PreferenceCategory; import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.util.Log; -import android.webkit.ValueCallback; -import android.widget.Toast; -import android.text.TextUtils; import com.android.browser.BrowserActivity; -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; -import java.util.Map; -import java.util.Set; -import org.codeaurora.swe.GeolocationPermissions; -import org.codeaurora.swe.WebStorage; - public class AdvancedPreferencesFragment implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { - private static final int DOWNLOAD_PATH_RESULT_CODE = 1; - private final static String LOGTAG = "AdvancedPreferencesFragment"; - PreferenceFragment mFragment = null; AdvancedPreferencesFragment(PreferenceFragment fragment) { mFragment = fragment; - PreferenceScreen websiteSettings = (PreferenceScreen) mFragment.findPreference( - PreferenceKeys.PREF_WEBSITE_SETTINGS); - websiteSettings.setFragment(WebsiteSettingsFragment.class.getName()); - websiteSettings.setOnPreferenceClickListener(this); - Preference e = mFragment.findPreference(PreferenceKeys.PREF_RESET_DEFAULT_PREFERENCES); e.setOnPreferenceChangeListener(this); @@ -69,6 +51,9 @@ public class AdvancedPreferencesFragment 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"); @@ -83,23 +68,7 @@ public class AdvancedPreferencesFragment // Below are preferences for carrier specific features PreferenceScreen contentSettingsPrefScreen = (PreferenceScreen) mFragment.findPreference("content_settings"); - - if (!BrowserConfig.getInstance(mFragment.getActivity().getApplicationContext()) - .hasFeature(BrowserConfig.Feature.CUSTOM_DOWNLOAD_PATH)) { - contentSettingsPrefScreen.removePreference(contentSettingsPrefScreen - .findPreference(PreferenceKeys.PREF_DOWNLOAD_PATH)); - } else { - PreferenceScreen downloadPathPreset = - (PreferenceScreen) mFragment.findPreference(PreferenceKeys.PREF_DOWNLOAD_PATH); - downloadPathPreset.setOnPreferenceClickListener(onClickDownloadPathSettings()); - - String downloadPath = downloadPathPreset.getSharedPreferences(). - getString(PreferenceKeys.PREF_DOWNLOAD_PATH, - BrowserSettings.getInstance().getDownloadPath()); - String downloadPathForUser = DownloadHandler.getDownloadPathForUser(mFragment.getActivity(), - downloadPath); - downloadPathPreset.setSummary(downloadPathForUser); - } + contentSettingsPrefScreen.setOnPreferenceClickListener(this); ListPreference edgeSwipePref = (ListPreference) mFragment.findPreference("edge_swiping_action"); @@ -117,33 +86,8 @@ public class AdvancedPreferencesFragment } } - private Preference.OnPreferenceClickListener onClickDownloadPathSettings() { - return new Preference.OnPreferenceClickListener() { - public boolean onPreferenceClick(Preference preference) { - final String filemanagerIntent = - mFragment.getResources().getString(R.string.def_intent_file_manager); - if (!TextUtils.isEmpty(filemanagerIntent)) { - try { - Intent i = new Intent(filemanagerIntent); - mFragment.startActivityForResult(i, - DOWNLOAD_PATH_RESULT_CODE); - } catch (Exception e) { - String err_msg = mFragment.getResources().getString( - R.string.activity_not_found, - filemanagerIntent); - Toast.makeText(mFragment.getActivity(), err_msg, Toast.LENGTH_LONG).show(); - } - return true; - } else { - Log.e(LOGTAG, "File Manager intent not defined !!"); - return true; - } - } - }; - } - public void onActivityResult(int requestCode, int resultCode, Intent intent) { - if (requestCode == DOWNLOAD_PATH_RESULT_CODE) { + 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); @@ -182,25 +126,6 @@ public class AdvancedPreferencesFragment * changed after calling the WebsiteSettingsActivity. */ public void onResume() { - final PreferenceScreen websiteSettings = (PreferenceScreen) mFragment.findPreference( - PreferenceKeys.PREF_WEBSITE_SETTINGS); - websiteSettings.setEnabled(false); - WebStorage.getInstance().getOrigins(new ValueCallback<Map>() { - @Override - public void onReceiveValue(Map webStorageOrigins) { - if ((webStorageOrigins != null) && !webStorageOrigins.isEmpty()) { - websiteSettings.setEnabled(true); - } - } - }); - GeolocationPermissions.getInstance().getOrigins(new ValueCallback<Set<String> >() { - @Override - public void onReceiveValue(Set<String> geolocationOrigins) { - if ((geolocationOrigins != null) && !geolocationOrigins.isEmpty()) { - websiteSettings.setEnabled(true); - } - } - }); } @Override @@ -232,32 +157,39 @@ public class AdvancedPreferencesFragment public boolean onPreferenceClick(Preference preference) { FragmentManager fragmentManager = mFragment.getFragmentManager(); - if (preference.getKey().equals(PreferenceKeys.PREF_WEBSITE_SETTINGS)) { + if (preference.getKey().equals(PreferenceKeys.PREF_DEBUG_MENU)) { FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - Fragment newFragment = new WebsiteSettingsFragment(); + Fragment newFragment = new DebugPreferencesFragment(); fragmentTransaction.replace(mFragment.getId(), newFragment); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); return true; - } else if (preference.getKey().equals(PreferenceKeys.PREF_DEBUG_MENU)) { + } else if (preference.getKey().equals("accessibility_menu")) { FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - Fragment newFragment = new DebugPreferencesFragment(); + Fragment newFragment = new AccessibilityPreferencesFragment(); fragmentTransaction.replace(mFragment.getId(), newFragment); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); return true; - } else if (preference.getKey().equals("accessibility_menu")) { + } else if (preference.getKey().equals("privacy_security")) { FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - Fragment newFragment = new AccessibilityPreferencesFragment(); + 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/com/android/browser/preferences/ContentPreferencesFragment.java b/src/com/android/browser/preferences/ContentPreferencesFragment.java new file mode 100644 index 00000000..63bae5b9 --- /dev/null +++ b/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/com/android/browser/preferences/DebugPreferencesFragment.java b/src/com/android/browser/preferences/DebugPreferencesFragment.java index 09f19ef5..21e3080e 100644 --- a/src/com/android/browser/preferences/DebugPreferencesFragment.java +++ b/src/com/android/browser/preferences/DebugPreferencesFragment.java @@ -20,13 +20,10 @@ import android.app.ActionBar; import android.os.Bundle; import android.preference.Preference; import android.preference.Preference.OnPreferenceClickListener; -import android.preference.PreferenceFragment; -import com.android.browser.BrowserSettings; -import com.android.browser.PreferenceKeys; import com.android.browser.R; -public class DebugPreferencesFragment extends PreferenceFragment +public class DebugPreferencesFragment extends SWEPreferenceFragment implements OnPreferenceClickListener { @Override public void onCreate(Bundle savedInstanceState) { diff --git a/src/com/android/browser/preferences/GeneralPreferencesFragment.java b/src/com/android/browser/preferences/GeneralPreferencesFragment.java index 0629115d..07d53b10 100644 --- a/src/com/android/browser/preferences/GeneralPreferencesFragment.java +++ b/src/com/android/browser/preferences/GeneralPreferencesFragment.java @@ -30,7 +30,6 @@ import android.content.res.Resources; import android.os.Bundle; import android.preference.ListPreference; import android.preference.Preference; -import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.text.InputType; import android.text.TextUtils; @@ -52,7 +51,7 @@ import com.android.browser.mdm.DoNotTrackRestriction; import com.android.browser.mdm.MdmCheckBoxPreference; import com.android.browser.mdm.SearchEngineRestriction; -public class GeneralPreferencesFragment extends PreferenceFragment +public class GeneralPreferencesFragment extends SWEPreferenceFragment implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { static final String TAG = "GeneralPreferencesFragment"; @@ -112,7 +111,7 @@ public class GeneralPreferencesFragment extends PreferenceFragment DoNotTrackRestriction.getInstance().registerPreference(dntPref); mAdvFrag = new AdvancedPreferencesFragment(this); - mPrivFrag = new PrivacySecurityPreferencesFragment(this); + //mPrivFrag = new PrivacySecurityPreferencesFragment(this); } @Override diff --git a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java index bddcdec9..f7aa2179 100644 --- a/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java +++ b/src/com/android/browser/preferences/PrivacySecurityPreferencesFragment.java @@ -19,42 +19,172 @@ package com.android.browser.preferences; import com.android.browser.PreferenceKeys; import com.android.browser.R; +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.PreferenceFragment; -import android.preference.PreferenceManager; +import android.preference.PreferenceScreen; +import android.preference.TwoStatePreference; -public class PrivacySecurityPreferencesFragment - implements Preference.OnPreferenceChangeListener { +import org.codeaurora.swe.PermissionsServiceFactory; +import org.codeaurora.swe.WebRefiner; - PreferenceFragment mFragment; +public class PrivacySecurityPreferencesFragment extends SWEPreferenceFragment + implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { - PrivacySecurityPreferencesFragment(PreferenceFragment fragment) { - mFragment = fragment; + @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); - Preference e = mFragment.findPreference(PreferenceKeys.PREF_CLEAR_SELECTED_DATA); + Preference e = findPreference(PreferenceKeys.PREF_CLEAR_SELECTED_DATA); e.setOnPreferenceChangeListener(this); + + readAndShowPermission("enable_geolocation", + PermissionsServiceFactory.PermissionType.GEOLOCATION); + + readAndShowPermission("microphone", PermissionsServiceFactory.PermissionType.VOICE); + + readAndShowPermission("camera", PermissionsServiceFactory.PermissionType.VIDEO); + + readAndShowPermission("distracting_contents", + PermissionsServiceFactory.PermissionType.WEBREFINER); + + readAndShowPermission("popup_windows", PermissionsServiceFactory.PermissionType.POPUP); + + readAndShowPermission("accept_cookies", PermissionsServiceFactory.PermissionType.COOKIE); + + readAndShowPermission("accept_third_cookies", + PermissionsServiceFactory.PermissionType.THIRDPARTYCOOKIES); + } + + @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 = (boolean) objValue; if (pref.getKey().equals(PreferenceKeys.PREF_CLEAR_SELECTED_DATA)) { if (pref.getPreferenceManager().getDefaultSharedPreferences( - (Context)mFragment.getActivity()).getBoolean( + (Context) getActivity()).getBoolean( PreferenceKeys.PREF_PRIVACY_CLEAR_HISTORY, false)) { // Need to tell the browser to remove the parent/child relationship // between tabs - mFragment.getActivity().setResult(Activity.RESULT_OK, - (new Intent()).putExtra(Intent.EXTRA_TEXT, - pref.getKey())); + getActivity().setResult(Activity.RESULT_OK, + (new Intent()).putExtra(Intent.EXTRA_TEXT, pref.getKey())); return true; } } - return true; + if (pref.getKey().toString().equalsIgnoreCase("enable_geolocation")) { + PermissionsServiceFactory.setDefaultPermissions( + PermissionsServiceFactory.PermissionType.GEOLOCATION, flag); + return true; + } + + if (pref.getKey().toString().equalsIgnoreCase("microphone")) { + PermissionsServiceFactory.setDefaultPermissions( + PermissionsServiceFactory.PermissionType.VOICE, flag); + return true; + } + + if (pref.getKey().toString().equalsIgnoreCase("camera")) { + PermissionsServiceFactory.setDefaultPermissions( + PermissionsServiceFactory.PermissionType.VIDEO, flag); + return true; + } + + if (pref.getKey().toString().equalsIgnoreCase("distracting_contents")) { + WebRefiner refiner = WebRefiner.getInstance(); + PermissionsServiceFactory.setDefaultPermissions( + PermissionsServiceFactory.PermissionType.WEBREFINER, flag); + if (refiner != null) { + refiner.setRulesEnabled(WebRefiner.CATEGORY_ALL, !flag); + } + return true; + } + + if (pref.getKey().toString().equalsIgnoreCase("popup_windows")) { + PermissionsServiceFactory.setDefaultPermissions( + PermissionsServiceFactory.PermissionType.POPUP, flag); + 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); + } + return true; + } + + if (pref.getKey().toString().equalsIgnoreCase("accept_third_cookies")) { + PermissionsServiceFactory.setDefaultPermissions( + PermissionsServiceFactory.PermissionType.THIRDPARTYCOOKIES, flag); + 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(); + if (bar != null) { + bar.setTitle(R.string.pref_privacy_security_title); + bar.setDisplayHomeAsUpEnabled(false); + bar.setHomeButtonEnabled(false); + } + } } diff --git a/src/com/android/browser/preferences/SWEPreferenceFragment.java b/src/com/android/browser/preferences/SWEPreferenceFragment.java new file mode 100644 index 00000000..79781da0 --- /dev/null +++ b/src/com/android/browser/preferences/SWEPreferenceFragment.java @@ -0,0 +1,101 @@ +/* + * 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.os.Bundle; +import android.preference.PreferenceFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.Switch; + +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; + } + + 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/com/android/browser/preferences/SiteSpecificPreferencesFragment.java b/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java new file mode 100644 index 00000000..68c3ebc7 --- /dev/null +++ b/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java @@ -0,0 +1,689 @@ +/* + * 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.DialogInterface; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; +import android.net.http.SslCertificate; +import android.net.http.SslError; +import android.os.Bundle; +import android.os.Parcelable; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceScreen; +import android.preference.TwoStatePreference; +import android.text.TextUtils; +import android.view.View; +import android.webkit.ValueCallback; +import android.widget.Button; +import android.widget.TextView; + +import com.android.browser.NavigationBarBase; +import com.android.browser.PageDialogsHandler; +import com.android.browser.R; + +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.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_WEB_REFINER_INFO = "website_refiner_info"; + public static final String EXTRA_SECURITY_CERT = "website_security_cert"; + public static final String EXTRA_SECURITY_CERT_ERR = "website_security_cert_err"; + + private PermissionsServiceFactory.PermissionsService.OriginInfo mOriginInfo; + private PermissionsServiceFactory.PermissionsService mPermServ; + private ActionBar mBar; + private List<String> mLocationValues; + + private boolean mUsingDefaultSettings = true; + private int mOriginalActionBarOptions; + private int mIconColor = 0; + + private SslCertificate mSslCert; + private SslError mSslError; + + 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(); + } + } + + 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; + + @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); + + 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(mOriginText); + try { + URL url = new URL(mOriginText); + pref.setSummary("(" + url.getHost() + ")"); + } catch (MalformedURLException e) { + } + mOriginInfo = mPermServ.getOriginInfo(mOriginText); + setActionBarTitle(PermissionsServiceFactory.getPrettyUrl(mOriginText)); + updatePreferenceInfo(); + } + } + ); + + Bundle parcel = args.getParcelable(EXTRA_SECURITY_CERT); + mSslCert = (parcel != null) ? SslCertificate.restoreState(parcel) : null; + + if (mSslCert != null) { + int certErrors = args.getInt(EXTRA_SECURITY_CERT_ERR, 0); + + if (certErrors == 0) { + mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.INFO, + "Valid SSL Certificate. "); + } else { + mSslError = new SslError(-1, mSslCert, mOriginText); + + if ((certErrors & (1 << SslError.SSL_DATE_INVALID)) != 0) { + mSslError.addError(SslError.SSL_DATE_INVALID); + mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.ERROR, + "Invalid SSL Certificate. "); + } + + if ((certErrors & (1 << SslError.SSL_EXPIRED)) != 0) { + mSslError.addError(SslError.SSL_EXPIRED); + mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.ERROR, + "Invalid SSL Certificate. "); + } + + if ((certErrors & (1 << SslError.SSL_IDMISMATCH)) != 0) { + mSslError.addError(SslError.SSL_IDMISMATCH); + mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.ERROR, + "Invalid SSL Certificate. "); + } + + if ((certErrors & (1 << SslError.SSL_INVALID)) != 0) { + mSslError.addError(SslError.SSL_INVALID); + mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.ERROR, + "Invalid SSL Certificate. "); + } + + if ((certErrors & (1 << SslError.SSL_NOTYETVALID)) != 0) { + mSslError.addError(SslError.SSL_NOTYETVALID); + mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.WARNING, + "SSL Certificate warnings. "); + } + + if ((certErrors & (1 << SslError.SSL_UNTRUSTED)) != 0) { + mSslError.addError(SslError.SSL_UNTRUSTED); + mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.WARNING, + "SSL Certificate warnings. "); + } + } + } + + int adBlocks = args.getInt(EXTRA_WEB_REFINER_INFO, 0); + if (adBlocks > 0) { + mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.INFO, + getString(R.string.pref_web_refiner_blocked) + " " + adBlocks + " " + + getString(R.string.pref_web_refiner_advertisements)); + } + } + + 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 = new String(""); + + 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); + } + + 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); + 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()) { + warningText += ", "; + } + warningText += getString(R.string.pref_security_allow_mic); + } + + 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()) { + warningText += ", "; + } + warningText += getString(R.string.pref_security_allow_camera); + } + + if (!warningText.isEmpty()) { + warningText += " "; + warningText += getResources().getString(R.string.pref_security_access_is_allowed); + mSecurityViews.appendText(SiteSecurityViewFactory.ViewType.WARNING, warningText); + } + + showPermission("distracting_contents", PermissionsServiceFactory.PermissionType.WEBREFINER, + R.string.pref_security_allowed, R.string.pref_security_not_allowed); + + 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); + } + + if (mSecurityViews.mbEmpty) { + PreferenceScreen screen = (PreferenceScreen) + findPreference("site_specific_prefs"); + + pref = findPreference("site_security_info_title"); + screen.removePreference(pref); + } + + } + + @Override + public void onResume() { + super.onResume(); + 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)); + mBar.setBackgroundDrawable(new ColorDrawable(color)); + NavigationBarBase.setStatusAndNavigationBarColor(getActivity(), + NavigationBarBase.adjustColor(color, 1, 1, 0.7f)); + } + } else { + if (mIconColor != 0) { + mBar.setBackgroundDrawable(new ColorDrawable(mIconColor)); + NavigationBarBase.setStatusAndNavigationBarColor(getActivity(), + NavigationBarBase.adjustColor(mIconColor, 1, 1, 0.7f)); + } + } + } + } + } + + @Override + public void onPause() { + super.onPause(); + if (mBar != null) { + mBar.setDisplayOptions(mOriginalActionBarOptions); + NavigationBarBase.setStatusAndNavigationBarColor(getActivity(), + NavigationBarBase.getDefaultStatusBarColor()); + } + } + + 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.website_settings_clear_all_dialog_ok_button, + 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.useGlobalRulesForDomains(origins); + } + + finish(); + } + } + }) + .setNegativeButton( + R.string.website_settings_clear_all_dialog_cancel_button, 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) { + PageDialogsHandler.createSslCertificateDialog(getActivity(),mSslCert, mSslError) + .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 enable = (boolean) objValue; + String[] origins = new String[1]; + origins[0] = mOriginInfo.getOrigin(); + if (enable) { + refiner.enableRulesForDomains(WebRefiner.CATEGORY_ALL, origins); + } else { + refiner.disableRulesForDomains(WebRefiner.CATEGORY_ALL, origins); + } + } + 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); + } + 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.website_settings_clear_all_dialog_ok_button, + new AlertDialog.OnClickListener() { + public void onClick(DialogInterface dlg, int which) { + if (mOriginInfo != null) { + mOriginInfo.clearAllStoredData(); + Preference e = findPreference("clear_data"); + e.setSummary("(Empty)"); + } + } + }) + .setNegativeButton(R.string.website_settings_clear_all_dialog_cancel_button, null) + .setIconAttribute(android.R.attr.alertDialogIcon) + .show(); + } + return true; + } + +} diff --git a/src/com/android/browser/preferences/WebsiteSettingsFragment.java b/src/com/android/browser/preferences/WebsiteSettingsFragment.java index ad166357..7ffb5c17 100644 --- a/src/com/android/browser/preferences/WebsiteSettingsFragment.java +++ b/src/com/android/browser/preferences/WebsiteSettingsFragment.java @@ -25,18 +25,12 @@ import android.app.FragmentTransaction; import android.app.ListFragment; import android.content.Context; import android.content.DialogInterface; -import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; +import android.graphics.drawable.ColorDrawable; import android.net.Uri; -import android.os.AsyncTask; import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.preference.PreferenceActivity; -import android.util.Log; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -44,20 +38,21 @@ 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.WebStorageSizeManager; -import com.android.browser.platformsupport.BrowserContract.Bookmarks; import java.util.HashMap; -import java.util.HashSet; 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; /** @@ -66,78 +61,24 @@ import org.codeaurora.swe.WebStorage; * and Geolocation. */ public class WebsiteSettingsFragment extends ListFragment implements OnClickListener { - - private static final String EXTRA_SITE = "site"; - private static final long MILLIS_PER_DAY = 86400000; - private String LOGTAG = "WebsiteSettingsActivity"; - private static String sMBStored = null; private SiteAdapter mAdapter = null; - private Site mSite = null; - - protected long geolocationPolicyExpiration; - protected boolean geolocationPolicyOriginAllowed; - static class Site implements Parcelable { + private class Site { private String mOrigin; private String mTitle; private Bitmap mIcon; - private int mFeatures; - - // These constants provide the set of features that a site may support - // They must be consecutive. To add a new feature, add a new FEATURE_XXX - // variable with value equal to the current value of FEATURE_COUNT, then - // increment FEATURE_COUNT. - final static int FEATURE_WEB_STORAGE = 0; - final static int FEATURE_GEOLOCATION = 1; - // The number of features available. - final static int FEATURE_COUNT = 2; public Site(String origin) { mOrigin = origin; mTitle = null; mIcon = null; - mFeatures = 0; - } - - public void addFeature(int feature) { - mFeatures |= (1 << feature); - } - - public void removeFeature(int feature) { - mFeatures &= ~(1 << feature); - } - - public boolean hasFeature(int feature) { - return (mFeatures & (1 << feature)) != 0; - } - - /** - * Gets the number of features supported by this site. - */ - public int getFeatureCount() { - int count = 0; - for (int i = 0; i < FEATURE_COUNT; ++i) { - count += hasFeature(i) ? 1 : 0; - } - return count; - } - - /** - * Gets the ID of the nth (zero-based) feature supported by this site. - * The return value is a feature ID - one of the FEATURE_XXX values. - * This is required to determine which feature is displayed at a given - * position in the list of features for this site. This is used both - * when populating the view and when responding to clicks on the list. - */ - public int getFeatureByIndex(int n) { - int j = -1; - for (int i = 0; i < FEATURE_COUNT; ++i) { - j += hasFeature(i) ? 1 : 0; - if (j == n) { - return i; - } - } - return -1; + PermissionsServiceFactory.getFavicon(origin, getActivity(), + new ValueCallback<Bitmap>() { + @Override + public void onReceiveValue(Bitmap value) { + mIcon = value; + } + }); } public String getOrigin() { @@ -165,41 +106,11 @@ public class WebsiteSettingsFragment extends ListFragment implements OnClickList } 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 int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mOrigin); - dest.writeString(mTitle); - dest.writeInt(mFeatures); - dest.writeParcelable(mIcon, flags); - } - - private Site(Parcel in) { - mOrigin = in.readString(); - mTitle = in.readString(); - mFeatures = in.readInt(); - mIcon = in.readParcelable(null); - } - - public static final Parcelable.Creator<Site> CREATOR - = new Parcelable.Creator<Site>() { - public Site createFromParcel(Parcel in) { - return new Site(in); - } - - public Site[] newArray(int size) { - return new Site[size]; - } - }; - } class SiteAdapter extends ArrayAdapter<Site> @@ -207,188 +118,69 @@ public class WebsiteSettingsFragment extends ListFragment implements OnClickList private int mResource; private LayoutInflater mInflater; private Bitmap mDefaultIcon; - private Bitmap mUsageEmptyIcon; - private Bitmap mUsageLowIcon; - private Bitmap mUsageHighIcon; - private Bitmap mLocationAllowedIcon; - private Bitmap mLocationDisallowedIcon; - private Site mCurrentSite; + private PermissionsServiceFactory.PermissionsService mPermServ; + private boolean mReady; public SiteAdapter(Context context, int rsc) { - this(context, rsc, null); - } - - public SiteAdapter(Context context, int rsc, Site site) { super(context, rsc); mResource = rsc; mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mDefaultIcon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_deco_favicon_normal); - mUsageEmptyIcon = BitmapFactory.decodeResource(getResources(), - R.drawable.ic_list_data_off); - mUsageLowIcon = BitmapFactory.decodeResource(getResources(), - R.drawable.ic_list_data_small); - mUsageHighIcon = BitmapFactory.decodeResource(getResources(), - R.drawable.ic_list_data_large); - mLocationAllowedIcon = BitmapFactory.decodeResource(getResources(), - R.drawable.ic_action_gps_on); - mLocationDisallowedIcon = BitmapFactory.decodeResource(getResources(), - R.drawable.ic_action_gps_off); - mCurrentSite = site; - if (mCurrentSite == null) { - askForOrigins(); - } - } - /** - * Adds the specified feature to the site corresponding to supplied - * origin in the map. Creates the site if it does not already exist. - */ - private void addFeatureToSite(Map<String, Site> sites, String origin, int feature) { - Site site = null; - if (sites.containsKey(origin)) { - site = (Site) sites.get(origin); - } else { - site = new Site(origin); - sites.put(origin, site); - } - site.addFeature(feature); + mReady = false; + askForOrigins(); } public void askForOrigins() { - // Get the list of origins we want to display. - // All 'HTML 5 modules' (Database, Geolocation etc) form these - // origin strings using WebCore::SecurityOrigin::toString(), so it's - // safe to group origins here. Note that WebCore::SecurityOrigin - // uses 0 (which is not printed) for the port if the port is the - // default for the protocol. Eg http://www.google.com and - // http://www.google.com:80 both record a port of 0 and hence - // toString() == 'http://www.google.com' for both. - - WebStorage.getInstance().getOrigins(new ValueCallback<Map>() { - public void onReceiveValue(Map origins) { - Map<String, Site> sites = new HashMap<String, Site>(); - if (origins != null) { - Iterator<String> iter = origins.keySet().iterator(); - while (iter.hasNext()) { - addFeatureToSite(sites, iter.next(), Site.FEATURE_WEB_STORAGE); - } - } - askForGeolocation(sites); - } - }); - } - - public void askForGeolocation(final Map<String, Site> sites) { - GeolocationPermissions.getInstance().getOrigins(new ValueCallback<Set<String> >() { - public void onReceiveValue(Set<String> origins) { - if (origins != null) { - Iterator<String> iter = origins.iterator(); - while (iter.hasNext()) { - addFeatureToSite(sites, iter.next(), Site.FEATURE_GEOLOCATION); - } - } - populateIcons(sites); - populateOrigins(sites); - } - }); - } - - public void populateIcons(Map<String, Site> sites) { - // 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(this.getContext(), sites).execute(); - } - - private class UpdateFromBookmarksDbTask extends AsyncTask<Void, Void, Void> { + 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)); + } - private Context mContext; - private boolean mDataSetChanged; - private Map<String, Site> mSites; + // 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(); - public UpdateFromBookmarksDbTask(Context ctx, Map<String, Site> sites) { - mContext = ctx.getApplicationContext(); - mSites = sites; + populateOrigins(sites); + mReady = true; + } + } + ); } + } - protected Void doInBackground(Void... unused) { - HashMap<String, Set<Site>> hosts = new HashMap<String, Set<Site>>(); - Set<Map.Entry<String, Site>> elements = mSites.entrySet(); - Iterator<Map.Entry<String, Site>> originIter = elements.iterator(); - while (originIter.hasNext()) { - Map.Entry<String, Site> entry = originIter.next(); - Site site = entry.getValue(); - String host = Uri.parse(entry.getKey()).getHost(); - Set<Site> hostSites = null; - if (hosts.containsKey(host)) { - hostSites = (Set<Site>)hosts.get(host); - } else { - hostSites = new HashSet<Site>(); - hosts.put(host, hostSites); + 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) { + mPermServ.deleteOriginInfo(info); } - hostSites.add(site); } - // Check the bookmark DB. If we have data for a host used by any of - // our origins, use it to set their title and favicon - Cursor c = mContext.getContentResolver().query(Bookmarks.CONTENT_URI, - new String[] { Bookmarks.URL, Bookmarks.TITLE, Bookmarks.FAVICON }, - Bookmarks.IS_FOLDER + " == 0", null, null); - - if (c != null) { - if (c.moveToFirst()) { - int urlIndex = c.getColumnIndex(Bookmarks.URL); - int titleIndex = c.getColumnIndex(Bookmarks.TITLE); - int faviconIndex = c.getColumnIndex(Bookmarks.FAVICON); - do { - String url = c.getString(urlIndex); - String host = Uri.parse(url).getHost(); - if (hosts.containsKey(host)) { - String title = c.getString(titleIndex); - Bitmap bmp = null; - byte[] data = c.getBlob(faviconIndex); - if (data != null) { - bmp = BitmapFactory.decodeByteArray(data, 0, data.length); - } - Set matchingSites = (Set) hosts.get(host); - Iterator<Site> sitesIter = matchingSites.iterator(); - while (sitesIter.hasNext()) { - Site site = sitesIter.next(); - // We should only set the title if the bookmark is for the root - // (i.e. www.google.com), as website settings act on the origin - // as a whole rather than a single page under that origin. If the - // user has bookmarked a page under the root but *not* the root, - // then we risk displaying the title of that page which may or - // may not have any relevance to the origin. - if (url.equals(site.getOrigin()) || - (new String(site.getOrigin()+"/")).equals(url)) { - mDataSetChanged = true; - site.setTitle(title); - } - - if (bmp != null) { - mDataSetChanged = true; - site.setIcon(bmp); - } - } - } - } while (c.moveToNext()); - } - c.close(); - } - return null; - } - - protected void onPostExecute(Void unused) { - if (mDataSetChanged) { - notifyDataSetChanged(); + WebRefiner refiner = WebRefiner.getInstance(); + if (refiner != null) { + refiner.useGlobalRulesForDomains(originArray); } } } - - public void populateOrigins(Map<String, Site> sites) { + private void populateOrigins(Map<String, Site> sites) { clear(); // We can now simply populate our array with Site instances @@ -407,70 +199,12 @@ public class WebsiteSettingsFragment extends ListFragment implements OnClickList } } - public int getCount() { - if (mCurrentSite == null) { - return super.getCount(); - } - return mCurrentSite.getFeatureCount(); - } - - public String sizeValueToString(long bytes) { - // We display the size in MB, to 1dp, rounding up to the next 0.1MB. - // bytes should always be greater than zero. - if (bytes <= 0) { - Log.e(LOGTAG, "sizeValueToString called with non-positive value: " + bytes); - return "0"; - } - float megabytes = (float) bytes / (1024.0F * 1024.0F); - int truncated = (int) Math.ceil(megabytes * 10.0F); - float result = (float) (truncated / 10.0F); - return String.valueOf(result); - } - - /* - * If we receive the back event and are displaying - * site's settings, we want to go back to the main - * list view. If not, we just do nothing (see - * dispatchKeyEvent() below). - */ - public boolean backKeyPressed() { - if (mCurrentSite != null) { - mCurrentSite = null; - askForOrigins(); - return true; - } - return false; - } - - /** - * @hide - * Utility function - * Set the icon according to the usage - */ - public void setIconForUsage(ImageView usageIcon, long usageInBytes) { - float usageInMegabytes = (float) usageInBytes / (1024.0F * 1024.0F); - // We set the correct icon: - // 0 < empty < 0.1MB - // 0.1MB < low < 5MB - // 5MB < high - if (usageInMegabytes <= 0.1) { - usageIcon.setImageBitmap(mUsageEmptyIcon); - } else if (usageInMegabytes > 0.1 && usageInMegabytes <= 5) { - usageIcon.setImageBitmap(mUsageLowIcon); - } else if (usageInMegabytes > 5) { - usageIcon.setImageBitmap(mUsageHighIcon); - } - } - @Override public View getView(int position, View convertView, ViewGroup parent) { View view; final TextView title; final TextView subtitle; final ImageView icon; - final ImageView usageIcon; - final ImageView locationIcon; - final ImageView featureIcon; if (convertView == null) { view = mInflater.inflate(mResource, parent, false); @@ -481,106 +215,30 @@ public class WebsiteSettingsFragment extends ListFragment implements OnClickList title = (TextView) view.findViewById(R.id.title); subtitle = (TextView) view.findViewById(R.id.subtitle); icon = (ImageView) view.findViewById(R.id.icon); - featureIcon = (ImageView) view.findViewById(R.id.feature_icon); - usageIcon = (ImageView) view.findViewById(R.id.usage_icon); - locationIcon = (ImageView) view.findViewById(R.id.location_icon); - usageIcon.setVisibility(View.GONE); - locationIcon.setVisibility(View.GONE); - - if (mCurrentSite == null) { - - Site site = getItem(position); - 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); - } - - icon.setVisibility(View.VISIBLE); - usageIcon.setVisibility(View.INVISIBLE); - locationIcon.setVisibility(View.INVISIBLE); - featureIcon.setVisibility(View.GONE); - Bitmap bmp = site.getIcon(); - if (bmp == null) { - bmp = mDefaultIcon; - } - icon.setImageBitmap(bmp); - // We set the site as the view's tag, - // so that we can get it in onItemClick() - view.setTag(site); - - String origin = site.getOrigin(); - if (site.hasFeature(Site.FEATURE_WEB_STORAGE)) { - WebStorage.getInstance().getUsageForOrigin(origin, new ValueCallback<Long>() { - public void onReceiveValue(Long value) { - if (value != null) { - setIconForUsage(usageIcon, value.longValue()); - usageIcon.setVisibility(View.VISIBLE); - } - } - }); - } - if (site.hasFeature(Site.FEATURE_GEOLOCATION)) { - locationIcon.setVisibility(View.VISIBLE); - GeolocationPermissions.getInstance().getAllowed(origin, new ValueCallback<Boolean>() { - public void onReceiveValue(Boolean allowed) { - if (allowed != null) { - if (allowed.booleanValue()) { - locationIcon.setImageBitmap(mLocationAllowedIcon); - } else { - locationIcon.setImageBitmap(mLocationDisallowedIcon); - } - } - } - }); - } + Site site = getItem(position); + 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 { - icon.setVisibility(View.GONE); - locationIcon.setVisibility(View.GONE); - usageIcon.setVisibility(View.GONE); - featureIcon.setVisibility(View.VISIBLE); - String origin = mCurrentSite.getOrigin(); - switch (mCurrentSite.getFeatureByIndex(position)) { - case Site.FEATURE_WEB_STORAGE: - WebStorage.getInstance().getUsageForOrigin(origin, new ValueCallback<Long>() { - public void onReceiveValue(Long value) { - if (value != null) { - String usage = sizeValueToString(value.longValue()) + " " + sMBStored; - title.setText(R.string.webstorage_clear_data_title); - subtitle.setText(usage); - subtitle.setVisibility(View.VISIBLE); - setIconForUsage(featureIcon, value.longValue()); - } - } - }); - break; - case Site.FEATURE_GEOLOCATION: - title.setText(R.string.geolocation_settings_page_title); - GeolocationPermissions.getInstance().getAllowed(origin, new ValueCallback<Boolean>() { - public void onReceiveValue(Boolean allowed) { - if (allowed != null) { - if (allowed.booleanValue()) { - subtitle.setText(R.string.geolocation_settings_page_summary_allowed); - featureIcon.setImageBitmap(mLocationAllowedIcon); - } else { - subtitle.setText(R.string.geolocation_settings_page_summary_not_allowed); - featureIcon.setImageBitmap(mLocationDisallowedIcon); - } - subtitle.setVisibility(View.VISIBLE); - } - } - }); - break; - } + subtitle.setVisibility(View.GONE); + title.setMaxLines(2); + title.setSingleLine(false); + } + + icon.setVisibility(View.VISIBLE); + Bitmap bmp = site.getIcon(); + if (bmp == null) { + bmp = mDefaultIcon; } + icon.setImageBitmap(bmp); + // We set the site as the view's tag, + // so that we can get it in onItemClick() + view.setTag(site); return view; } @@ -589,142 +247,41 @@ public class WebsiteSettingsFragment extends ListFragment implements OnClickList View view, int position, long id) { - if (mCurrentSite != null) { - switch (mCurrentSite.getFeatureByIndex(position)) { - case Site.FEATURE_WEB_STORAGE: - new AlertDialog.Builder(getContext()) - .setMessage(R.string.webstorage_clear_data_dialog_message) - .setPositiveButton(R.string.webstorage_clear_data_dialog_ok_button, - new AlertDialog.OnClickListener() { - public void onClick(DialogInterface dlg, int which) { - WebStorage.getInstance().deleteOrigin(mCurrentSite.getOrigin()); - // If this site has no more features, then go back to the - // origins list. - mCurrentSite.removeFeature(Site.FEATURE_WEB_STORAGE); - if (mCurrentSite.getFeatureCount() == 0) { - finish(); - } - askForOrigins(); - notifyDataSetChanged(); - }}) - .setNegativeButton(R.string.webstorage_clear_data_dialog_cancel_button, null) - .setIconAttribute(android.R.attr.alertDialogIcon) - .show(); - break; - case Site.FEATURE_GEOLOCATION: - final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - final String origin = mCurrentSite.getOrigin(); - final GeolocationPermissions geolocationPermissions - = GeolocationPermissions.getInstance(); - - DialogInterface.OnClickListener alertDialogListener = - new AlertDialog.OnClickListener() { - public void onClick(DialogInterface dlg, int which) { - GeolocationPermissions geolocationPermissions = - GeolocationPermissions.getInstance(); - String origin = mCurrentSite.getOrigin(); - int selectedPosition = ((AlertDialog)dlg) - .getListView().getCheckedItemPosition(); - switch (selectedPosition) { - case 0: // Deny forever - geolocationPermissions.deny(origin); - break; - case 1: - // Allow for 24 hours - geolocationPermissions.allow(origin, - System.currentTimeMillis() + MILLIS_PER_DAY); - break; - case 2: // Allow forever - geolocationPermissions.allow(origin); - break; - case 3: // Always ask - geolocationPermissions.clear(origin); - mCurrentSite.removeFeature(Site.FEATURE_GEOLOCATION); - if (mCurrentSite.getFeatureCount() == 0) { - finish(); - } - break; - default: - break; - } - askForOrigins(); - notifyDataSetChanged(); - }}; - - builder.setTitle(String.format(getResources() - .getString(R.string.geolocation_settings_page_dialog_title), - "http".equals(Uri.parse(mCurrentSite.getOrigin()).getScheme()) ? - origin.substring(7) : origin )) - .setPositiveButton(R.string.geolocation_settings_page_dialog_ok_button, - alertDialogListener) - .setNegativeButton(R.string.geolocation_settings_page_dialog_cancel_button, null); - - switch(geolocationPermissions.getContentSetting(origin)) { - case BLOCK: - builder.setSingleChoiceItems(R.array.geolocation_settings_choices, - 0, null); - break; - case ALLOW_24H: - builder.setSingleChoiceItems(R.array.geolocation_settings_choices, - 1, null); - break; - case ALLOW: - builder.setSingleChoiceItems(R.array.geolocation_settings_choices, - 2, null); - break; - } - builder.show(); - } - } else { - Site site = (Site) view.getTag(); - Activity activity = getActivity(); - if (activity != null) { - Bundle args = new Bundle(); - args.putParcelable(EXTRA_SITE, site); - - FragmentManager fragmentManager = activity.getFragmentManager(); - FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); - - Fragment newFragment = new WebsiteSettingsFragment(); - newFragment.setArguments(args); - fragmentTransaction.replace(getId(), newFragment); - fragmentTransaction.addToBackStack(null); - fragmentTransaction.commit(); - } + Site site = (Site) view.getTag(); + Activity activity = getActivity(); + if (activity != null) { + Bundle args = new Bundle(); + args.putString(SiteSpecificPreferencesFragment.EXTRA_ORIGIN, site.getOrigin()); + + FragmentManager fragmentManager = activity.getFragmentManager(); + FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); + + Fragment newFragment = new SiteSpecificPreferencesFragment(); + newFragment.setArguments(args); + fragmentTransaction.replace(getId(), newFragment); + fragmentTransaction.addToBackStack(null); + fragmentTransaction.commit(); } } - - public Site currentSite() { - return mCurrentSite; - } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.swe_website_settings, container, false); - Bundle args = getArguments(); - if (args != null) { - mSite = (Site) args.getParcelable(EXTRA_SITE); - } - if (mSite == null) { - View clear = view.findViewById(R.id.clear_all_button); - clear.setVisibility(View.VISIBLE); - clear.setOnClickListener(this); - } + 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); - if (sMBStored == null) { - sMBStored = getString(R.string.webstorage_origin_summary_mb_stored); - } mAdapter = new SiteAdapter(getActivity(), R.layout.website_settings_row); - if (mSite != null) { - mAdapter.mCurrentSite = mSite; - } getListView().setAdapter(mAdapter); getListView().setOnItemClickListener(mAdapter); } @@ -738,6 +295,7 @@ public class WebsiteSettingsFragment extends ListFragment implements OnClickList bar.setTitle(R.string.pref_extras_website_settings); bar.setDisplayHomeAsUpEnabled(false); bar.setHomeButtonEnabled(false); + bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.accent))); } } @@ -752,24 +310,53 @@ public class WebsiteSettingsFragment extends ListFragment implements OnClickList 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. + // 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.website_settings_clear_all_dialog_ok_button, + .setMessage(R.string.website_settings_clear_all_dialog_message) + .setPositiveButton(R.string.website_settings_clear_all_dialog_ok_button, + new AlertDialog.OnClickListener() { + public void onClick(DialogInterface dlg, int which) { + mAdapter.deleteAllOrigins(); + WebStorage.getInstance().deleteAllData(); + GeolocationPermissions.getInstance().clearAll(); + if (GeolocationPermissions.isIncognitoCreated()) { + GeolocationPermissions.getIncognitoInstance().clearAll(); + } + WebStorageSizeManager.resetLastOutOfSpaceNotificationTime(); + mAdapter.askForOrigins(); + finish(); + } + }) + .setNegativeButton(R.string.website_settings_clear_all_dialog_cancel_button, 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 dlg, int which) { - WebStorage.getInstance().deleteAllData(); - GeolocationPermissions.getInstance().clearAll(); - if (GeolocationPermissions.isIncognitoCreated()) { - GeolocationPermissions.getIncognitoInstance().clearAll(); - } - WebStorageSizeManager.resetLastOutOfSpaceNotificationTime(); - mAdapter.askForOrigins(); - finish(); + 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.website_settings_clear_all_dialog_cancel_button, null) - .setIconAttribute(android.R.attr.alertDialogIcon) + .setNegativeButton(R.string.pref_security_cancel, null) .show(); + break; } } |