diff options
27 files changed, 743 insertions, 147 deletions
diff --git a/res/drawable-xxhdpi/img_tile_background.9.png b/res/drawable-xxhdpi/img_tile_background.9.png Binary files differnew file mode 100644 index 00000000..9ef7ae5a --- /dev/null +++ b/res/drawable-xxhdpi/img_tile_background.9.png diff --git a/res/layout/bookmark_thumbnail.xml b/res/layout/bookmark_thumbnail.xml index df9e8535..8913551d 100644 --- a/res/layout/bookmark_thumbnail.xml +++ b/res/layout/bookmark_thumbnail.xml @@ -18,46 +18,24 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingStart="@dimen/combo_horizontalSpacing" - android:paddingEnd="@dimen/combo_horizontalSpacing" android:layout_margin="@dimen/combo_bookmark_thumbnail_margin" - android:background="@drawable/bookmark_thumb_selector" android:orientation="vertical" - > - - <FrameLayout - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <com.android.browser.view.BookmarkThumbImageView - android:id="@+id/thumb_image" - android:layout_width="@dimen/bookmarkThumbnailWidth" - android:layout_height="@dimen/bookmarkThumbnailHeight" - android:paddingTop="2dip" - android:scaleType="centerCrop" - android:src="@drawable/browser_thumbnail" - /> - - <LinearLayout - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:layout_gravity="bottom" - android:background="@color/bookmarkWidgetFolderBackground" - android:orientation="vertical" > - - <TextView - android:id="@+id/label" - android:layout_width="@dimen/bookmarkThumbnailWidth" - android:layout_height="wrap_content" - android:ellipsize="marquee" - android:paddingStart="8dip" - android:paddingEnd="4dip" - android:paddingTop="2dip" - android:paddingBottom="2dip" - android:singleLine="true" - android:textAppearance="@style/BookmarkText" - /> - </LinearLayout> - </FrameLayout> - + android:paddingEnd="@dimen/combo_horizontalSpacing" + android:paddingStart="@dimen/combo_horizontalSpacing" > + + <com.android.browser.SiteTileView + android:id="@+id/thumb_image" + android:layout_width="@dimen/bookmarkThumbnailWidth" + android:layout_height="@dimen/bookmarkThumbnailHeight" /> + + <TextView + android:id="@+id/label" + android:layout_width="@dimen/bookmarkThumbnailWidth" + android:layout_height="wrap_content" + android:gravity="center" + android:ellipsize="marquee" + android:lines="2" + android:paddingBottom="2dip" + android:paddingTop="2dip" + android:textAppearance="@style/BookmarkText" /> </com.android.browser.view.BookmarkContainer> diff --git a/res/layout/bookmarks.xml b/res/layout/bookmarks.xml index d4238f5c..7eee4e9b 100644 --- a/res/layout/bookmarks.xml +++ b/res/layout/bookmarks.xml @@ -18,6 +18,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" + android:background="@color/comboViewBackground" android:paddingTop="@dimen/combo_paddingTop"> <FrameLayout diff --git a/res/layout/history.xml b/res/layout/history.xml index 1636fe6a..c2444233 100644 --- a/res/layout/history.xml +++ b/res/layout/history.xml @@ -19,6 +19,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" + android:background="@color/comboViewBackground" android:paddingTop="@dimen/combo_paddingTop"> <FrameLayout diff --git a/res/layout/history_item.xml b/res/layout/history_item.xml index cd236d5e..332dc364 100644 --- a/res/layout/history_item.xml +++ b/res/layout/history_item.xml @@ -20,15 +20,12 @@ android:minHeight="?android:attr/listPreferredItemHeight" android:orientation="horizontal"> - <ImageView + <com.android.browser.SiteTileView android:id="@+id/favicon" - android:layout_width="32dip" - android:layout_height="32dip" - android:layout_gravity="center_vertical" - android:layout_marginStart="12dip" - android:background="@drawable/bookmark_list_favicon_bg" - android:scaleType="fitXY" - android:src="@drawable/ic_deco_favicon_normal" /> + android:layout_width="36dip" + android:layout_height="36dip" + android:layout_gravity="center" + android:layout_marginStart="12dip" /> <LinearLayout android:layout_width="0dip" diff --git a/res/layout/site_specific_security_info.xml b/res/layout/site_specific_security_info.xml index 31560df4..700d0c27 100644 --- a/res/layout/site_specific_security_info.xml +++ b/res/layout/site_specific_security_info.xml @@ -31,7 +31,6 @@ 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" @@ -50,10 +49,15 @@ android:minHeight="?android:attr/listPreferredItemHeightSmall" android:gravity="center_vertical" > + <!--Padding--> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="20dip" /> + <ImageView android:gravity="center" android:src="@drawable/ic_sp_level_severe" - android:minWidth="40dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> @@ -61,6 +65,7 @@ android:id="@+id/security_view_text" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginStart="10dip" android:gravity="start" /> </LinearLayout> @@ -72,10 +77,15 @@ android:minHeight="?android:attr/listPreferredItemHeightSmall" android:gravity="center_vertical" > + <!--Padding--> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="20dip" /> + <ImageView android:gravity="center" android:src="@drawable/ic_sp_level_warning" - android:minWidth="40dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> @@ -83,6 +93,7 @@ android:id="@id/security_view_text" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginStart="10dip" android:gravity="start" /> </LinearLayout> @@ -94,10 +105,15 @@ android:minHeight="?android:attr/listPreferredItemHeightSmall" android:gravity="center_vertical" > + <!--Padding--> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="20dip" /> + <ImageView android:src="@drawable/ic_sp_level_good" android:gravity="center" - android:minWidth="40dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> @@ -105,6 +121,7 @@ android:id="@id/security_view_text" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginStart="10dip" android:gravity="start" /> </LinearLayout> </LinearLayout> diff --git a/res/layout/snapshot_item.xml b/res/layout/snapshot_item.xml index 01153564..c3ce866c 100644 --- a/res/layout/snapshot_item.xml +++ b/res/layout/snapshot_item.xml @@ -53,8 +53,7 @@ android:paddingStart="8dip" android:gravity="center_vertical" android:typeface="sans" - android:textSize="12sp" - android:textColor="#AAAAAA" + android:textAppearance="@style/BookmarkText" android:lines="2" /> <ImageView android:id="@+id/divider" diff --git a/res/layout/snapshots.xml b/res/layout/snapshots.xml index 30d4ca44..d01809e6 100644 --- a/res/layout/snapshots.xml +++ b/res/layout/snapshots.xml @@ -18,6 +18,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/comboViewBackground" android:paddingTop="@dimen/combo_paddingTop"> <com.android.browser.view.SnapshotGridView diff --git a/res/layout/swe_preference_custom_actionbar.xml b/res/layout/swe_preference_custom_actionbar.xml index 9dca94df..44eb1de7 100644 --- a/res/layout/swe_preference_custom_actionbar.xml +++ b/res/layout/swe_preference_custom_actionbar.xml @@ -30,7 +30,7 @@ <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:text="@string/pref_extras_reset" android:background="@android:color/transparent" android:layout_gravity="end" android:layout_width="wrap_content" diff --git a/res/values-land/dimensions.xml b/res/values-land/dimensions.xml index 262ca488..5fd3d125 100644 --- a/res/values-land/dimensions.xml +++ b/res/values-land/dimensions.xml @@ -17,5 +17,5 @@ <dimen name="preference_widget_width">72dp</dimen> <dimen name="nav_tab_width">225dip</dimen> <dimen name="nav_tab_height">150dip</dimen> - <dimen name="combo_paddingTop">60dip</dimen> + <dimen name="combo_paddingTop">56dip</dimen> </resources> diff --git a/res/values-v17/styles.xml b/res/values-v17/styles.xml index 73eed02e..f251c030 100644 --- a/res/values-v17/styles.xml +++ b/res/values-v17/styles.xml @@ -62,9 +62,11 @@ </style> <style name="BookmarkText"> - <item name="android:textSize">16sp</item> - <item name="android:textColor">@color/white</item> - <item name="android:fontFamily">sans-serif-light</item> + <item name="android:textSize">12sp</item> + <item name="android:textColor">@color/black</item> + <item name="android:textStyle">normal</item> + <item name="android:textAlignment">center</item> + <item name="android:fontFamily">roboto</item> </style> <style name="ShortcutTheme" parent="@style/BrowserBase"> diff --git a/res/values/attrs_site_tile_view.xml b/res/values/attrs_site_tile_view.xml new file mode 100644 index 00000000..1cc6c59c --- /dev/null +++ b/res/values/attrs_site_tile_view.xml @@ -0,0 +1,35 @@ +<!-- + 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. +--> +<resources> + <declare-styleable name="SiteTileView"> + <attr name="android:src" /> + <attr name="flat" format="boolean|reference" /> + <attr name="floating" format="boolean|reference" /> + </declare-styleable> +</resources> diff --git a/res/values/colors.xml b/res/values/colors.xml index 480ca7d6..3efdd390 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -49,8 +49,11 @@ <color name="bookmarkListFaviconBackground">#23ffffff</color> <color name="bookmarkLabelColor">#555555</color> <color name="comboViewActionBarColor">#ffffff</color> + <color name="comboViewBackground">#efeff0</color> <color name="tabFaviconBackground">#FF555555</color> <color name="tabFocusHighlight">#FF99CC00</color> <color name="tabViewTitleBackground">#D0000000</color> <color name="navtab_bg">#80606060</color> + + <color name="SiteTileOverline">#666</color> </resources> diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml index 9ddfb98e..f2e47100 100755 --- a/res/values/dimensions.xml +++ b/res/values/dimensions.xml @@ -19,8 +19,8 @@ <dimen name="tab_slice">15.5dp</dimen> <dimen name="tab_focus_stroke">2dip</dimen> <dimen name="max_tab_width">300dp</dimen> - <dimen name="bookmarkThumbnailWidth">100dip</dimen> - <dimen name="bookmarkThumbnailHeight">100dip</dimen> + <dimen name="bookmarkThumbnailWidth">90dip</dimen> + <dimen name="bookmarkThumbnailHeight">90dip</dimen> <!--Add for Navigation Feature --> <dimen name="mynav_item_width">80px</dimen> <dimen name="mynav_item_width_portrait">80px</dimen> @@ -48,8 +48,8 @@ <dimen name="widgetVerticalSpacing">6dip</dimen> <dimen name="widgetColumnWidth">80dip</dimen> <!-- For the combined Bookmarks History view --> - <dimen name="combo_paddingTop">50dip</dimen> - <dimen name="combo_horizontalSpacing">6dip</dimen> + <dimen name="combo_paddingTop">48dip</dimen> + <dimen name="combo_horizontalSpacing">8dip</dimen> <dimen name="combo_bookmark_thumbnail_margin">4dip</dimen> <dimen name="combo_snapshot_item_padding">12dip</dimen> <dimen name="combo_shadow_height">8dip</dimen> @@ -85,4 +85,6 @@ <dimen name="edge_swipe_in_slop">25dp</dimen> <dimen name="edge_swipe_in_additional_slop">50dp</dimen> <dimen name="edge_swipe_out_slop">18dp</dimen> + + <dimen name="SiteTileOverline">1dp</dimen> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index f0436c9c..3172642e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -529,7 +529,7 @@ <!-- Settings summmary --> <string name="pref_security_show_security_warning_summary">Show warning if there\'s a problem with a site\'s security</string> <!-- Settings Label --> - <string name="pref_do_not_track">Do Not Track</string> + <string name="pref_do_not_track">Request \'Do Not Track\'</string> <!-- Settings summary --> <string name="pref_do_not_track_summary">Send a Do Not Track request with your browsing traffic</string> <!-- Settings label --> @@ -539,13 +539,15 @@ <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_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_security_on">On</string> + <string name="pref_security_off">Off</string> <string name="pref_website_title">Website</string> <string name="pref_security_add">Add</string> <string name="pref_security_cancel">Cancel</string> @@ -597,13 +599,14 @@ <!-- Settings screen, section title [CHAR LIMIT=50] --> <string name="pref_extras_title">Advanced</string> <!-- Settings label --> - <string name="pref_extras_website_settings">Per Site 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] --> <string name="pref_extras_reset_default_title">Reset defaults</string> <!-- Settings label --> <string name="pref_extras_reset_default">Reset to default</string> + <string name="pref_extras_reset">Reset</string> <!-- Settings summary --> <string name="pref_extras_reset_default_summary">Restore default settings</string> <!-- Confirmation dialog message --> @@ -667,7 +670,7 @@ <item>auto</item> </string-array> <string name="pref_default_text_encoding_default">UTF-8</string> - <string name="pref_edge_swipe_title">Edge Swipe</string> + <string name="pref_edge_swipe_title">Edge swipe</string> <string name="pref_edge_swipe_option_msg">When swiping, would you like:</string> <string name="pref_temporal_edge_swipe">Previous/Next Web Site</string> <string name="pref_spatial_edge_swipe">Change Tab</string> @@ -890,7 +893,7 @@ <string name="webstorage_outofspace_notification_text">Touch to free up space.</string> <!-- Used in the Browser Settings --> <string name="webstorage_clear_data_title">Storage</string> - <string name="webstorage_private_data_title">Private Data</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> diff --git a/res/xml/privacy_and_security_preferences.xml b/res/xml/privacy_and_security_preferences.xml index 37eeaf8b..b15509fe 100644 --- a/res/xml/privacy_and_security_preferences.xml +++ b/res/xml/privacy_and_security_preferences.xml @@ -36,8 +36,8 @@ 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:summaryOn="@string/pref_security_on" + android:summaryOff="@string/pref_security_off" android:title="@string/pref_do_not_track" /> <SwitchPreference @@ -128,6 +128,24 @@ android:title="@string/pref_default_site_settings_title"> <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="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" /> + + <SwitchPreference + android:layout="@layout/swe_preference" android:defaultValue="true" android:icon="@drawable/ic_sp_location" android:key="enable_geolocation" @@ -156,29 +174,11 @@ <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 index 19aac5cd..63e03b0f 100644 --- a/res/xml/site_specific_preferences.xml +++ b/res/xml/site_specific_preferences.xml @@ -36,6 +36,7 @@ android:title="@string/pref_website_title" > <Preference android:layout="@layout/swe_preference" + android:selectable="false" android:key="site_name"/> </PreferenceCategory> @@ -46,6 +47,7 @@ <PreferenceScreen android:key="site_security_info" + android:selectable="false" android:layout="@layout/site_specific_security_info"/> </PreferenceCategory> @@ -54,6 +56,24 @@ android:layout="@layout/swe_preference_category" android:key="reset_default"> + <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="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" /> + <ListPreference android:layout="@layout/swe_preference" android:widgetLayout="@layout/swe_preference_list_widget" @@ -85,30 +105,12 @@ <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" diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java index 884cdc4d..a50a7d64 100644 --- a/src/com/android/browser/AddBookmarkPage.java +++ b/src/com/android/browser/AddBookmarkPage.java @@ -657,6 +657,7 @@ public class AddBookmarkPage extends Activity String title = null; String url = null; + mTouchIconUrl = null; mFakeTitle = (TextView) findViewById(R.id.fake_title); if (mMap != null) { @@ -838,7 +839,7 @@ public class AddBookmarkPage extends Activity Bookmarks.addBookmark(AddBookmarkPage.this, false, url, title, thumbnail, mCurrentFolder); if (touchIconUrl != null) { - new DownloadTouchIcon(mContext, cr, url).execute(mTouchIconUrl); + new DownloadTouchIcon(mContext, cr, url).execute(touchIconUrl); } mMessage.arg1 = 1; } catch (IllegalStateException e) { @@ -1083,7 +1084,9 @@ public class AddBookmarkPage extends Activity } else { bundle.putParcelable(BrowserContract.Bookmarks.THUMBNAIL, thumbnail); bundle.putBoolean(REMOVE_THUMBNAIL, !urlUnmodified); - bundle.putString(TOUCH_ICON_URL, mTouchIconUrl); + if (mTouchIconUrl != null) { + bundle.putString(TOUCH_ICON_URL, mTouchIconUrl); + } // Post a message to write to the DB. Message msg = Message.obtain(mHandler, SAVE_BOOKMARK); msg.setData(bundle); diff --git a/src/com/android/browser/BookmarkItem.java b/src/com/android/browser/BookmarkItem.java index b230de6c..12b2b705 100644 --- a/src/com/android/browser/BookmarkItem.java +++ b/src/com/android/browser/BookmarkItem.java @@ -16,18 +16,14 @@ package com.android.browser; -import com.android.browser.R; - import android.content.Context; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; -import android.text.method.ScrollingMovementMethod; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ScrollView; -import android.widget.ImageView; import android.widget.TextView; /** @@ -37,13 +33,14 @@ class BookmarkItem extends ScrollView { final static int MAX_TEXTVIEW_LEN = 80; - protected TextView mTextView; - protected TextView mUrlText; - protected ImageView mImageView; - protected String mUrl; - protected String mTitle; + protected TextView mTextView; + protected TextView mUrlText; + protected SiteTileView mTileView; + protected String mUrl; + protected String mTitle; protected boolean mEnableScrolling = false; + protected Bitmap mBitmap; /** * Instantiate a bookmark item, including a default favicon. * @@ -58,22 +55,12 @@ class BookmarkItem extends ScrollView { factory.inflate(R.layout.history_item, this); mTextView = (TextView) findViewById(R.id.title); mUrlText = (TextView) findViewById(R.id.url); - mImageView = (ImageView) findViewById(R.id.favicon); + mTileView = (SiteTileView) findViewById(R.id.favicon); View star = findViewById(R.id.star); star.setVisibility(View.GONE); } /** - * Copy this BookmarkItem to item. - * @param item BookmarkItem to receive the info from this BookmarkItem. - */ - /* package */ void copyTo(BookmarkItem item) { - item.mTextView.setText(mTextView.getText()); - item.mUrlText.setText(mUrlText.getText()); - item.mImageView.setImageDrawable(mImageView.getDrawable()); - } - - /** * Return the name assigned to this bookmark item. */ /* package */ String getName() { @@ -92,18 +79,17 @@ class BookmarkItem extends ScrollView { */ /* package */ void setFavicon(Bitmap b) { if (b != null) { - mImageView.setImageBitmap(b); - } else { - mImageView.setImageResource(R.drawable.ic_deco_favicon_normal); + mTileView.replaceFavicon(b); + mBitmap = b; } } public int getFavIconIntrinsicWidth() { - return mImageView.getDrawable().getIntrinsicWidth(); + return mTileView.getMeasuredWidth(); } void setFaviconBackground(Drawable d) { - mImageView.setBackgroundDrawable(d); + mTileView.setBackgroundDrawable(d); } /** diff --git a/src/com/android/browser/BrowserBookmarksAdapter.java b/src/com/android/browser/BrowserBookmarksAdapter.java index 38e07e07..cef6e626 100644 --- a/src/com/android/browser/BrowserBookmarksAdapter.java +++ b/src/com/android/browser/BrowserBookmarksAdapter.java @@ -24,6 +24,7 @@ import android.graphics.drawable.BitmapDrawable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.TextView; import com.android.browser.mdm.EditBookmarksRestriction; @@ -85,7 +86,7 @@ public class BrowserBookmarksAdapter extends .getDimensionPixelSize(R.dimen.combo_horizontalSpacing); view.setPadding(padding, view.getPaddingTop(), padding, view.getPaddingBottom()); - BookmarkThumbImageView thumb = (BookmarkThumbImageView) view.findViewById(R.id.thumb_image); + SiteTileView thumb = (SiteTileView) view.findViewById(R.id.thumb_image); TextView tv = (TextView) view.findViewById(R.id.label); tv.setText(item.title); int containerWidth = thumb.getWidth() - thumb.getPaddingLeft() - thumb.getPaddingRight(); @@ -94,7 +95,8 @@ public class BrowserBookmarksAdapter extends if (item.is_folder) { b = BitmapFactory.decodeResource(mContext.getResources(), - R.drawable.thumb_bookmark_widget_folder_holo); + R.drawable.ic_deco_folder_normal); + thumb.setFloating(true); } else if (item.thumbnail == null || !item.has_thumbnail) { b = BitmapFactory.decodeResource(mContext.getResources(), @@ -105,7 +107,8 @@ public class BrowserBookmarksAdapter extends } // If the item is managed by mdm or edit bookmark restriction enabled - if (containerWidth != 0 && (item.is_mdm_managed || EditBookmarksRestriction.getInstance().isEnabled())) { + if (containerWidth != 0 && (item.is_mdm_managed || + EditBookmarksRestriction.getInstance().isEnabled())) { int iconResId; float overlayScale, overlayVertPos; @@ -122,11 +125,12 @@ public class BrowserBookmarksAdapter extends float willScale = (float) containerWidth / (float) b.getWidth(); Bitmap bm = BrowserBookmarksPage.overlayBookmarkBitmap(b, iconResId, mContext, overlayScale / willScale, (int) (overlayVertPos / willScale)); - thumb.setImageBitmap(bm); + thumb.replaceFavicon(bm); } else { - thumb.setImageBitmap(b); + thumb.replaceFavicon(b); } + thumb.setLongClickable(true); } @Override diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java index f0cec84f..80e1da7e 100644 --- a/src/com/android/browser/BrowserHistoryPage.java +++ b/src/com/android/browser/BrowserHistoryPage.java @@ -652,8 +652,14 @@ public class BrowserHistoryPage extends Fragment item.getPaddingRight(), item.getPaddingBottom()); item.setFaviconBackground(mFaviconBackground); + item.setTag(R.id.group_position, groupPosition); + item.setTag(R.id.child_position, childPosition); + item.setTag(R.id.combo_view_container, mHistoryList); } else { item = (HistoryItem) convertView; + item.setTag(R.id.group_position, groupPosition); + item.setTag(R.id.child_position, childPosition); + item.setTag(R.id.combo_view_container, mHistoryList); } // Bail early if the Cursor is closed. diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java index c7ceb681..5563b627 100644 --- a/src/com/android/browser/Controller.java +++ b/src/com/android/browser/Controller.java @@ -2028,10 +2028,12 @@ public class Controller switch (item.getItemId()) { // -- Main menu case R.id.new_tab_menu_id: + getCurrentTab().capture(); openTabToHomePage(); break; case R.id.incognito_menu_id: + getCurrentTab().capture(); openIncognitoTab(); break; @@ -2543,7 +2545,7 @@ public class Controller AddBookmarkPage.class); i.putExtra(BrowserContract.Bookmarks.URL, w.getUrl()); i.putExtra(BrowserContract.Bookmarks.TITLE, w.getTitle()); - String touchIconUrl = w.getTouchIconUrl(); + String touchIconUrl = getCurrentTab().getTouchIconUrl(); if (touchIconUrl != null) { i.putExtra(AddBookmarkPage.TOUCH_ICON_URL, touchIconUrl); WebSettings settings = w.getSettings(); diff --git a/src/com/android/browser/HistoryItem.java b/src/com/android/browser/HistoryItem.java index 20efcb1f..5153d9ca 100644 --- a/src/com/android/browser/HistoryItem.java +++ b/src/com/android/browser/HistoryItem.java @@ -20,14 +20,14 @@ import android.content.Context; import android.view.View; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.ExpandableListView; -import com.android.browser.R; import com.android.browser.platformsupport.Browser; /** * Layout representing a history item in the classic history viewer. */ /* package */ class HistoryItem extends BookmarkItem - implements OnCheckedChangeListener { + implements OnCheckedChangeListener, View.OnClickListener { private CompoundButton mStar; // Star for bookmarking /** @@ -48,13 +48,15 @@ import com.android.browser.platformsupport.Browser; } else { mStar.setVisibility(View.GONE); } + + mTileView.setOnClickListener(this); } /* package */ void copyTo(HistoryItem item) { item.mTextView.setText(mTextView.getText()); item.mUrlText.setText(mUrlText.getText()); item.setIsBookmark(mStar.isChecked()); - item.mImageView.setImageDrawable(mImageView.getDrawable()); + item.mTileView.replaceFavicon(mBitmap); } /** @@ -87,4 +89,21 @@ import com.android.browser.platformsupport.Browser; getContext().getContentResolver(), mUrl, getName()); } } + + @Override + public void onClick(View v) { + if (v == mTileView) { + ExpandableListView list = (ExpandableListView) getTag(R.id.combo_view_container); + int group = (int) getTag(R.id.group_position); + int pos = (int) getTag(R.id.child_position); + if (list != null) { + long packedPos = list.getPackedPositionForChild(group, pos); + int flatPos = list.getFlatListPosition(packedPos); + list.performItemClick( + list.getAdapter().getView(flatPos, null, null), + flatPos, list.getAdapter().getItemId(flatPos)); + } + performClick(); + } + } } diff --git a/src/com/android/browser/SiteTileView.java b/src/com/android/browser/SiteTileView.java new file mode 100644 index 00000000..36f21c9d --- /dev/null +++ b/src/com/android/browser/SiteTileView.java @@ -0,0 +1,510 @@ +/* + * 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; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.TypedValue; +import android.view.View; + +/** + * This represents a WebSite Tile that is created from a Drawable and will scale across any + * area this is externally layouted to. There are 3 possible looks: + * - just the favicon (TYPE_SMALL) + * - drop-shadow plus a thin overlay border (1dp) (TYPE_MEDIUM) + * - centered favicon, extended color, rounded base (TYPE_LARGE) + * + * By centralizing everything in this class we make customization of looks much easier. + * + * NOTES: + * - do not set a background from the outside; this overrides it automatically + */ +public class SiteTileView extends View { + + // external configuration constants + public static final int TYPE_SMALL = 1; + public static final int TYPE_MEDIUM = 2; + public static final int TYPE_LARGE = 3; + private static final int TYPE_AUTO = 0; + private static final int COLOR_AUTO = 0; + + + // static configuration + private static final int THRESHOLD_MEDIUM_DP = 32; + private static final int THRESHOLD_LARGE_DP = 64; + private static final int LARGE_FAVICON_SIZE_DP = 48; + private static final int BACKGROUND_DRAWABLE_RES = R.drawable.img_tile_background; + private static final float FILLER_RADIUS_DP = 2f; // sync with the bg image radius + private static final int FILLER_FALLBACK_COLOR = Color.WHITE; // in case there is no favicon + private static final int OVERLINE_WIDTH_RES = R.dimen.SiteTileOverline; + private static final int OVERLINE_COLOR_RES = R.color.SiteTileOverline; + + + // configuration + private Bitmap mFaviconBitmap = null; + private Paint mFundamentalPaint = null; + private int mFaviconWidth = 0; + private int mFaviconHeight = 0; + private int mForcedType = TYPE_AUTO; + private int mForcedFundamentalColor = COLOR_AUTO; + + // static objects, to be recycled amongst instances (this is an optimization) + private static int sMediumPxThreshold = -1; + private static int sLargePxThreshold = -1; + private static int sLargeFaviconPx = -1; + private static float sRoundedRadius = -1; + private static Paint sBitmapPaint = null; + private static Rect sSrcRect = new Rect(); + private static Rect sDstRect = new Rect(); + private static RectF sRectF = new RectF(); + private static Paint sOverlineOutlinePaint = null; + private static Drawable sBackgroundDrawable = null; + private static Rect sBackgroundDrawablePadding = new Rect(); + + // runtime params set on Layout + private int mCurrentWidth = 0; + private int mCurrentHeight = 0; + private int mCurrentType = TYPE_MEDIUM; + private boolean mCurrentBackgroundDrawn = false; + private boolean mFloating = false; + private int mPaddingLeft = 0; + private int mPaddingTop = 0; + private int mPaddingRight = 0; + private int mPaddingBottom = 0; + + + + /* XML constructors */ + + public SiteTileView(Context context) { + super(context); + xmlInit(null, 0); + } + + public SiteTileView(Context context, AttributeSet attrs) { + super(context, attrs); + xmlInit(attrs, 0); + } + + public SiteTileView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + xmlInit(attrs, defStyle); + } + + + /* Programmatic Constructors */ + + public SiteTileView(Context context, Bitmap favicon) { + super(context); + init(favicon, COLOR_AUTO); + } + + public SiteTileView(Context context, Bitmap favicon, int fundamentalColor) { + super(context); + init(favicon, fundamentalColor); + } + + + /** + * Changes the current favicon (and associated fundamental color) on the fly + */ + public void replaceFavicon(Bitmap favicon) { + replaceFavicon(favicon, COLOR_AUTO); + } + + /** + * Changes the current favicon (and associated fundamental color) on the fly + * @param favicon the new favicon + * @param fundamentalColor the new fudamental color, or COLOR_AUTO + */ + public void replaceFavicon(Bitmap favicon, int fundamentalColor) { + init(favicon, fundamentalColor); + requestLayout(); + } + + /** + * Disables the automatic background and filling. Useful for things that are not really + * "Website Tiles", like folders. + * @param floating true to disable the background (defaults to false) + */ + public void setFloating(boolean floating) { + mFloating = floating; + invalidate(); + } + + + /** + * @return The fundamental color representing the site. + */ + public int getFundamentalColor() { + if (mForcedFundamentalColor != COLOR_AUTO) + return mForcedFundamentalColor; + if (mFundamentalPaint == null) + mFundamentalPaint = createFundamentalPaint(mFaviconBitmap, COLOR_AUTO); + return mFundamentalPaint.getColor(); + } + + + /*** private stuff ahead ***/ + + private void xmlInit(AttributeSet attrs, int defStyle) { + // load attributes + final TypedArray a = getContext().obtainStyledAttributes(attrs, + R.styleable.SiteTileView, defStyle, 0); + + // fetch the drawable, if defined - then just extract and use the bitmap + final Drawable drawable = a.getDrawable(R.styleable.SiteTileView_android_src); + final Bitmap favicon = drawable instanceof BitmapDrawable ? + ((BitmapDrawable) drawable).getBitmap() : null; + + // check if we disable shading (plain favicon) + if (a.getBoolean(R.styleable.SiteTileView_flat, false)) + mForcedType = TYPE_SMALL; + + // check if we want it floating (disable shadow and filler) + if (a.getBoolean(R.styleable.SiteTileView_floating, false)) + mFloating = true; + + // delete attribute resolution + a.recycle(); + + // proceed with real initialization + init(favicon, COLOR_AUTO); + } + + private void init(Bitmap favicon, int fundamentalColor) { + mFaviconBitmap = favicon; + if (mFaviconBitmap != null) { + mFaviconWidth = mFaviconBitmap.getWidth(); + mFaviconHeight = mFaviconBitmap.getHeight(); + } + + // don't compute the paint right now, just save any hint for later + mFundamentalPaint = null; + mForcedFundamentalColor = fundamentalColor; + + // shared (static) resources initialization; except for background, inited on-demand + if (sMediumPxThreshold < 0) { + final DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); + + // heuristics thresholds + sMediumPxThreshold = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + THRESHOLD_MEDIUM_DP, displayMetrics); + sLargePxThreshold = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + THRESHOLD_LARGE_DP, displayMetrics); + sLargeFaviconPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + LARGE_FAVICON_SIZE_DP, displayMetrics); + + // rounded radius + sRoundedRadius = FILLER_RADIUS_DP > 0 ? TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, FILLER_RADIUS_DP, displayMetrics) : 0; + + // bitmap paint (copy, smooth scale) + sBitmapPaint = new Paint(); + sBitmapPaint.setColor(Color.BLACK); + sBitmapPaint.setFilterBitmap(true); + + // overline configuration (null if we don't need it) + int ovlColor = getResources().getColor(OVERLINE_COLOR_RES); + float ovlWidthPx = getResources().getDimension(OVERLINE_WIDTH_RES); + if (ovlWidthPx > 0.5 && ovlColor != Color.TRANSPARENT) { + sOverlineOutlinePaint = new Paint(); + sOverlineOutlinePaint.setColor(ovlColor); + sOverlineOutlinePaint.setStrokeWidth(ovlWidthPx); + sOverlineOutlinePaint.setStyle(Paint.Style.STROKE); + } + } + + // change when clicked + setClickable(true); + // disable by default the long click + setLongClickable(false); + } + + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + mCurrentWidth = right - left; + mCurrentHeight = bottom - top; + + // auto-determine the "TYPE_" from the physical size of the layout + if (mForcedType == TYPE_AUTO) { + if (mCurrentWidth < sMediumPxThreshold && mCurrentHeight < sMediumPxThreshold) + mCurrentType = TYPE_SMALL; + else if (mCurrentWidth < sLargePxThreshold && mCurrentHeight < sLargePxThreshold) + mCurrentType = TYPE_MEDIUM; + else + mCurrentType = TYPE_LARGE; + } else { + // or use the forced one, if defined + mCurrentType = mForcedType; + } + + // set or remove the background (if the need changed!) + boolean requiresBackground = mCurrentType >= TYPE_MEDIUM; + if (requiresBackground && !mCurrentBackgroundDrawn) { + // draw the background + mCurrentBackgroundDrawn = true; + + // load the background just the first time, on demand (it may fail too) + if (sBackgroundDrawable == null) { + sBackgroundDrawable = getResources().getDrawable(BACKGROUND_DRAWABLE_RES); + if (sBackgroundDrawable != null) + sBackgroundDrawable.getPadding(sBackgroundDrawablePadding); + } + + // background -> padding + mPaddingLeft = sBackgroundDrawablePadding.left; + mPaddingTop = sBackgroundDrawablePadding.top; + mPaddingRight = sBackgroundDrawablePadding.right; + mPaddingBottom = sBackgroundDrawablePadding.bottom; + } else if (!requiresBackground && mCurrentBackgroundDrawn) { + // turn off background drawing + mCurrentBackgroundDrawn = false; + + // no background -> no padding + mPaddingLeft = 0; + mPaddingTop = 0; + mPaddingRight = 0; + mPaddingBottom = 0; + } + + // just proceed, do nothing here + super.onLayout(changed, left, top, right, bottom); + } + + @Override + public void setPressed(boolean pressed) { + super.setPressed(pressed); + // schedule a repaint to show pressed/released + invalidate(); + } + + @Override + public void setSelected(boolean selected) { + super.setSelected(selected); + // schedule a repaint to show selected + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + // Selection State: make everything smaller + if (isSelected()) { + float scale = 0.8f; + canvas.translate(mCurrentWidth * (1 - scale) / 2, mCurrentHeight * (1 - scale) / 2); + canvas.scale(scale, scale); + } + + // Pressed state: make the button reach the finger + if (isPressed()) { + float scale = 1.1f; + canvas.translate(mCurrentWidth * (1 - scale) / 2, mCurrentHeight * (1 - scale) / 2); + canvas.scale(scale, scale); + } + + final int left = mPaddingLeft; + final int top = mPaddingTop; + final int right = mCurrentWidth - mPaddingRight; + final int bottom = mCurrentHeight - mPaddingBottom; + final int contentWidth = right - left; + final int contentHeight = bottom - top; + + // A. the background drawable (if set) + boolean requiresBackground = mCurrentBackgroundDrawn && sBackgroundDrawable != null + && !isPressed() && !mFloating; + if (requiresBackground) { + sBackgroundDrawable.setBounds(0, 0, mCurrentWidth, mCurrentHeight); + sBackgroundDrawable.draw(canvas); + } + + // B. (when needed) draw the background rectangle; sharp our rounded + boolean requiresFundamentalFiller = mCurrentType >= TYPE_LARGE && !mFloating; + if (requiresFundamentalFiller) { + // create the filler paint on demand (not all icons need it) + if (mFundamentalPaint == null) + mFundamentalPaint = createFundamentalPaint(mFaviconBitmap, mForcedFundamentalColor); + + // paint if not white, since requiresBackground already painted it white + int fundamentalColor = mFundamentalPaint.getColor(); + if (fundamentalColor != COLOR_AUTO && + (fundamentalColor != Color.WHITE || !requiresBackground)) { + if (sRoundedRadius >= 1.) { + sRectF.set(left, top, right, bottom); + canvas.drawRoundRect(sRectF, sRoundedRadius, sRoundedRadius, mFundamentalPaint); + } else + canvas.drawRect(left, top, right, bottom, mFundamentalPaint); + } + } + + // C. (if present) draw the favicon + boolean requiresFavicon = mFaviconBitmap != null + && mFaviconWidth > 1 && mFaviconHeight > 1; + if (requiresFavicon) { + // destination can either fill, or auto-center + boolean fillSpace = mCurrentType <= TYPE_MEDIUM; + if (fillSpace || contentWidth < sLargeFaviconPx || contentHeight < sLargeFaviconPx) { + sDstRect.set(left, top, right, bottom); + } else { + int dstLeft = left + (contentWidth - sLargeFaviconPx) / 2; + int dstTop = top + (contentHeight - sLargeFaviconPx) / 2; + sDstRect.set(dstLeft, dstTop, dstLeft + sLargeFaviconPx, dstTop + sLargeFaviconPx); + } + + // source has to 'crop proportionally' to keep the dest aspect ratio + sSrcRect.set(0, 0, mFaviconWidth, mFaviconHeight); + int sW = sSrcRect.width(); + int sH = sSrcRect.height(); + int dW = sDstRect.width(); + int dH = sDstRect.height(); + if (sW > 4 && sH > 4 && dW > 4 && dH > 4) { + float hScale = (float) dW / (float) sW; + float vScale = (float) dH / (float) sH; + if (hScale == vScale) { + // no transformation needed, just zoom + } else if (hScale < vScale) { + // horizontal crop + float hCrop = 1 - hScale / vScale; + int hCropPx = (int) (sW * hCrop / 2 + 0.5); + sSrcRect.left += hCropPx; + sSrcRect.right -= hCropPx; + canvas.drawBitmap(mFaviconBitmap, sSrcRect, sDstRect, sBitmapPaint); + } else { + // vertical crop + float vCrop = 1 - vScale / hScale; + int vCropPx = (int) (sH * vCrop / 2 + 0.5); + sSrcRect.top += vCropPx; + sSrcRect.bottom -= vCropPx; + } + } + + // blit favicon, croppped, scaled + canvas.drawBitmap(mFaviconBitmap, sSrcRect, sDstRect, sBitmapPaint); + } + + // D. (when needed) draw the thin over-line + boolean requiresOverline = mCurrentType == TYPE_MEDIUM + && sOverlineOutlinePaint != null; + if (requiresOverline) { + canvas.drawRect(left, top, right, bottom, sOverlineOutlinePaint); + } + + /*if (true) { // DEBUG TYPE + Paint paint = new Paint(); + paint.setColor(Color.BLACK); + paint.setTextSize(20); + canvas.drawText(String.valueOf(mCurrentType), 30, 30, paint); + }*/ + } + + + /** + * Creates a fill Paint from the favicon, or using the forced color (if not COLOR_AUTO) + */ + private static Paint createFundamentalPaint(Bitmap favicon, int forceFillColor) { + final Paint fillPaint = new Paint(); + if (forceFillColor != COLOR_AUTO) + fillPaint.setColor(forceFillColor); + else + fillPaint.setColor(guessFundamentalColor(favicon)); + return fillPaint; + } + + /** + * This uses very stupid mechanism - a 9x9 grid sample on the borders and center - and selects + * the color with the most frequency, or the center. + * + * @param bitmap the bitmap to guesss the color about + * @return a Color + */ + private static int guessFundamentalColor(Bitmap bitmap) { + if (bitmap == null) + return FILLER_FALLBACK_COLOR; + int height = bitmap.getHeight(); + int width = bitmap.getWidth(); + if (height < 2 || width < 2) + return FILLER_FALLBACK_COLOR; + + // pick up to 9 colors + // NOTE: the order of sampling sets the precendece, in case of ties + int[] pxColors = new int[9]; + int idx = 0; + if ((pxColors[idx] = sampleColor(bitmap, width / 2, height / 2)) != 0) idx++; + if ((pxColors[idx] = sampleColor(bitmap, width / 2, height - 1)) != 0) idx++; + if ((pxColors[idx] = sampleColor(bitmap, width - 1, height - 1)) != 0) idx++; + if ((pxColors[idx] = sampleColor(bitmap, width - 1, height / 2)) != 0) idx++; + if ((pxColors[idx] = sampleColor(bitmap, 0, 0 )) != 0) idx++; + if ((pxColors[idx] = sampleColor(bitmap, width / 2, 0 )) != 0) idx++; + if ((pxColors[idx] = sampleColor(bitmap, width - 1, 0 )) != 0) idx++; + if ((pxColors[idx] = sampleColor(bitmap, 0 , height / 2)) != 0) idx++; + if ((pxColors[idx] = sampleColor(bitmap, 0 , height - 1)) != 0) idx++; + + // find the most popular + int popColor = -1; + int popCount = -1; + for (int i = 0; i < idx; i++) { + int thisColor = pxColors[i]; + int thisCount = 0; + for (int j = 0; j < idx; j++) { + if (pxColors[j] == thisColor) + thisCount++; + } + if (thisCount > popCount) { + popColor = thisColor; + popCount = thisCount; + } + } + return popCount > -1 ? popColor : FILLER_FALLBACK_COLOR; + } + + /** + * @return Color, but if it's 0, you should discard it (not representative) + */ + private static int sampleColor(Bitmap bitmap, int x, int y) { + int color = bitmap.getPixel(x, y); + // discard semi-transparent pixels, because they're probably from a spurious border + // discard black pixels, because black is not a color (well, not a good looking one) + if ((color >>> 24) <= 128 || (color & 0xFFFFFF) == 0) + return 0; + return color; + } + +}
\ No newline at end of file diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java index 3e3c9aaf..ef4c3806 100644 --- a/src/com/android/browser/Tab.java +++ b/src/com/android/browser/Tab.java @@ -193,6 +193,8 @@ class Tab implements PictureListener { // determine if webview is destroyed to MemoryMonitor private boolean mWebViewDestroyedByMemoryMonitor; + private String mTouchIconUrl; + private Observable mFirstPixelObservable; private Observable mTabHistoryUpdateObservable; @@ -634,6 +636,7 @@ class Tab implements PictureListener { @Override public void beforeNavigation(WebView view, String url) { + mTouchIconUrl = null; if (BrowserCommandLine.hasSwitch("ui-low-power-mode")) { return; } @@ -726,6 +729,9 @@ class Tab implements PictureListener { mCurrentState.mIncognito = view.isPrivateBrowsingEnabled(); } + public String getTouchIconUrl() { + return mTouchIconUrl; + } public boolean isTabFullScreen() { return mFullScreen; @@ -771,6 +777,8 @@ class Tab implements PictureListener { mWebViewController.attachSubWindow(Tab.this); transport.setWebView(mSubView); } else { + capture(); + final Tab newTab = mWebViewController.openTab(url, Tab.this, true, true); // This is special case for rendering links on a webpage in @@ -919,6 +927,7 @@ class Tab implements PictureListener { mContext, cr, view); mTouchIconLoader.execute(url); } + mTouchIconUrl = url; } @Override diff --git a/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java b/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java index 329f66cd..10595074 100644 --- a/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java +++ b/src/com/android/browser/preferences/SiteSpecificPreferencesFragment.java @@ -229,6 +229,11 @@ public class SiteSpecificPreferencesFragment extends SWEPreferenceFragment mSslCert = (parcel != null) ? SslCertificate.restoreState(parcel) : null; if (mSslCert != null) { + Preference pref = findPreference("site_security_info"); + if (pref != null) { + pref.setSelectable(true); + } + int certErrors = args.getInt(EXTRA_SECURITY_CERT_ERR, 0); if (certErrors == 0) { diff --git a/src/com/android/browser/view/BookmarkContainer.java b/src/com/android/browser/view/BookmarkContainer.java index 54f281cc..730f1278 100644 --- a/src/com/android/browser/view/BookmarkContainer.java +++ b/src/com/android/browser/view/BookmarkContainer.java @@ -26,6 +26,9 @@ import android.view.View.OnClickListener; import android.view.ViewConfiguration; import android.widget.LinearLayout; +import com.android.browser.R; +import com.android.browser.SiteTileView; + public class BookmarkContainer extends LinearLayout implements OnClickListener { private OnClickListener mClickListener; @@ -53,13 +56,21 @@ public class BookmarkContainer extends LinearLayout implements OnClickListener { } @Override - public void setBackgroundDrawable(Drawable d) { - super.setBackgroundDrawable(d); + public void setOnClickListener(OnClickListener l) { + mClickListener = l; + View thumb = findViewById(R.id.thumb_image); + if (thumb != null) { + thumb.setOnClickListener(l); + } } @Override - public void setOnClickListener(OnClickListener l) { - mClickListener = l; + public void setTag(int key, final Object tag) { + super.setTag(key, tag); + View thumb = findViewById(R.id.thumb_image); + if (thumb != null) { + thumb.setTag(key, tag); + } } @Override |