Merge "Fixes cutoff in url suggestions"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 9fea44a..b653461 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -39,7 +39,7 @@
<application android:name="Browser"
android:label="@string/application_name"
- android:icon="@drawable/ic_launcher_browser"
+ android:icon="@mipmap/ic_launcher_browser"
android:backupAgent=".BrowserBackupAgent"
android:hardwareAccelerated="false"
android:taskAffinity="android.task.browser" >
@@ -147,7 +147,7 @@
<activity android:name="ShortcutActivity"
android:theme="@style/ShortcutTheme"
android:label="@string/shortcut_bookmark"
- android:icon="@drawable/ic_launcher_shortcut_browser_bookmark">
+ android:icon="@mipmap/ic_launcher_shortcut_browser_bookmark">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
diff --git a/res/drawable/preview.png b/res/drawable/preview.png
index f05710f..b363ab5 100644
--- a/res/drawable/preview.png
+++ b/res/drawable/preview.png
Binary files differ
diff --git a/res/layout/bookmark_list.xml b/res/layout/bookmark_list.xml
new file mode 100644
index 0000000..720685b
--- /dev/null
+++ b/res/layout/bookmark_list.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/list_item"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:minHeight="@dimen/widgetItemMinHeight"
+ android:orientation="horizontal"
+ android:padding="8dip">
+ <ImageView
+ android:id="@+id/favicon"
+ android:layout_height="24dp"
+ android:layout_width="24dp"
+ android:layout_gravity="center_vertical"
+ android:scaleType="fitXY"/>
+ <TextView
+ android:id="@+id/label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:padding="8dip"
+ android:maxLines="1"
+ android:scrollHorizontally="true"
+ android:ellipsize="marquee"/>
+</LinearLayout>
diff --git a/res/layout/bookmarklistwidget.xml b/res/layout/bookmarklistwidget.xml
index 983854c..17aee1d 100644
--- a/res/layout/bookmarklistwidget.xml
+++ b/res/layout/bookmarklistwidget.xml
@@ -33,7 +33,7 @@
android:id="@+id/logo"
android:layout_width="32dp"
android:layout_height="32dp"
- android:src="@drawable/ic_launcher_browser" />
+ android:src="@mipmap/ic_launcher_browser" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/layout/bookmarks.xml b/res/layout/bookmarks.xml
index fa08353..7a0aa23 100644
--- a/res/layout/bookmarks.xml
+++ b/res/layout/bookmarks.xml
@@ -14,29 +14,49 @@
limitations under the License.
-->
-<FrameLayout
+<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent">
- <GridView
- android:id="@+id/grid"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:id="@+id/header_container"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:horizontalSpacing="16dip"
- android:verticalSpacing="16dip"
- android:stretchMode="spacingWidth"
- android:scrollbarStyle="insideInset"
- android:listSelector="@android:drawable/gallery_thumb"
- android:drawSelectorOnTop="true"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:numColumns="auto_fit" />
- <TextView
- android:id="@android:id/empty"
- android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:text="@string/empty_bookmarks_folder"
android:visibility="gone" />
-</FrameLayout>
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <GridView
+ android:id="@+id/grid"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:horizontalSpacing="16dip"
+ android:verticalSpacing="16dip"
+ android:stretchMode="spacingWidth"
+ android:scrollbarStyle="insideInset"
+ android:listSelector="@android:drawable/gallery_thumb"
+ android:drawSelectorOnTop="true"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:numColumns="auto_fit" />
+ <ListView
+ android:id="@+id/list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:visibility="gone"/>
+ <TextView
+ android:id="@android:id/empty"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:text="@string/empty_bookmarks_folder"
+ android:visibility="gone" />
+ </FrameLayout>
+
+</LinearLayout>
diff --git a/res/layout/bookmarks_header.xml b/res/layout/bookmarks_header.xml
new file mode 100644
index 0000000..597e629
--- /dev/null
+++ b/res/layout/bookmarks_header.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="48dip"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/root_folder"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:text="@string/defaultBookmarksUpButton"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="center_vertical"
+ android:visibility="gone"
+ android:paddingLeft="16dip"
+ android:drawableLeft="@drawable/ic_tab_bookmarks_selected"
+ android:drawablePadding="16dip" />
+
+ <com.android.browser.BreadCrumbView
+ android:id="@+id/crumbs"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:paddingLeft="16dip" />
+
+ <TextView
+ android:id="@+id/select_bookmark_view"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:text="@string/switch_to_thumbnails"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="center_vertical" />
+
+</LinearLayout>
diff --git a/res/layout/bookmarks_history.xml b/res/layout/bookmarks_history.xml
index a89a2b9..a3a5084 100644
--- a/res/layout/bookmarks_history.xml
+++ b/res/layout/bookmarks_history.xml
@@ -22,16 +22,14 @@
android:paddingRight="16dip"
android:orientation="vertical"
android:background="@color/black">
- <RelativeLayout
- android:id="@+id/bar"
+ <LinearLayout
android:layout_width="match_parent"
android:layout_height="48dip">
+
<LinearLayout
android:id="@+id/tabs"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingLeft="16dip"
- android:paddingRight="16dip">
+ android:layout_height="match_parent">
<TextView
android:id="@+id/historytab"
android:layout_width="wrap_content"
@@ -58,25 +56,34 @@
android:text="@string/bookmarks"
android:drawableLeft="@drawable/ic_tab_bookmarks_selected"
android:drawablePadding="16dip" />
- <com.android.browser.BreadCrumbView
- android:id="@+id/crumbs"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:paddingLeft="16dip"
- android:paddingRight="16dip" />
</LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/header_container"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent" />
+
+ <ImageView
+ android:id="@+id/seperate_select_add"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:paddingRight="16dip"
+ android:paddingLeft="16dip"
+ android:src="@drawable/divider_vert" />
+
<TextView
android:id="@+id/addbm"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="@string/add_new_bookmark"
- android:layout_alignParentRight="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center_vertical"
android:background="@null"
android:drawableLeft="@drawable/ic_favorite_off_normal"
android:drawablePadding="16dip" />
- </RelativeLayout>
+
+ </LinearLayout>
<FrameLayout
android:id="@+id/fragment"
android:paddingTop="8dip"
diff --git a/res/layout/browser_subwindow.xml b/res/layout/browser_subwindow.xml
index adf3284..a3868cd 100644
--- a/res/layout/browser_subwindow.xml
+++ b/res/layout/browser_subwindow.xml
@@ -28,12 +28,6 @@
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:drawable/dialog_frame" >
- <WebView android:id="@+id/webview"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fadeScrollbars="true"
- android:scrollbarStyle="outsideOverlay"
- android:layout_weight="1" />
</LinearLayout>
</FrameLayout>
<LinearLayout
diff --git a/res/layout/suggestion_two_column.xml b/res/layout/suggestion_two_column.xml
index fc74140..cc4f2e2 100644
--- a/res/layout/suggestion_two_column.xml
+++ b/res/layout/suggestion_two_column.xml
@@ -27,18 +27,21 @@
android:baselineAligned="false">
<include
android:id="@+id/suggest1"
- layout="@layout/suggestion_item"
+ android:layout_height="56dip"
android:layout_width="0dip"
android:layout_weight="1"
+ layout="@layout/suggestion_item"
/>
<ImageView
+ android:id="@+id/suggestion_divider"
android:layout_width="wrap_content"
android:layout_height="56dip"
android:background="@drawable/list_divider_vert" />
<include
android:id="@+id/suggest2"
- layout="@layout/suggestion_item"
+ android:layout_height="56dip"
android:layout_width="0dip"
android:layout_weight="1"
+ layout="@layout/suggestion_item"
/>
</LinearLayout>
diff --git a/res/menu/bookmark_view.xml b/res/menu/bookmark_view.xml
new file mode 100644
index 0000000..fdfd672
--- /dev/null
+++ b/res/menu/bookmark_view.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/thumbnail_view"
+ android:title="@string/bookmark_thumbnail_view"/>
+ <item android:id="@+id/list_view"
+ android:title="@string/bookmark_list_view"/>
+</menu>
diff --git a/res/menu/browsercontext.xml b/res/menu/browsercontext.xml
index 70cf8d4..f5361d5 100644
--- a/res/menu/browsercontext.xml
+++ b/res/menu/browsercontext.xml
@@ -57,5 +57,9 @@
<item android:id="@+id/set_wallpaper_context_menu_id"
android:title="@string/contextmenu_set_wallpaper"/>
</group>
+ <group android:id="@+id/SELECT_TEXT_MENU">
+ <item android:id="@+id/select_text_menu_id"
+ android:title="@string/select_dot"/>
+ </group>
</menu>
diff --git a/res/drawable-hdpi/ic_launcher_browser.png b/res/mipmap-hdpi/ic_launcher_browser.png
similarity index 100%
rename from res/drawable-hdpi/ic_launcher_browser.png
rename to res/mipmap-hdpi/ic_launcher_browser.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_shortcut_browser_bookmark.png b/res/mipmap-hdpi/ic_launcher_shortcut_browser_bookmark.png
similarity index 100%
rename from res/drawable-hdpi/ic_launcher_shortcut_browser_bookmark.png
rename to res/mipmap-hdpi/ic_launcher_shortcut_browser_bookmark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_browser.png b/res/mipmap-mdpi/ic_launcher_browser.png
similarity index 100%
rename from res/drawable-mdpi/ic_launcher_browser.png
rename to res/mipmap-mdpi/ic_launcher_browser.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_shortcut_browser_bookmark.png b/res/mipmap-mdpi/ic_launcher_shortcut_browser_bookmark.png
similarity index 100%
rename from res/drawable-mdpi/ic_launcher_shortcut_browser_bookmark.png
rename to res/mipmap-mdpi/ic_launcher_shortcut_browser_bookmark.png
Binary files differ
diff --git a/res/values/integers.xml b/res/values/integers.xml
index 4e029b1..2864d47 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -13,7 +13,7 @@
<resources
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- The number of lines in the suggestions dropdown in landscape -->
- <integer name="max_suggest_lines_landscape">6</integer>
+ <integer name="max_suggest_lines_landscape">4</integer>
<!-- The number of lines in the suggestions dropdown in portrait -->
<integer name="max_suggest_lines_portrait">12</integer>
<!-- The maximum number of open tabs -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d724085..7d27dec 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -75,6 +75,9 @@
<!-- Label for a button on an SSL error dialog that lets the user view the
certificate -->
<string name="view_certificate">View certificate</string>
+ <!-- Label for a button on an SSL error dialog that lets the user go back to
+ the last page they were on instead of continuing to the new page. [CHAR-LIMIT=20] -->
+ <string name="ssl_go_back">Go back</string>
<!-- Message in an SSL Error dialog -->
<string name="ssl_untrusted">This certificate is not from a trusted authority.</string>
@@ -181,11 +184,11 @@
showing. -->
<string name="bookmark_page">Bookmark last-viewed page</string>
<!-- Menu item in the page that displays all bookmarks. Switches to
- a grid view which shows thumbnails -->
- <string name="switch_to_thumbnails">Thumbnail view</string>
+ a grid view which shows thumbnails [CHAR LIMIT=50] -->
+ <string name="bookmark_thumbnail_view">Thumbnail view</string>
<!-- Menu item in the page that displays all bookmarks. Switches to a
- list view which shows titles -->
- <string name="switch_to_list">List view</string>
+ list view which shows titles [CHAR LIMIT=50] -->
+ <string name="bookmark_list_view">List view</string>
<!-- Summary text under the New Bookmark item on the Bookmarks screen.
Tells the user that if they select this item, it will bring up a
dialog to bookmark the page that the browser is currently viewing,
@@ -393,6 +396,12 @@
<!-- Button text to delete all the AutoFill profile data [CHAR-LIMIT=20] -->
<string name="autofill_profile_editor_delete_profile">Delete profile data</string>
+ <!-- Text on a dialog shown to the user when they are prompted to set up the autofill feature [CHAR-LIMIT=NONE] -->
+ <string name="autofill_setup_dialog_message">Browser can automatically complete web forms like this one. Would you like to set up your profile?</string>
+ <!-- Toast message displayed when the user decides to not set up autofill at this time. We want to remind them that they can configure
+ it through the Browser Settings menu. [CHAR-LIMIT=NONE] -->
+ <string name="autofill_setup_dialog_negative_toast">AutoFill can always be configured through Browser Settings -> Personal Settings.</string>
+
<!-- Settings screen, section title -->
<string name="pref_privacy_title">Privacy settings</string>
<!-- Settings label -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index a1ca842..1a4ee2d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -32,7 +32,7 @@
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
- <style name="ShortcutTheme" parent="@android:Theme.Black">
+ <style name="ShortcutTheme" parent="@android:Theme.Holo.DialogWhenLarge">
<item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
</style>
diff --git a/res/xml/browser_preferences.xml b/res/xml/browser_preferences.xml
index 623c8e7..a2d91ff 100644
--- a/res/xml/browser_preferences.xml
+++ b/res/xml/browser_preferences.xml
@@ -135,7 +135,7 @@
<CheckBoxPreference
android:key="autofill_enabled"
- android:defaultValue="false"
+ android:defaultValue="true"
android:title="@string/pref_autofill_enabled"
android:summary="@string/pref_autofill_enabled_summary" />
diff --git a/res/xml/personal_preferences.xml b/res/xml/personal_preferences.xml
index 939d14c..30ebae2 100644
--- a/res/xml/personal_preferences.xml
+++ b/res/xml/personal_preferences.xml
@@ -24,6 +24,7 @@
<CheckBoxPreference android:key="autofill_enabled"
android:title="@string/pref_autofill_enabled"
android:summary="@string/pref_autofill_enabled_summary"
+ android:defaultValue="true"
/>
<PreferenceScreen
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 2a23bb1..5f8944f 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -34,12 +34,15 @@
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.webkit.WebHistoryItem;
import android.webkit.WebView;
import android.widget.FrameLayout;
+import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Toast;
@@ -164,6 +167,16 @@
return w;
}
+ @Override
+ public WebView createSubWebView(boolean privateBrowsing) {
+ ScrollWebView web = (ScrollWebView) createWebView(privateBrowsing);
+ if (mXLargeScreenSize) {
+ // no scroll listener for subview
+ web.setScrollListener(null);
+ }
+ return web;
+ }
+
void stopWebViewScrolling() {
ScrollWebView web = (ScrollWebView) mUiController.getCurrentWebView();
if (web != null) {
@@ -415,6 +428,33 @@
}
/**
+ * create a sub window container and webview for the tab
+ * Note: this methods operates through side-effects for now
+ * it sets both the subView and subViewContainer for the given tab
+ * @param tab tab to create the sub window for
+ * @param subView webview to be set as a subwindow for the tab
+ */
+ @Override
+ public void createSubWindow(Tab tab, WebView subView) {
+ View subViewContainer = mActivity.getLayoutInflater().inflate(
+ R.layout.browser_subwindow, null);
+ ViewGroup inner = (ViewGroup) subViewContainer
+ .findViewById(R.id.inner_container);
+ inner.addView(subView, new LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT));
+ final ImageButton cancel = (ImageButton) subViewContainer
+ .findViewById(R.id.subwindow_close);
+ final WebView cancelSubView = subView;
+ cancel.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ cancelSubView.getWebChromeClient().onCloseWindow(cancelSubView);
+ }
+ });
+ tab.setSubWebView(subView);
+ tab.setSubViewContainer(subViewContainer);
+ }
+
+ /**
* Remove the sub window from the content view.
*/
@Override
@@ -428,6 +468,10 @@
*/
@Override
public void attachSubWindow(View container) {
+ if (container.getParent() != null) {
+ // already attached, remove first
+ ((ViewGroup) container.getParent()).removeView(container);
+ }
mContentView.addView(container, COVER_SCREEN_PARAMS);
}
diff --git a/src/com/android/browser/BookmarkUtils.java b/src/com/android/browser/BookmarkUtils.java
index 0fdad15..751c0b3 100644
--- a/src/com/android/browser/BookmarkUtils.java
+++ b/src/com/android/browser/BookmarkUtils.java
@@ -105,12 +105,12 @@
// Want to create a shortcut icon on the homescreen, so the icon
// background is the red bookmark.
return BitmapFactory.decodeResource(context.getResources(),
- R.drawable.ic_launcher_shortcut_browser_bookmark);
+ R.mipmap.ic_launcher_shortcut_browser_bookmark);
} else if (type == BookmarkIconType.ICON_INSTALLABLE_WEB_APP) {
// Use the web browser icon as the background for the icon for an installable
// web app.
return BitmapFactory.decodeResource(context.getResources(),
- R.drawable.ic_launcher_browser);
+ R.mipmap.ic_launcher_browser);
}
return null;
}
diff --git a/src/com/android/browser/BrowserBookmarksAdapter.java b/src/com/android/browser/BrowserBookmarksAdapter.java
index a5d51dd..f587f01 100644
--- a/src/com/android/browser/BrowserBookmarksAdapter.java
+++ b/src/com/android/browser/BrowserBookmarksAdapter.java
@@ -20,42 +20,102 @@
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CursorAdapter;
import android.widget.ImageView;
-import android.widget.ResourceCursorAdapter;
import android.widget.TextView;
-class BrowserBookmarksAdapter extends ResourceCursorAdapter {
+class BrowserBookmarksAdapter extends CursorAdapter {
+ LayoutInflater mInflater;
+ int mCurrentView;
+
/**
* Create a new BrowserBookmarksAdapter.
*/
- public BrowserBookmarksAdapter(Context context) {
+ public BrowserBookmarksAdapter(Context context, int defaultView) {
// Make sure to tell the CursorAdapter to avoid the observer and auto-requery
// since the Loader will do that for us.
- super(context, R.layout.bookmark_thumbnail, null);
+ super(context, null);
+ mInflater = LayoutInflater.from(context);
+ selectView(defaultView);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
+ if (mCurrentView == BrowserBookmarksPage.VIEW_LIST) {
+ bindListView(view, context, cursor);
+ } else {
+ bindGridView(view, context, cursor);
+ }
+ }
+
+ void bindGridView(View view, Context context, Cursor cursor) {
ImageView thumb = (ImageView) view.findViewById(R.id.thumb);
TextView tv = (TextView) view.findViewById(R.id.label);
tv.setText(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
- Bitmap thumbnail = null;
if (cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0) {
// folder
thumb.setImageResource(R.drawable.ic_folder);
} else {
- byte[] data = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_THUMBNAIL);
- if (data != null) {
- thumbnail = BitmapFactory.decodeByteArray(data, 0, data.length);
+ byte[] thumbData = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_THUMBNAIL);
+ Bitmap thumbBitmap = null;
+ if (thumbData != null) {
+ thumbBitmap = BitmapFactory.decodeByteArray(thumbData, 0, thumbData.length);
}
- if (thumbnail == null) {
+ if (thumbBitmap == null) {
thumb.setImageResource(R.drawable.browser_thumbnail);
} else {
- thumb.setImageBitmap(thumbnail);
+ thumb.setImageBitmap(thumbBitmap);
}
}
}
+
+ void bindListView(View view, Context context, Cursor cursor) {
+ ImageView favicon = (ImageView) view.findViewById(R.id.favicon);
+ TextView tv = (TextView) view.findViewById(R.id.label);
+
+ tv.setText(cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
+ if (cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0) {
+ // folder
+ favicon.setImageResource(R.drawable.ic_folder);
+ } else {
+ byte[] faviconData = cursor.getBlob(BookmarksLoader.COLUMN_INDEX_FAVICON);
+ Bitmap faviconBitmap = null;
+ if (faviconData != null) {
+ faviconBitmap = BitmapFactory.decodeByteArray(faviconData, 0, faviconData.length);
+ }
+
+ if (faviconBitmap == null) {
+ favicon.setImageResource(R.drawable.app_web_browser_sm);
+ } else {
+ favicon.setImageBitmap(faviconBitmap);
+ }
+ }
+ }
+
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ if (mCurrentView == BrowserBookmarksPage.VIEW_LIST) {
+ return mInflater.inflate(R.layout.bookmark_list, parent, false);
+ } else {
+ return mInflater.inflate(R.layout.bookmark_thumbnail, parent, false);
+ }
+ }
+
+ public void selectView(int view) {
+ if (view != BrowserBookmarksPage.VIEW_LIST
+ && view != BrowserBookmarksPage.VIEW_THUMBNAILS) {
+ throw new IllegalArgumentException("Unknown view specified: " + view);
+ }
+ mCurrentView = view;
+ }
+
+ @Override
+ public Cursor getItem(int position) {
+ return (Cursor) super.getItem(position);
+ }
}
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index c7392cc..4370885 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -31,6 +31,7 @@
import android.content.Intent;
import android.content.Loader;
import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -46,6 +47,7 @@
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.webkit.WebIconDatabase.IconListener;
import android.widget.Adapter;
@@ -53,14 +55,25 @@
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.GridView;
+import android.widget.ListView;
+import android.widget.PopupMenu;
+import android.widget.PopupMenu.OnMenuItemClickListener;
+import android.widget.TextView;
import android.widget.Toast;
+interface BookmarksPageCallbacks {
+ // Return true if handled
+ boolean onBookmarkSelected(Cursor c, boolean isFolder);
+ // Return true if handled
+ boolean onOpenInNewWindow(Cursor c);
+}
+
/**
* View showing the user's bookmarks in the browser.
*/
public class BrowserBookmarksPage extends Fragment implements View.OnCreateContextMenuListener,
LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener, IconListener,
- OnItemSelectedListener {
+ OnItemSelectedListener, BreadCrumbView.Controller, OnClickListener, OnMenuItemClickListener {
static final int BOOKMARKS_SAVE = 1;
static final String LOGTAG = "browser";
@@ -68,7 +81,6 @@
static final int LOADER_BOOKMARKS = 1;
static final int LOADER_ACCOUNTS_THEN_BOOKMARKS = 2;
- static final String EXTRA_SHORTCUT = "create_shortcut";
static final String EXTRA_DISABLE_WINDOW = "disable_new_window";
static final String ACCOUNT_NAME_UNSYNCED = "Unsynced";
@@ -77,24 +89,33 @@
public static final String PREF_ACCOUNT_NAME = "acct_name";
static final String DEFAULT_ACCOUNT = "local";
+ static final int VIEW_THUMBNAILS = 1;
+ static final int VIEW_LIST = 2;
+ static final String PREF_SELECTED_VIEW = "bookmarks_view";
- BookmarksHistoryCallbacks mCallbacks;
+ BookmarksPageCallbacks mCallbacks;
GridView mGrid;
+ ListView mList;
BrowserBookmarksAdapter mAdapter;
boolean mDisableNewWindow;
BookmarkItem mContextHeader;
boolean mCanceled = false;
- boolean mCreateShortcut;
+ boolean mEnableContextMenu = true;
+ boolean mShowRootFolder = false;
View mEmptyView;
-
+ int mCurrentView;
+ View mHeader;
+ View mRootFolderView;
+ ViewGroup mHeaderContainer;
BreadCrumbView mCrumbs;
+ TextView mSelectBookmarkView;
- static BrowserBookmarksPage newInstance(BookmarksHistoryCallbacks cb,
- BreadCrumbView crumbs, Bundle args) {
+ static BrowserBookmarksPage newInstance(BookmarksPageCallbacks cb,
+ Bundle args, ViewGroup headerContainer) {
BrowserBookmarksPage bbp = new BrowserBookmarksPage();
bbp.mCallbacks = cb;
+ bbp.mHeaderContainer = headerContainer;
bbp.setArguments(args);
- bbp.mCrumbs = crumbs;
return bbp;
}
@@ -134,9 +155,10 @@
if (cursor == null || cursor.getCount() == 0) {
mEmptyView.setVisibility(View.VISIBLE);
mGrid.setVisibility(View.GONE);
+ mList.setVisibility(View.GONE);
} else {
mEmptyView.setVisibility(View.GONE);
- mGrid.setVisibility(View.VISIBLE);
+ setupBookmarkView();
}
// Give the new data to the adapter
@@ -209,7 +231,7 @@
long getFolderId() {
LoaderManager manager = getLoaderManager();
BookmarksLoader loader =
- (BookmarksLoader) ((Loader)(manager.getLoader(LOADER_BOOKMARKS)));
+ (BookmarksLoader) ((Loader<?>)manager.getLoader(LOADER_BOOKMARKS));
Uri uri = loader.getUri();
if (uri != null) {
@@ -230,7 +252,7 @@
}
LoaderManager manager = getLoaderManager();
BookmarksLoader loader =
- (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS));
+ (BookmarksLoader) ((Loader<?>) manager.getLoader(LOADER_BOOKMARKS));
loader.setUri(uri);
loader.forceLoad();
@@ -259,7 +281,8 @@
editBookmark(i.position);
break;
case R.id.shortcut_context_menu_id:
- activity.sendBroadcast(createShortcutIntent(i.position));
+ Cursor c = mAdapter.getItem(i.position);
+ activity.sendBroadcast(createShortcutIntent(getActivity(), c));
break;
case R.id.delete_context_menu_id:
displayRemoveBookmarkDialog(i.position);
@@ -268,7 +291,7 @@
openInNewWindow(i.position);
break;
case R.id.share_link_context_menu_id: {
- Cursor cursor = (Cursor) mAdapter.getItem(i.position);
+ Cursor cursor = mAdapter.getItem(i.position);
Controller.sharePage(activity,
cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE),
cursor.getString(BookmarksLoader.COLUMN_INDEX_URL),
@@ -286,7 +309,7 @@
}
// Only for the Most visited page
case R.id.save_to_bookmarks_menu_id: {
- Cursor cursor = (Cursor) mAdapter.getItem(i.position);
+ Cursor cursor = mAdapter.getItem(i.position);
String name = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
// If the site is bookmarked, the item becomes remove from
@@ -300,7 +323,7 @@
return true;
}
- Bitmap getBitmap(Cursor cursor, int columnIndex) {
+ static Bitmap getBitmap(Cursor cursor, int columnIndex) {
byte[] data = cursor.getBlob(columnIndex);
if (data == null) {
return null;
@@ -311,7 +334,7 @@
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
- Cursor cursor = (Cursor) mAdapter.getItem(info.position);
+ Cursor cursor = mAdapter.getItem(info.position);
boolean isFolder
= cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
if (isFolder) return;
@@ -354,7 +377,6 @@
super.onCreate(icicle);
Bundle args = getArguments();
- mCreateShortcut = args == null ? false : args.getBoolean(EXTRA_SHORTCUT, false);
mDisableNewWindow = args == null ? false : args.getBoolean(EXTRA_DISABLE_WINDOW, false);
}
@@ -369,16 +391,36 @@
mGrid = (GridView) root.findViewById(R.id.grid);
mGrid.setOnItemClickListener(this);
mGrid.setColumnWidth(Controller.getDesiredThumbnailWidth(getActivity()));
- if (!mCreateShortcut) {
- mGrid.setOnCreateContextMenuListener(this);
- }
+ mList = (ListView) root.findViewById(R.id.list);
+ mList.setOnItemClickListener(this);
+ setEnableContextMenu(mEnableContextMenu);
- mAdapter = new BrowserBookmarksAdapter(getActivity());
- mGrid.setAdapter(mAdapter);
+ // Prep the header
+ ViewGroup hc = mHeaderContainer;
+ if (hc == null) {
+ hc = (ViewGroup) root.findViewById(R.id.header_container);
+ hc.setVisibility(View.VISIBLE);
+ }
+ mHeader = inflater.inflate(R.layout.bookmarks_header, hc, true);
+ mCrumbs = (BreadCrumbView) mHeader.findViewById(R.id.crumbs);
+ mCrumbs.setController(this);
+ mSelectBookmarkView = (TextView) mHeader.findViewById(R.id.select_bookmark_view);
+ mSelectBookmarkView.setOnClickListener(this);
+ mRootFolderView = mHeader.findViewById(R.id.root_folder);
+ mRootFolderView.setOnClickListener(this);
+ setShowRootFolder(mShowRootFolder);
// Start the loaders
LoaderManager lm = getLoaderManager();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ mCurrentView =
+ prefs.getInt(PREF_SELECTED_VIEW, BrowserBookmarksPage.VIEW_THUMBNAILS);
+ if (mCurrentView == BrowserBookmarksPage.VIEW_THUMBNAILS) {
+ mSelectBookmarkView.setText(R.string.bookmark_thumbnail_view);
+ } else {
+ mSelectBookmarkView.setText(R.string.bookmark_list_view);
+ }
+ mAdapter = new BrowserBookmarksAdapter(getActivity(), mCurrentView);
String accountType = prefs.getString(PREF_ACCOUNT_TYPE, DEFAULT_ACCOUNT);
String accountName = prefs.getString(PREF_ACCOUNT_NAME, DEFAULT_ACCOUNT);
if (!TextUtils.isEmpty(accountType) && !TextUtils.isEmpty(accountName)) {
@@ -401,6 +443,27 @@
return root;
}
+ public void setShowRootFolder(boolean show) {
+ mShowRootFolder = show;
+ if (mRootFolderView != null) {
+ if (mShowRootFolder) {
+ mRootFolderView.setVisibility(View.VISIBLE);
+ } else {
+ mRootFolderView.setVisibility(View.GONE);
+ }
+ }
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ if (mHeaderContainer != null) {
+ mHeaderContainer.removeView(mHeader);
+ }
+ mCrumbs.setController(null);
+ mCrumbs = null;
+ }
+
@Override
public void onReceivedIcon(String url, Bitmap icon) {
// A new favicon has been loaded, so let anything attached to the adapter know about it
@@ -409,7 +472,7 @@
}
@Override
- public void onItemClick(AdapterView parent, View v, int position, long id) {
+ public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// It is possible that the view has been canceled when we get to
// this point as back has a higher priority
if (mCanceled) {
@@ -417,22 +480,18 @@
return;
}
- if (mCreateShortcut) {
- Intent intent = createShortcutIntent(position);
- // the activity handles the intent in startActivityFromFragment
- startActivity(intent);
+ Cursor cursor = mAdapter.getItem(position);
+ boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
+ if (mCallbacks != null &&
+ mCallbacks.onBookmarkSelected(cursor, isFolder)) {
return;
}
- Cursor cursor = (Cursor) mAdapter.getItem(position);
- boolean isFolder = cursor.getInt(BookmarksLoader.COLUMN_INDEX_IS_FOLDER) != 0;
- if (!isFolder) {
- mCallbacks.onUrlSelected(getUrl(position), false);
- } else {
+ if (isFolder) {
String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
LoaderManager manager = getLoaderManager();
BookmarksLoader loader =
- (BookmarksLoader) ((Loader) manager.getLoader(LOADER_BOOKMARKS));
+ (BookmarksLoader) ((Loader<?>) manager.getLoader(LOADER_BOOKMARKS));
Uri uri = ContentUris.withAppendedId(
BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER, id);
if (mCrumbs != null) {
@@ -474,26 +533,29 @@
// Do nothing
}
- private Intent createShortcutIntent(int position) {
- Cursor cursor = (Cursor) mAdapter.getItem(position);
+ /* package */ static Intent createShortcutIntent(Context context, Cursor cursor) {
String url = cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
String title = cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE);
Bitmap touchIcon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_TOUCH_ICON);
Bitmap favicon = getBitmap(cursor, BookmarksLoader.COLUMN_INDEX_FAVICON);
- return BookmarkUtils.createAddToHomeIntent(getActivity(), url, title, touchIcon, favicon);
+ return BookmarkUtils.createAddToHomeIntent(context, url, title, touchIcon, favicon);
}
private void loadUrl(int position) {
- mCallbacks.onUrlSelected(getUrl(position), false);
+ if (mCallbacks != null) {
+ mCallbacks.onBookmarkSelected(mAdapter.getItem(position), false);
+ }
}
private void openInNewWindow(int position) {
- mCallbacks.onUrlSelected(getUrl(position), true);
+ if (mCallbacks != null) {
+ mCallbacks.onOpenInNewWindow(mAdapter.getItem(position));
+ }
}
private void editBookmark(int position) {
Intent intent = new Intent(getActivity(), AddBookmarkPage.class);
- Cursor cursor = (Cursor) mAdapter.getItem(position);
+ Cursor cursor = mAdapter.getItem(position);
Bundle item = new Bundle();
item.putString(BrowserContract.Bookmarks.TITLE,
cursor.getString(BookmarksLoader.COLUMN_INDEX_TITLE));
@@ -576,7 +638,7 @@
private void displayRemoveBookmarkDialog(final int position) {
// Put up a dialog asking if the user really wants to
// delete the bookmark
- Cursor cursor = (Cursor) mAdapter.getItem(position);
+ Cursor cursor = mAdapter.getItem(position);
Context context = getActivity();
final ContentResolver resolver = context.getContentResolver();
final Uri uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI,
@@ -599,8 +661,11 @@
}
private String getUrl(int position) {
- Cursor cursor = (Cursor) mAdapter.getItem(position);
- return cursor.getString(BookmarksLoader.COLUMN_INDEX_URL);
+ return getUrl(mAdapter.getItem(position));
+ }
+
+ /* package */ static String getUrl(Cursor c) {
+ return c.getString(BookmarksLoader.COLUMN_INDEX_URL);
}
private void copy(CharSequence text) {
@@ -609,4 +674,109 @@
cm.setPrimaryClip(ClipData.newRawUri(null, null, Uri.parse(text.toString())));
}
+ void selectView(int view) {
+ if (view == mCurrentView) {
+ return;
+ }
+ mCurrentView = view;
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ Editor edit = prefs.edit();
+ edit.putInt(PREF_SELECTED_VIEW, mCurrentView);
+ edit.apply();
+ if (mEmptyView.getVisibility() == View.VISIBLE) {
+ return;
+ }
+ setupBookmarkView();
+ }
+
+ private void setupBookmarkView() {
+ mAdapter.selectView(mCurrentView);
+ switch (mCurrentView) {
+ case VIEW_THUMBNAILS:
+ mList.setAdapter(null);
+ mGrid.setAdapter(mAdapter);
+ mGrid.setVisibility(View.VISIBLE);
+ mList.setVisibility(View.GONE);
+ break;
+ case VIEW_LIST:
+ mGrid.setAdapter(null);
+ mList.setAdapter(mAdapter);
+ mGrid.setVisibility(View.GONE);
+ mList.setVisibility(View.VISIBLE);
+ break;
+ }
+ }
+
+ public BreadCrumbView getBreadCrumb() {
+ return mCrumbs;
+ }
+
+ /**
+ * BreadCrumb controller callback
+ */
+ @Override
+ public void onTop(int level, Object data) {
+ onFolderChange(level, data);
+ }
+
+ @Override
+ public void onClick(View view) {
+ if (mSelectBookmarkView == view) {
+ PopupMenu popup = new PopupMenu(getActivity(), mSelectBookmarkView);
+ popup.getMenuInflater().inflate(R.menu.bookmark_view,
+ popup.getMenu());
+ popup.setOnMenuItemClickListener(this);
+ popup.show();
+ } else if (mRootFolderView == view) {
+ mCrumbs.clear();
+ }
+ }
+
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.list_view:
+ mSelectBookmarkView.setText(R.string.bookmark_list_view);
+ selectView(BrowserBookmarksPage.VIEW_LIST);
+ return true;
+ case R.id.thumbnail_view:
+ mSelectBookmarkView.setText(R.string.bookmark_thumbnail_view);
+ selectView(BrowserBookmarksPage.VIEW_THUMBNAILS);
+ return true;
+ }
+ return false;
+ }
+
+ public boolean onBackPressed() {
+ if (mCrumbs != null &&
+ mCrumbs.size() > 0) {
+ mCrumbs.popView();
+ return true;
+ }
+ return false;
+ }
+
+ public void setCallbackListener(BookmarksPageCallbacks callbackListener) {
+ mCallbacks = callbackListener;
+ }
+
+ public void setEnableContextMenu(boolean enable) {
+ mEnableContextMenu = enable;
+ if (mGrid != null) {
+ if (mEnableContextMenu) {
+ registerForContextMenu(mGrid);
+ } else {
+ unregisterForContextMenu(mGrid);
+ mGrid.setLongClickable(false);
+ }
+ }
+ if (mList != null) {
+ if (mEnableContextMenu) {
+ registerForContextMenu(mList);
+ } else {
+ unregisterForContextMenu(mList);
+ mList.setLongClickable(false);
+ }
+ }
+ }
}
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 069f886..1229e4b 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -567,6 +567,13 @@
ed.apply();
}
+ /* package */ void disableAutoFill(Context ctx) {
+ autoFillEnabled = false;
+ Editor ed = PreferenceManager.getDefaultSharedPreferences(ctx).edit();
+ ed.putBoolean(PREF_AUTOFILL_ENABLED, false);
+ ed.apply();
+ }
+
/**
* Add a WebSettings object to the list of observers that will be updated
* when update() is called.
@@ -716,7 +723,7 @@
showSecurityWarnings = true;
rememberPasswords = true;
saveFormData = true;
- autoFillEnabled = false;
+ autoFillEnabled = true;
openInBackground = false;
autoFitPage = true;
loadsPageInOverviewMode = true;
diff --git a/src/com/android/browser/CombinedBookmarkHistoryView.java b/src/com/android/browser/CombinedBookmarkHistoryView.java
index c078b51..15f31f6 100644
--- a/src/com/android/browser/CombinedBookmarkHistoryView.java
+++ b/src/com/android/browser/CombinedBookmarkHistoryView.java
@@ -22,6 +22,7 @@
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.res.Resources;
+import android.database.Cursor;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -29,6 +30,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.ViewGroup;
import android.webkit.WebIconDatabase;
import android.webkit.WebIconDatabase.IconListener;
import android.widget.LinearLayout;
@@ -44,7 +46,7 @@
}
public class CombinedBookmarkHistoryView extends LinearLayout
- implements OnClickListener, BreadCrumbView.Controller {
+ implements OnClickListener {
final static String STARTING_FRAGMENT = "fragment";
@@ -59,10 +61,11 @@
long mCurrentFragment;
View mTabs;
- BreadCrumbView mCrumbs;
TextView mTabBookmarks;
TextView mTabHistory;
TextView mAddBookmark;
+ View mSeperateSelectAdd;
+ ViewGroup mBookmarksHeader;
BrowserBookmarksPage mBookmarks;
BrowserHistoryPage mHistory;
@@ -116,12 +119,12 @@
// setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
mTabs = findViewById(R.id.tabs);
- mCrumbs = (BreadCrumbView) findViewById(R.id.crumbs);
- mCrumbs.setController(this);
+ mBookmarksHeader = (ViewGroup) findViewById(R.id.header_container);
mTabBookmarks = (TextView) findViewById(R.id.bmtab);
mTabHistory = (TextView) findViewById(R.id.historytab);
mAddBookmark = (TextView) findViewById(R.id.addbm);
+ mSeperateSelectAdd = findViewById(R.id.seperate_select_add);
mAddBookmark.setOnClickListener(this);
mTabHistory.setOnClickListener(this);
mTabBookmarks.setOnClickListener(this);
@@ -146,8 +149,26 @@
}
+ private BookmarksPageCallbacks mBookmarkCallbackWrapper = new BookmarksPageCallbacks() {
+ @Override
+ public boolean onOpenInNewWindow(Cursor c) {
+ mUiController.onUrlSelected(BrowserBookmarksPage.getUrl(c), true);
+ return true;
+ }
+
+ @Override
+ public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
+ if (isFolder) {
+ return false;
+ }
+ mUiController.onUrlSelected(BrowserBookmarksPage.getUrl(c), false);
+ return true;
+ }
+ };
+
private void initFragments(Bundle extras) {
- mBookmarks = BrowserBookmarksPage.newInstance(mUiController, mCrumbs, extras);
+ mBookmarks = BrowserBookmarksPage.newInstance(mBookmarkCallbackWrapper,
+ extras, mBookmarksHeader);
mHistory = BrowserHistoryPage.newInstance(mUiController, extras);
}
@@ -157,14 +178,13 @@
switch (id) {
case FRAGMENT_ID_BOOKMARKS:
fragment = mBookmarks;
- mCrumbs.setVisibility(View.VISIBLE);
- if (notify) {
- mCrumbs.notifyController();
- }
+ mSeperateSelectAdd.setVisibility(View.VISIBLE);
+ mBookmarksHeader.setVisibility(View.VISIBLE);
break;
case FRAGMENT_ID_HISTORY:
fragment = mHistory;
- mCrumbs.setVisibility(View.GONE);
+ mBookmarksHeader.setVisibility(View.INVISIBLE);
+ mSeperateSelectAdd.setVisibility(View.INVISIBLE);
break;
default:
throw new IllegalArgumentException();
@@ -178,6 +198,19 @@
}
@Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ FragmentManager fm = mActivity.getFragmentManager();
+ FragmentTransaction transaction = fm.openTransaction();
+ if (mCurrentFragment == FRAGMENT_ID_BOOKMARKS) {
+ transaction.remove(mBookmarks);
+ } else if (mCurrentFragment == FRAGMENT_ID_HISTORY) {
+ transaction.remove(mHistory);
+ }
+ transaction.commit();
+ }
+
+ @Override
public void onClick(View view) {
if ((mTabHistory == view) && (mCurrentFragment != FRAGMENT_ID_HISTORY)) {
loadFragment(FRAGMENT_ID_HISTORY, mExtras, false);
@@ -185,7 +218,10 @@
if (mCurrentFragment != FRAGMENT_ID_BOOKMARKS) {
loadFragment(FRAGMENT_ID_BOOKMARKS, mExtras, true);
} else {
- mCrumbs.clear();
+ BreadCrumbView crumbs = mBookmarks.getBreadCrumb();
+ if (crumbs != null) {
+ crumbs.clear();
+ }
}
} else if (mAddBookmark == view) {
mUiController.bookmarkCurrentPage(mBookmarks.getFolderId());
@@ -193,23 +229,12 @@
}
/**
- * BreadCrumb controller callback
- */
- @Override
- public void onTop(int level, Object data) {
- mBookmarks.onFolderChange(level, data);
- }
-
- /**
* callback for back key presses
*/
boolean onBackPressed() {
- if ((mCurrentFragment == FRAGMENT_ID_BOOKMARKS) &&
- (mCrumbs.size() > 0)) {
- mCrumbs.popView();
- return true;
+ if (mCurrentFragment == FRAGMENT_ID_BOOKMARKS) {
+ return mBookmarks.onBackPressed();
}
return false;
}
-
}
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index aabdb26..41e7356 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -47,6 +47,7 @@
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
+import android.preference.PreferenceActivity;
import android.provider.Browser;
import android.provider.BrowserContract;
import android.provider.BrowserContract.History;
@@ -114,6 +115,8 @@
// activity requestCode
final static int PREFERENCES_PAGE = 3;
final static int FILE_SELECTED = 4;
+ final static int AUTOFILL_SETUP = 5;
+
private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
// As the ids are dynamically created, we can't guarantee that they will
@@ -143,6 +146,8 @@
private PageDialogsHandler mPageDialogsHandler;
private NetworkStateHandler mNetworkHandler;
+ private Message mAutoFillSetupMessage;
+
private boolean mShouldShowErrorConsole;
private SystemAllowGeolocationOrigins mSystemAllowGeolocationOrigins;
@@ -306,11 +311,22 @@
mFactory = factory;
}
- WebViewFactory getWebViewFactory() {
+ @Override
+ public WebViewFactory getWebViewFactory() {
return mFactory;
}
@Override
+ public void createSubWindow(Tab tab) {
+ endActionMode();
+ WebView mainView = tab.getWebView();
+ WebView subView = mFactory.createWebView((mainView == null)
+ ? false
+ : mainView.isPrivateBrowsingEnabled());
+ mUi.createSubWindow(tab, subView);
+ }
+
+ @Override
public Activity getActivity() {
return mActivity;
}
@@ -394,6 +410,13 @@
case R.id.view_image_context_menu_id:
loadUrlFromContext(getCurrentTopWebView(), url);
break;
+ case R.id.open_newtab_context_menu_id:
+ final Tab parent = mTabControl.getCurrentTab();
+ final Tab newTab = openTab(url, false);
+ if (newTab != null && newTab != parent) {
+ parent.addChildTab(newTab);
+ }
+ break;
case R.id.bookmark_context_menu_id:
Intent intent = new Intent(mActivity,
AddBookmarkPage.class);
@@ -1032,6 +1055,15 @@
mUploadHandler.onResult(resultCode, intent);
mUploadHandler = null;
break;
+ case AUTOFILL_SETUP:
+ // Determine whether a profile was actually set up or not
+ // and if so, send the message back to the WebTextView to
+ // fill the form with the new profile.
+ if (getSettings().getAutoFillProfile() != null) {
+ mAutoFillSetupMessage.sendToTarget();
+ mAutoFillSetupMessage = null;
+ }
+ break;
default:
break;
}
@@ -1156,7 +1188,7 @@
if (!(v instanceof WebView)) {
return;
}
- WebView webview = (WebView) v;
+ final WebView webview = (WebView) v;
WebView.HitTestResult result = webview.getHitTestResult();
if (result == null) {
return;
@@ -1193,7 +1225,15 @@
menu.setGroupVisible(R.id.ANCHOR_MENU,
type == WebView.HitTestResult.SRC_ANCHOR_TYPE
|| type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
-
+ boolean hitText = type == WebView.HitTestResult.SRC_ANCHOR_TYPE
+ || type == WebView.HitTestResult.PHONE_TYPE
+ || type == WebView.HitTestResult.EMAIL_TYPE
+ || type == WebView.HitTestResult.GEO_TYPE;
+ menu.setGroupVisible(R.id.SELECT_TEXT_MENU, hitText);
+ if (hitText) {
+ menu.findItem(R.id.select_text_menu_id)
+ .setOnMenuItemClickListener(new SelectText(webview));
+ }
// Setup custom handling depending on the type
switch (type) {
case WebView.HitTestResult.PHONE_TYPE:
@@ -1245,17 +1285,36 @@
= menu.findItem(R.id.open_newtab_context_menu_id);
newTabItem.setVisible(showNewTab);
if (showNewTab) {
- newTabItem.setOnMenuItemClickListener(
- new MenuItem.OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- final Tab parent = mTabControl.getCurrentTab();
- final Tab newTab = openTab(extra, false);
- if (newTab != parent) {
- parent.addChildTab(newTab);
+ if (WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE == type) {
+ newTabItem.setOnMenuItemClickListener(
+ new MenuItem.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ final HashMap<String, WebView> hrefMap =
+ new HashMap<String, WebView>();
+ hrefMap.put("webview", webview);
+ final Message msg = mHandler.obtainMessage(
+ FOCUS_NODE_HREF,
+ R.id.open_newtab_context_menu_id,
+ 0, hrefMap);
+ webview.requestFocusNodeHref(msg);
+ return true;
}
- return true;
- }
- });
+ });
+ } else {
+ newTabItem.setOnMenuItemClickListener(
+ new MenuItem.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ final Tab parent = mTabControl.getCurrentTab();
+ final Tab newTab = openTab(extra, false);
+ if (newTab != parent) {
+ parent.addChildTab(newTab);
+ }
+ return true;
+ }
+ });
+ }
}
menu.findItem(R.id.bookmark_context_menu_id).setVisible(
Bookmarks.urlHasAcceptableScheme(extra));
@@ -1884,6 +1943,22 @@
}
}
+ private static class SelectText implements OnMenuItemClickListener {
+ private WebView mWebView;
+
+ public boolean onMenuItemClick(MenuItem item) {
+ if (mWebView != null) {
+ return mWebView.selectText();
+ }
+ return false;
+ }
+
+ public SelectText(WebView webView) {
+ mWebView = webView;
+ }
+
+ }
+
/********************** TODO: UI stuff *****************************/
// these methods have been copied, they still need to be cleaned up
@@ -2348,4 +2423,14 @@
return mMenuIsDown;
}
+ public void setupAutoFill(Message message) {
+ // Open the settings activity at the AutoFill profile fragment so that
+ // the user can create a new profile. When they return, we will dispatch
+ // the message so that we can autofill the form using their new profile.
+ Intent intent = new Intent(mActivity, BrowserPreferencesPage.class);
+ intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT,
+ AutoFillSettingsFragment.class.getName());
+ mAutoFillSetupMessage = message;
+ mActivity.startActivityForResult(intent, AUTOFILL_SETUP);
+ }
}
diff --git a/src/com/android/browser/ShortcutActivity.java b/src/com/android/browser/ShortcutActivity.java
index 354d694..57cb4a7 100644
--- a/src/com/android/browser/ShortcutActivity.java
+++ b/src/com/android/browser/ShortcutActivity.java
@@ -17,62 +17,51 @@
package com.android.browser;
import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
import android.content.Intent;
+import android.database.Cursor;
import android.os.Bundle;
public class ShortcutActivity extends Activity
- implements BookmarksHistoryCallbacks {
+ implements BookmarksPageCallbacks {
+
+ private BrowserBookmarksPage mBookmarks;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ // TODO: Is this needed?
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
- FragmentManager fm = getFragmentManager();
- FragmentTransaction transaction = fm.openTransaction();
- Bundle extras = new Bundle();
- extras.putBoolean(BrowserBookmarksPage.EXTRA_SHORTCUT, true);
- extras.putBoolean(BrowserBookmarksPage.EXTRA_DISABLE_WINDOW, true);
- Fragment frag = BrowserBookmarksPage.newInstance(this, null, extras);
- transaction.add(android.R.id.content, frag);
- transaction.commit();
+ mBookmarks = BrowserBookmarksPage.newInstance(this, null, null);
+ mBookmarks.setEnableContextMenu(false);
+ mBookmarks.setShowRootFolder(true);
+ getFragmentManager()
+ .openTransaction()
+ .add(android.R.id.content, mBookmarks)
+ .commit();
}
+ // BookmarksPageCallbacks
- /**
- * handle fragment startActivity
- */
@Override
- public void startActivityFromFragment(Fragment f, Intent intent, int requestCode) {
+ public boolean onBookmarkSelected(Cursor c, boolean isFolder) {
+ if (isFolder) {
+ return false;
+ }
+ Intent intent = BrowserBookmarksPage.createShortcutIntent(this, c);
setResult(RESULT_OK, intent);
finish();
+ return true;
}
@Override
- public void finish() {
- super.finish();
+ public boolean onOpenInNewWindow(Cursor c) {
+ return false;
}
- // BookmarksHistoryCallbacks
-
- /**
- * not used for shortcuts
- */
@Override
- public void onRemoveParentChildRelationships() {}
-
- @Override
- public void onComboCanceled() {
- setResult(RESULT_CANCELED);
- finish();
+ public void onBackPressed() {
+ if (!mBookmarks.onBackPressed()) {
+ super.onBackPressed();
+ }
}
-
- /**
- * not used for shortcuts
- */
- @Override
- public void onUrlSelected(String url, boolean newWindow) {}
-
}
diff --git a/src/com/android/browser/SuggestionsAdapter.java b/src/com/android/browser/SuggestionsAdapter.java
index d3609b2..8c06353 100644
--- a/src/com/android/browser/SuggestionsAdapter.java
+++ b/src/com/android/browser/SuggestionsAdapter.java
@@ -22,6 +22,8 @@
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
import android.provider.BrowserContract;
import android.text.TextUtils;
import android.view.LayoutInflater;
@@ -32,24 +34,21 @@
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
-import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
/**
* adapter to wrap multiple cursors for url/search completions
*/
public class SuggestionsAdapter extends BaseAdapter implements Filterable, OnClickListener {
- static final int TYPE_SEARCH = 0;
- static final int TYPE_SUGGEST = 1;
- static final int TYPE_BOOKMARK = 2;
- static final int TYPE_SUGGEST_URL = 3;
- static final int TYPE_HISTORY = 4;
+ static final int TYPE_BOOKMARK = 0;
+ static final int TYPE_SUGGEST_URL = 1;
+ static final int TYPE_HISTORY = 2;
+ static final int TYPE_SEARCH = 3;
+ static final int TYPE_SUGGEST = 4;
private static final String[] COMBINED_PROJECTION =
{BrowserContract.Combined._ID, BrowserContract.Combined.TITLE,
@@ -62,12 +61,14 @@
Context mContext;
Filter mFilter;
- SuggestionResults mResults;
+ SuggestionResults mMixedResults;
+ List<SuggestItem> mSuggestResults, mFilterResults;
List<CursorSource> mSources;
boolean mLandscapeMode;
CompletionListener mListener;
int mLinesPortrait;
int mLinesLandscape;
+ Object mResultsLock = new Object();
interface CompletionListener {
@@ -87,21 +88,21 @@
mLinesLandscape = mContext.getResources().
getInteger(R.integer.max_suggest_lines_landscape);
mFilter = new SuggestFilter();
- addSource(new SuggestCursor());
addSource(new SearchesCursor());
addSource(new CombinedCursor());
}
public void setLandscapeMode(boolean mode) {
mLandscapeMode = mode;
+ notifyDataSetChanged();
}
public int getLeftCount() {
- return mResults.getLeftCount();
+ return mMixedResults.getLeftCount();
}
public int getRightCount() {
- return mResults.getRightCount();
+ return mMixedResults.getRightCount();
}
public void addSource(CursorSource c) {
@@ -131,32 +132,32 @@
@Override
public int getCount() {
- return (mResults == null) ? 0 : mResults.getLineCount();
+ return (mMixedResults == null) ? 0 : mMixedResults.getLineCount();
}
@Override
public SuggestItem getItem(int position) {
- if (mResults == null) {
+ if (mMixedResults == null) {
return null;
}
if (mLandscapeMode) {
- if (position >= mResults.getLineCount()) {
+ if (position >= mMixedResults.getLineCount()) {
// right column
- position = position - mResults.getLineCount();
+ position = position - mMixedResults.getLineCount();
// index in column
- if (position >= mResults.getRightCount()) {
+ if (position >= mMixedResults.getRightCount()) {
return null;
}
- return mResults.items.get(position + mResults.getLeftCount());
+ return mMixedResults.items.get(position + mMixedResults.getLeftCount());
} else {
// left column
- if (position >= mResults.getLeftCount()) {
+ if (position >= mMixedResults.getLeftCount()) {
return null;
}
- return mResults.items.get(position);
+ return mMixedResults.items.get(position);
}
} else {
- return mResults.items.get(position);
+ return mMixedResults.items.get(position);
}
}
@@ -168,34 +169,35 @@
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(mContext);
+ View view = convertView;
+ if (view == null) {
+ view = inflater.inflate(R.layout.suggestion_two_column, parent, false);
+ }
+ View s1 = view.findViewById(R.id.suggest1);
+ View s2 = view.findViewById(R.id.suggest2);
+ View div = view.findViewById(R.id.suggestion_divider);
if (mLandscapeMode) {
- View view = inflater.inflate(R.layout.suggestion_two_column, parent, false);
SuggestItem item = getItem(position);
- View iv = view.findViewById(R.id.suggest1);
- LayoutParams lp = new LayoutParams(iv.getLayoutParams());
- lp.weight = 0.5f;
- iv.setLayoutParams(lp);
+ div.setVisibility(View.VISIBLE);
if (item != null) {
- bindView(iv, item);
+ s1.setVisibility(View.VISIBLE);
+ bindView(s1, item);
} else {
- iv.setVisibility((mResults.getLeftCount() == 0) ? View.GONE :
- View.INVISIBLE);
+ s1.setVisibility(View.INVISIBLE);
}
- item = getItem(position + mResults.getLineCount());
- iv = view.findViewById(R.id.suggest2);
- lp = new LayoutParams(iv.getLayoutParams());
- lp.weight = 0.5f;
- iv.setLayoutParams(lp);
+ item = getItem(position + mMixedResults.getLineCount());
if (item != null) {
- bindView(iv, item);
+ s2.setVisibility(View.VISIBLE);
+ bindView(s2, item);
} else {
- iv.setVisibility((mResults.getRightCount() == 0) ? View.GONE :
- View.INVISIBLE);
+ s2.setVisibility(View.INVISIBLE);
}
return view;
} else {
- View view = inflater.inflate(R.layout.suggestion_item, parent, false);
- bindView(view, getItem(position));
+ s1.setVisibility(View.VISIBLE);
+ div.setVisibility(View.GONE);
+ s2.setVisibility(View.GONE);
+ bindView(s1, getItem(position));
return view;
}
}
@@ -241,9 +243,52 @@
ic2.setOnClickListener(this);
}
- class SuggestFilter extends Filter {
+ class SlowFilterTask extends AsyncTask<CharSequence, Void, List<SuggestItem>> {
- SuggestionResults results;
+ @Override
+ protected List<SuggestItem> doInBackground(CharSequence... params) {
+ SuggestCursor cursor = new SuggestCursor();
+ cursor.runQuery(params[0]);
+ List<SuggestItem> results = new ArrayList<SuggestItem>();
+ int count = cursor.getCount();
+ for (int i = 0; i < count; i++) {
+ results.add(cursor.getItem());
+ cursor.moveToNext();
+ }
+ cursor.close();
+ return results;
+ }
+
+ @Override
+ protected void onPostExecute(List<SuggestItem> items) {
+ mSuggestResults = items;
+ mMixedResults = buildSuggestionResults();
+ notifyDataSetChanged();
+ mListener.onFilterComplete(mMixedResults.getLineCount());
+ }
+ }
+
+ SuggestionResults buildSuggestionResults() {
+ SuggestionResults mixed = new SuggestionResults();
+ List<SuggestItem> filter, suggest;
+ synchronized (mResultsLock) {
+ filter = mFilterResults;
+ suggest = mSuggestResults;
+ }
+ if (filter != null) {
+ for (SuggestItem item : filter) {
+ mixed.addResult(item);
+ }
+ }
+ if (suggest != null) {
+ for (SuggestItem item : suggest) {
+ mixed.addResult(item);
+ }
+ }
+ return mixed;
+ }
+
+ class SuggestFilter extends Filter {
@Override
public CharSequence convertResultToString(Object item) {
@@ -258,6 +303,10 @@
}
}
+ void startSuggestionsAsync(final CharSequence constraint) {
+ new SlowFilterTask().execute(constraint);
+ }
+
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults res = new FilterResults();
@@ -266,47 +315,40 @@
res.values = null;
return res;
}
- results = new SuggestionResults();
+ startSuggestionsAsync(constraint);
+ List<SuggestItem> filterResults = new ArrayList<SuggestItem>();
if (constraint != null) {
for (CursorSource sc : mSources) {
sc.runQuery(constraint);
}
- mixResults();
+ mixResults(filterResults);
}
- res.count = results.getLineCount();
- res.values = results;
+ synchronized (mResultsLock) {
+ mFilterResults = filterResults;
+ }
+ SuggestionResults mixed = buildSuggestionResults();
+ res.count = mixed.getLineCount();
+ res.values = mixed;
return res;
}
- void mixResults() {
+ void mixResults(List<SuggestItem> results) {
+ int maxLines = mLandscapeMode ? mLinesLandscape : (mLinesPortrait / 2);
for (int i = 0; i < mSources.size(); i++) {
CursorSource s = mSources.get(i);
- int n = Math.min(s.getCount(), (mLandscapeMode ? mLinesLandscape
- : mLinesPortrait));
+ int n = Math.min(s.getCount(), maxLines);
+ maxLines -= n;
boolean more = false;
for (int j = 0; j < n; j++) {
- results.addResult(s.getItem());
+ results.add(s.getItem());
more = s.moveToNext();
}
- if (s instanceof SuggestCursor) {
- int k = n;
- while (more && (k < mLinesPortrait)) {
- SuggestItem item = s.getItem();
- if (item.type == TYPE_SUGGEST_URL) {
- results.addResult(item);
- break;
- }
- more = s.moveToNext();
- k++;
-
- }
- }
}
}
@Override
protected void publishResults(CharSequence constraint, FilterResults fresults) {
- mResults = (SuggestionResults) fresults.values;
+ mMixedResults = (SuggestionResults) fresults.values;
mListener.onFilterComplete(fresults.count);
notifyDataSetChanged();
}
@@ -343,20 +385,22 @@
int getLineCount() {
if (mLandscapeMode) {
- return Math.max(getLeftCount(), getRightCount());
+ return Math.min(mLinesLandscape,
+ Math.max(getLeftCount(), getRightCount()));
} else {
- return getLeftCount() + getRightCount();
+ return Math.min(mLinesPortrait, getLeftCount() + getRightCount());
}
}
int getLeftCount() {
- return counts[TYPE_SEARCH] + counts[TYPE_SUGGEST];
- }
-
- int getRightCount() {
return counts[TYPE_BOOKMARK] + counts[TYPE_HISTORY] + counts[TYPE_SUGGEST_URL];
}
+ int getRightCount() {
+ return counts[TYPE_SEARCH] + counts[TYPE_SUGGEST];
+ }
+
+ @Override
public String toString() {
if (items == null) return null;
if (items.size() == 0) return "[]";
@@ -513,7 +557,7 @@
mCursor.close();
}
String like = constraint + "%";
- String[] args = new String[] {constraint.toString()};
+ String[] args = new String[] {like};
String selection = BrowserContract.Searches.SEARCH + " LIKE ?";
Uri.Builder ub = BrowserContract.Searches.CONTENT_URI.buildUpon();
ub.appendQueryParameter(BrowserContract.PARAM_LIMIT,
@@ -571,4 +615,9 @@
}
+ public void clearCache() {
+ mFilterResults = null;
+ mSuggestResults = null;
+ }
+
}
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index ec42584..a048c2d 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -36,7 +36,6 @@
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
import android.view.ViewStub;
import android.webkit.ConsoleMessage;
import android.webkit.DownloadListener;
@@ -53,9 +52,9 @@
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
-import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
+import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
@@ -706,7 +705,7 @@
mWebViewController.showSslCertificateOnError(view,
handler, error);
}
- }).setNegativeButton(R.string.cancel,
+ }).setNegativeButton(R.string.ssl_go_back,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int whichButton) {
@@ -1063,6 +1062,35 @@
public void getVisitedHistory(final ValueCallback<String[]> callback) {
mWebViewController.getVisitedHistory(callback);
}
+
+ @Override
+ public void setupAutoFill(Message message) {
+ // Prompt the user to set up their profile.
+ final Message msg = message;
+ AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
+ builder.setMessage(R.string.autofill_setup_dialog_message)
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ // Take user to the AutoFill profile editor. When they return,
+ // we will send the message that we pass here which will trigger
+ // the form to get filled out with their new profile.
+ mWebViewController.setupAutoFill(msg);
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ // Disable autofill and show a toast with how to turn it on again.
+ BrowserSettings s = BrowserSettings.getInstance();
+ s.addObserver(mMainView.getSettings());
+ s.disableAutoFill(mActivity);
+ s.update();
+ Toast.makeText(mActivity, R.string.autofill_setup_dialog_negative_toast,
+ Toast.LENGTH_LONG).show();
+ }
+ }).show();
+ }
};
// -------------------------------------------------------------------------
@@ -1278,15 +1306,7 @@
*/
boolean createSubWindow() {
if (mSubView == null) {
- mWebViewController.endActionMode();
- mSubViewContainer = mInflateService.inflate(
- R.layout.browser_subwindow, null);
- mSubView = (WebView) mSubViewContainer.findViewById(R.id.webview);
- mSubView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
- // use trackball directly
- mSubView.setMapTrackballToArrowKeys(false);
- // Enable the built-in zoom
- mSubView.getSettings().setBuiltInZoomControls(true);
+ mWebViewController.createSubWindow(this);
mSubView.setWebViewClient(new SubWindowClient(mWebViewClient,
mWebViewController));
mSubView.setWebChromeClient(new SubWindowChromeClient(
@@ -1307,15 +1327,6 @@
}
});
mSubView.setOnCreateContextMenuListener(mActivity);
- final BrowserSettings s = BrowserSettings.getInstance();
- s.addObserver(mSubView.getSettings()).update(s, null);
- final ImageButton cancel = (ImageButton) mSubViewContainer
- .findViewById(R.id.subwindow_close);
- cancel.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- mSubView.getWebChromeClient().onCloseWindow(mSubView);
- }
- });
return true;
}
return false;
@@ -1463,10 +1474,18 @@
return mSubView;
}
+ void setSubWebView(WebView subView) {
+ mSubView = subView;
+ }
+
View getSubViewContainer() {
return mSubViewContainer;
}
+ void setSubViewContainer(View subViewContainer) {
+ mSubViewContainer = subViewContainer;
+ }
+
/**
* @return The geolocation permissions prompt for this tab.
*/
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index 08cf33a..3a8a5cd 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -25,6 +25,7 @@
import android.view.Menu;
import android.view.View;
import android.webkit.WebChromeClient.CustomViewCallback;
+import android.webkit.WebView;
import java.util.List;
@@ -57,6 +58,8 @@
public void attachTab(Tab tab);
+ public void createSubWindow(Tab tab, WebView subWebView);
+
public void attachSubWindow(View subContainer);
public void removeSubWindow(View subContainer);
diff --git a/src/com/android/browser/UrlInputView.java b/src/com/android/browser/UrlInputView.java
index e7fc233..2e29f26 100644
--- a/src/com/android/browser/UrlInputView.java
+++ b/src/com/android/browser/UrlInputView.java
@@ -18,7 +18,6 @@
import com.android.browser.SuggestionsAdapter.CompletionListener;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
@@ -68,6 +67,7 @@
setAdapter(mAdapter);
setSelectAllOnFocus(false);
onConfigurationChanged(ctx.getResources().getConfiguration());
+ setThreshold(1);
}
void setContainer(View container) {
@@ -76,29 +76,35 @@
@Override
protected void onConfigurationChanged(Configuration config) {
+ super.onConfigurationChanged(config);
mLandscape = (config.orientation &
Configuration.ORIENTATION_LANDSCAPE) > 0;
+ mAdapter.setLandscapeMode(mLandscape);
if (isPopupShowing() && (getVisibility() == View.VISIBLE)) {
- dismissDropDown();
- getFilter().filter(getText());
+ setupDropDown();
}
}
@Override
public void showDropDown() {
+ setupDropDown();
+ super.showDropDown();
+ }
+
+ @Override
+ public void dismissDropDown() {
+ super.dismissDropDown();
+ mAdapter.clearCache();
+ }
+
+ private void setupDropDown() {
int width = mContainer.getWidth();
- if (mLandscape && ((mAdapter.getLeftCount() == 0) ||
- (mAdapter.getRightCount() == 0))) {
- width = width / 2;
- }
if (width != getDropDownWidth()) {
setDropDownWidth(width);
}
if (getLeft() != -getDropDownHorizontalOffset()) {
setDropDownHorizontalOffset(-getLeft());
}
- mAdapter.setLandscapeMode(mLandscape);
- super.showDropDown();
}
@Override
diff --git a/src/com/android/browser/WebViewController.java b/src/com/android/browser/WebViewController.java
index fdd8ab1..eeeee18 100644
--- a/src/com/android/browser/WebViewController.java
+++ b/src/com/android/browser/WebViewController.java
@@ -22,6 +22,7 @@
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
+import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.HttpAuthHandler;
@@ -39,6 +40,10 @@
TabControl getTabControl();
+ WebViewFactory getWebViewFactory();
+
+ void createSubWindow(Tab tab);
+
void onPageStarted(Tab tab, WebView view, String url, Bitmap favicon);
void onPageFinished(Tab tab, String url);
@@ -98,4 +103,6 @@
void closeTab(Tab tab);
+ void setupAutoFill(Message message);
+
}
diff --git a/src/com/android/browser/WebViewFactory.java b/src/com/android/browser/WebViewFactory.java
index 6047d1c..1186e65 100644
--- a/src/com/android/browser/WebViewFactory.java
+++ b/src/com/android/browser/WebViewFactory.java
@@ -25,4 +25,6 @@
public WebView createWebView(boolean privateBrowsing);
+ public WebView createSubWebView(boolean privateBrowsing);
+
}
diff --git a/src/com/android/browser/preferences/PersonalPreferencesFragment.java b/src/com/android/browser/preferences/PersonalPreferencesFragment.java
index 656d47a..a0c8ea0 100644
--- a/src/com/android/browser/preferences/PersonalPreferencesFragment.java
+++ b/src/com/android/browser/preferences/PersonalPreferencesFragment.java
@@ -34,6 +34,7 @@
import android.content.OperationApplicationException;
import android.content.SharedPreferences;
import android.database.Cursor;
+import android.os.AsyncTask;
import android.os.Bundle;
import android.os.RemoteException;
import android.preference.Preference;
@@ -80,32 +81,47 @@
refreshUi(context);
}
- void refreshUi(Context context) {
- AccountManager am = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
- Account[] accounts = am.getAccountsByType("com.google");
- if (accounts == null || accounts.length == 0) {
- // No Google accounts setup, don't offer Chrome sync
- if (mChromeSync != null) {
- getPreferenceScreen().removePreference(mChromeSync);
- }
- } else {
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- Bundle args = mChromeSync.getExtras();
- args.putParcelableArray("accounts", accounts);
- mEnabled = BrowserContract.Settings.isSyncEnabled(context);
- if (!mEnabled) {
- // Google accounts are present, but Chrome sync isn't enabled yet.
- // Setup a link to the enable wizard
- mChromeSync.setSummary(R.string.pref_personal_sync_with_chrome_summary);
- } else {
- // Chrome sync is enabled, setup a link to account switcher
- String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME, null);
- mChromeSync.setSummary(accountName);
- args.putString("curAccount", accountName);
- }
- mChromeSync.setOnPreferenceClickListener(this);
+ private class GetAccountsTask extends AsyncTask<Void, Void, Void> {
+ private Context mContext;
+
+ GetAccountsTask(Context ctx) {
+ mContext = ctx;
}
+ protected Void doInBackground(Void... unused) {
+ AccountManager am = (AccountManager) mContext.getSystemService(Context.ACCOUNT_SERVICE);
+ Account[] accounts = am.getAccountsByType("com.google");
+ if (accounts == null || accounts.length == 0) {
+ // No Google accounts setup, don't offer Chrome sync
+ if (mChromeSync != null) {
+ getPreferenceScreen().removePreference(mChromeSync);
+ }
+ } else {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ Bundle args = mChromeSync.getExtras();
+ args.putParcelableArray("accounts", accounts);
+ mEnabled = BrowserContract.Settings.isSyncEnabled(mContext);
+ if (!mEnabled) {
+ // Google accounts are present, but Chrome sync isn't enabled yet.
+ // Setup a link to the enable wizard
+ mChromeSync.setSummary(R.string.pref_personal_sync_with_chrome_summary);
+ } else {
+ // Chrome sync is enabled, setup a link to account switcher
+ String accountName = prefs.getString(BrowserBookmarksPage.PREF_ACCOUNT_NAME,
+ null);
+ mChromeSync.setSummary(accountName);
+ args.putString("curAccount", accountName);
+ }
+ mChromeSync.setOnPreferenceClickListener(PersonalPreferencesFragment.this);
+ }
+
+ return null;
+ }
+ }
+
+ void refreshUi(Context context) {
+ new GetAccountsTask(context).execute();
+
PreferenceScreen autoFillSettings =
(PreferenceScreen)findPreference(BrowserSettings.PREF_AUTOFILL_PROFILE);
autoFillSettings.setDependency(BrowserSettings.PREF_AUTOFILL_ENABLED);