summaryrefslogtreecommitdiffstats
path: root/src/com/android/browser
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-02-10 15:44:04 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-02-10 15:44:04 -0800
commitb7775e1e46a6c8ce0f07747d44c1b1792bb0ce1c (patch)
tree5955e8e4ec01ed58967626e02c703e40a10bd6a8 /src/com/android/browser
parentd9effa543b8c81d48b8324aac00410b8c2a355a0 (diff)
downloadpackages_apps_Browser-b7775e1e46a6c8ce0f07747d44c1b1792bb0ce1c.zip
packages_apps_Browser-b7775e1e46a6c8ce0f07747d44c1b1792bb0ce1c.tar.gz
packages_apps_Browser-b7775e1e46a6c8ce0f07747d44c1b1792bb0ce1c.tar.bz2
auto import from //branches/cupcake/...@130745
Diffstat (limited to 'src/com/android/browser')
-rw-r--r--src/com/android/browser/AddBookmarkPage.java63
-rw-r--r--src/com/android/browser/AddNewBookmark.java6
-rw-r--r--src/com/android/browser/BookmarkItem.java28
-rw-r--r--src/com/android/browser/BrowserActivity.java193
-rw-r--r--src/com/android/browser/BrowserBookmarksPage.java20
-rw-r--r--src/com/android/browser/BrowserDownloadAdapter.java1
-rw-r--r--src/com/android/browser/BrowserHistoryPage.java202
-rw-r--r--src/com/android/browser/BrowserProvider.java383
-rw-r--r--src/com/android/browser/BrowserSettings.java19
-rw-r--r--src/com/android/browser/CombinedBookmarkHistoryActivity.java124
-rw-r--r--src/com/android/browser/FindDialog.java3
-rw-r--r--src/com/android/browser/HistoryItem.java165
-rw-r--r--src/com/android/browser/MostVisitedActivity.java191
-rw-r--r--src/com/android/browser/TabControl.java24
14 files changed, 932 insertions, 490 deletions
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index ea65a46..23c0fac 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -48,8 +48,8 @@ public class AddBookmarkPage extends Activity {
private Bundle mMap;
private static final String[] mProjection =
- { "_id", "url", "bookmark", "created", "title" };
- private static final String WHERE_CLAUSE = "url = ? AND bookmark = 0";
+ { "_id", "url", "bookmark", "created", "title", "visits" };
+ private static final String WHERE_CLAUSE = "url = ?";
private final String[] SELECTION_ARGS = new String[1];
private View.OnClickListener mSaveBookmark = new View.OnClickListener() {
@@ -163,25 +163,58 @@ public class AddBookmarkPage extends Activity {
WHERE_CLAUSE,
SELECTION_ARGS,
null);
- if (c.moveToFirst()) {
- // This means we have been to this site, so convert the
- // history item to a bookmark.
- ContentValues map = new ContentValues();
+ ContentValues map = new ContentValues();
+ if (c.moveToFirst() && c.getInt(c.getColumnIndexOrThrow(
+ Browser.BookmarkColumns.BOOKMARK)) == 0) {
+ // This means we have been to this site but not bookmarked
+ // it, so convert the history item to a bookmark
map.put(Browser.BookmarkColumns.CREATED, creationTime);
map.put(Browser.BookmarkColumns.TITLE, title);
map.put(Browser.BookmarkColumns.BOOKMARK, 1);
cr.update(Browser.BOOKMARKS_URI, map,
"_id = " + c.getInt(0), null);
} else {
- // Adding a bookmark for a site the user has not been to.
- ContentValues map = new ContentValues();
- map.put(Browser.BookmarkColumns.TITLE, title);
- map.put(Browser.BookmarkColumns.URL, url);
- map.put(Browser.BookmarkColumns.CREATED, creationTime);
- map.put(Browser.BookmarkColumns.BOOKMARK, 1);
- map.put(Browser.BookmarkColumns.DATE, 0);
- map.put(Browser.BookmarkColumns.VISITS, 0);
- cr.insert(Browser.BOOKMARKS_URI, map);
+ int count = c.getCount();
+ boolean matchedTitle = false;
+ for (int i = 0; i < count; i++) {
+ // One or more bookmarks already exist for this site.
+ // Check the names of each
+ c.moveToPosition(i);
+ if (c.getString(c.getColumnIndexOrThrow(
+ Browser.BookmarkColumns.TITLE)).equals(title)) {
+ // The old bookmark has the same name.
+ // Update its creation time.
+ map.put(Browser.BookmarkColumns.CREATED,
+ creationTime);
+ cr.update(Browser.BOOKMARKS_URI, map,
+ "_id = " + c.getInt(0), null);
+ matchedTitle = true;
+ }
+ }
+ if (!matchedTitle) {
+ // Adding a bookmark for a site the user has visited,
+ // or a new bookmark (with a different name) for a site
+ // the user has visited
+ map.put(Browser.BookmarkColumns.TITLE, title);
+ map.put(Browser.BookmarkColumns.URL, url);
+ map.put(Browser.BookmarkColumns.CREATED, creationTime);
+ map.put(Browser.BookmarkColumns.BOOKMARK, 1);
+ map.put(Browser.BookmarkColumns.DATE, 0);
+ int visits = 0;
+ if (count > 0) {
+ // The user has already bookmarked, and possibly
+ // visited this site. However, they are creating
+ // a new bookmark with the same url but a different
+ // name. The new bookmark should have the same
+ // number of visits as the already created bookmark.
+ visits = c.getInt(c.getColumnIndexOrThrow(
+ Browser.BookmarkColumns.VISITS));
+ }
+ // Bookmark starts with 3 extra visits so that it will
+ // bubble up in the most visited and goto search box
+ map.put(Browser.BookmarkColumns.VISITS, visits + 3);
+ cr.insert(Browser.BOOKMARKS_URI, map);
+ }
}
WebIconDatabase.getInstance().retainIconForPageUrl(url);
c.deactivate();
diff --git a/src/com/android/browser/AddNewBookmark.java b/src/com/android/browser/AddNewBookmark.java
index 748c9c2..a75d002 100644
--- a/src/com/android/browser/AddNewBookmark.java
+++ b/src/com/android/browser/AddNewBookmark.java
@@ -63,10 +63,6 @@ class AddNewBookmark extends LinearLayout {
* @param url The new url for the bookmark item.
*/
/* package */ void setUrl(String url) {
- if (url.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
- mUrlText.setText(url.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN));
- } else {
- mUrlText.setText(url);
- }
+ mUrlText.setText(url);
}
}
diff --git a/src/com/android/browser/BookmarkItem.java b/src/com/android/browser/BookmarkItem.java
index 0015eaf..a70dd4f 100644
--- a/src/com/android/browser/BookmarkItem.java
+++ b/src/com/android/browser/BookmarkItem.java
@@ -19,19 +19,20 @@ package com.android.browser;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
+import android.view.View;
import android.widget.ImageView;
-import android.widget.RelativeLayout;
+import android.widget.LinearLayout;
import android.widget.TextView;
/**
* Custom layout for an item representing a bookmark in the browser.
*/
-class BookmarkItem extends RelativeLayout {
+class BookmarkItem extends LinearLayout {
- private TextView mTextView;
- private TextView mUrlText;
- private ImageView mImageView;
- private LayoutInflater mFactory;
+ protected TextView mTextView;
+ protected TextView mUrlText;
+ protected ImageView mImageView;
+ protected String mUrl;
/**
* Instantiate a bookmark item, including a default favicon.
@@ -41,11 +42,13 @@ class BookmarkItem extends RelativeLayout {
BookmarkItem(Context context) {
super(context);
- mFactory = LayoutInflater.from(context);
- mFactory.inflate(R.layout.bookmark_item, this);
+ LayoutInflater factory = LayoutInflater.from(context);
+ 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);
+ View star = findViewById(R.id.star);
+ star.setVisibility(View.GONE);
}
/**
@@ -61,8 +64,8 @@ class BookmarkItem extends RelativeLayout {
/**
* Return the name assigned to this bookmark item.
*/
- /* package */ CharSequence getName() {
- return mTextView.getText();
+ /* package */ String getName() {
+ return mTextView.getText().toString();
}
/**
@@ -72,6 +75,10 @@ class BookmarkItem extends RelativeLayout {
return mTextView;
}
+ /* package */ String getUrl() {
+ return mUrl;
+ }
+
/**
* Set the favicon for this item.
*
@@ -101,5 +108,6 @@ class BookmarkItem extends RelativeLayout {
*/
/* package */ void setUrl(String url) {
mUrlText.setText(url);
+ mUrl = url;
}
}
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 170083d..b6942d2 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -54,10 +54,10 @@ import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.PaintDrawable;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
+import android.net.ConnectivityManager;
import android.net.Uri;
import android.net.WebAddress;
import android.net.http.EventHandler;
-import android.net.http.RequestQueue;
import android.net.http.SslCertificate;
import android.net.http.SslError;
import android.os.AsyncTask;
@@ -97,6 +97,7 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
+import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
@@ -730,19 +731,18 @@ public class BrowserActivity extends Activity
http stack */
mNetworkStateChangedFilter = new IntentFilter();
mNetworkStateChangedFilter.addAction(
- RequestQueue.HTTP_NETWORK_STATE_CHANGED_INTENT);
+ ConnectivityManager.CONNECTIVITY_ACTION);
mNetworkStateIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(
- RequestQueue.HTTP_NETWORK_STATE_CHANGED_INTENT)) {
- Boolean up = (Boolean)intent.getExtra(
- RequestQueue.HTTP_NETWORK_STATE_UP);
- onNetworkToggle(up);
+ ConnectivityManager.CONNECTIVITY_ACTION)) {
+ boolean down = intent.getBooleanExtra(
+ ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
+ onNetworkToggle(!down);
}
}
};
- setRequestedOrientation(mSettings.getOrientation());
}
@Override
@@ -1324,14 +1324,8 @@ public class BrowserActivity extends Activity
}
break;
- case R.id.search_menu_id:
- // launch using "global" search, which will bring up the Google search box
- startSearch(null, false,
- createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHMENU), true);
- break;
-
case R.id.bookmarks_menu_id:
- bookmarksPicker();
+ bookmarksOrHistoryPicker(false);
break;
case R.id.windows_menu_id:
@@ -1412,12 +1406,7 @@ public class BrowserActivity extends Activity
break;
case R.id.classic_history_menu_id:
- loadHistory();
- break;
-
- case R.id.bookmark_page_menu_id:
- Browser.saveBookmark(this, getTopWindow().getTitle(),
- getTopWindow().getUrl());
+ bookmarksOrHistoryPicker(true);
break;
case R.id.share_page_menu_id:
@@ -1428,12 +1417,6 @@ public class BrowserActivity extends Activity
getTopWindow().debugDump();
break;
- case R.id.zoom_menu_id:
- // FIXME: Can we move this out of WebView? How does this work
- // for a subwindow?
- getTopWindow().invokeZoomPicker();
- break;
-
case R.id.zoom_in_menu_id:
getTopWindow().zoomIn();
break;
@@ -1446,18 +1429,6 @@ public class BrowserActivity extends Activity
viewDownloads(null);
break;
- case R.id.flip_orientation_menu_id:
- if (mSettings.getOrientation() !=
- ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
- mSettings.setOrientation(this,
- ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
- } else {
- mSettings.setOrientation(this,
- ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- }
- setRequestedOrientation(mSettings.getOrientation());
- break;
-
// -- Tab menu
case R.id.view_tab_menu_id:
if (mTabListener != null && mTabOverview != null) {
@@ -1499,17 +1470,12 @@ public class BrowserActivity extends Activity
}
break;
- case R.id.history_tab_menu_id: {
- Intent i = new Intent(this, BrowserHistoryPage.class);
- i.putExtra("maxTabsOpen",
- mTabControl.getTabCount() >=
- TabControl.MAX_TABS);
- startActivityForResult(i, CLASSIC_HISTORY_PAGE);
- }
+ case R.id.history_tab_menu_id:
+ bookmarksOrHistoryPicker(true);
break;
case R.id.bookmarks_tab_menu_id:
- bookmarksPicker();
+ bookmarksOrHistoryPicker(false);
break;
case R.id.properties_tab_menu_id:
@@ -1570,6 +1536,7 @@ public class BrowserActivity extends Activity
if (mCurrentMenuState != mMenuState) {
menu.setGroupVisible(R.id.MAIN_MENU, false);
menu.setGroupEnabled(R.id.MAIN_MENU, false);
+ menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
menu.setGroupVisible(R.id.TAB_MENU, true);
menu.setGroupEnabled(R.id.TAB_MENU, true);
}
@@ -1582,6 +1549,7 @@ public class BrowserActivity extends Activity
if (mCurrentMenuState != mMenuState) {
menu.setGroupVisible(R.id.MAIN_MENU, false);
menu.setGroupEnabled(R.id.MAIN_MENU, false);
+ menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
menu.setGroupVisible(R.id.TAB_MENU, false);
menu.setGroupEnabled(R.id.TAB_MENU, false);
}
@@ -1590,31 +1558,27 @@ public class BrowserActivity extends Activity
if (mCurrentMenuState != mMenuState) {
menu.setGroupVisible(R.id.MAIN_MENU, true);
menu.setGroupEnabled(R.id.MAIN_MENU, true);
+ menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
menu.setGroupVisible(R.id.TAB_MENU, false);
menu.setGroupEnabled(R.id.TAB_MENU, false);
}
final WebView w = getTopWindow();
- boolean canGoBack = w.canGoBack();
+ boolean canGoBack = false;
+ boolean canGoForward = false;
+ boolean isHome = false;
+ if (w != null) {
+ canGoBack = w.canGoBack();
+ canGoForward = w.canGoForward();
+ isHome = mSettings.getHomePage().equals(w.getUrl());
+ }
final MenuItem back = menu.findItem(R.id.back_menu_id);
- back.setVisible(canGoBack);
back.setEnabled(canGoBack);
- final MenuItem flip =
- menu.findItem(R.id.flip_orientation_menu_id);
- boolean keyboardClosed =
- getResources().getConfiguration().hardKeyboardHidden ==
- Configuration.HARDKEYBOARDHIDDEN_YES;
- flip.setEnabled(keyboardClosed);
-
- boolean isHome = mSettings.getHomePage().equals(w.getUrl());
+
final MenuItem home = menu.findItem(R.id.homepage_menu_id);
- home.setVisible(!isHome);
home.setEnabled(!isHome);
menu.findItem(R.id.forward_menu_id)
- .setEnabled(w.canGoForward());
-
- menu.findItem(R.id.zoom_in_menu_id).setVisible(false);
- menu.findItem(R.id.zoom_out_menu_id).setVisible(false);
+ .setEnabled(canGoForward);
// decide whether to show the share link option
PackageManager pm = getPackageManager();
@@ -1625,13 +1589,6 @@ public class BrowserActivity extends Activity
menu.findItem(R.id.share_page_menu_id).setVisible(
list.size() > 0);
- // Hide the menu+<window number> items
- // Can't set visibility in menu xml file b/c when a
- // group is set visible, all items are set visible.
- for (int i = 0; i < WINDOW_SHORTCUT_ID_ARRAY.length; i++) {
- menu.findItem(WINDOW_SHORTCUT_ID_ARRAY[i]).setVisible(false);
- }
-
// If there is only 1 window, the text will be "New window"
final MenuItem windows = menu.findItem(R.id.windows_menu_id);
windows.setTitleCondensed(mTabControl.getTabCount() > 1 ?
@@ -1741,10 +1698,14 @@ public class BrowserActivity extends Activity
PackageManager.MATCH_DEFAULT_ONLY);
menu.findItem(R.id.share_link_context_menu_id).setVisible(
list.size() > 0);
- break;
-
+ if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
+ break;
+ }
+ // otherwise fall through to handle image part
case WebView.HitTestResult.IMAGE_TYPE:
- menu.setHeaderTitle(extra);
+ if (type == WebView.HitTestResult.IMAGE_TYPE) {
+ menu.setHeaderTitle(extra);
+ }
menu.findItem(R.id.view_image_context_menu_id).setIntent(
new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
menu.findItem(R.id.download_context_menu_id).
@@ -1838,7 +1799,13 @@ public class BrowserActivity extends Activity
// Send the animate message.
final HashMap map = new HashMap();
map.put("view", view);
- map.put("url", url);
+ // Load the url after the AnimatingView has captured the picture. This
+ // prevents any bad layout or bad scale from being used during
+ // animation.
+ if (url != null) {
+ dismissSubWindow(tab);
+ tab.getWebView().loadUrl(url);
+ }
map.put("msg", msg);
mHandler.sendMessageDelayed(mHandler.obtainMessage(
ANIMATE_FROM_OVERVIEW, newTab ? 1 : 0, 0, map), delay);
@@ -2041,7 +2008,7 @@ public class BrowserActivity extends Activity
// Animate from the tab picker. The index supplied is the index to animate
// from.
private void animateFromTabOverview(final AnimatingView view,
- final boolean newTab, final String url, final Message msg) {
+ final boolean newTab, final Message msg) {
// firstVisible is the first visible tab on the screen. This helps
// to know which corner of the screen the selected tab is.
int firstVisible = mTabOverview.getFirstVisiblePosition();
@@ -2063,7 +2030,7 @@ public class BrowserActivity extends Activity
// Find the view at this location.
final View v = mTabOverview.getChildAt(location);
- // Wait until the animation completes to load the url.
+ // Wait until the animation completes to replace the AnimatingView.
final Animation.AnimationListener l =
new Animation.AnimationListener() {
public void onAnimationStart(Animation a) {}
@@ -2078,15 +2045,9 @@ public class BrowserActivity extends Activity
dismissTabOverview(v == null);
TabControl.Tab t =
mTabControl.getCurrentTab();
- WebView w = t.getWebView();
- if (url != null) {
- // Dismiss the subwindow if one exists.
- dismissSubWindow(t);
- w.loadUrl(url);
- }
mMenuState = R.id.MAIN_MENU;
// Resume regular updates.
- w.resumeTimers();
+ t.getWebView().resumeTimers();
// Dispatch the message after the animation
// completes.
if (msg != null) {
@@ -2111,7 +2072,7 @@ public class BrowserActivity extends Activity
// Make the view VISIBLE during the animation.
view.setVisibility(View.VISIBLE);
} else {
- // Go ahead and load the url.
+ // Go ahead and do all the cleanup.
l.onAnimationEnd(null);
}
}
@@ -2450,7 +2411,7 @@ public class BrowserActivity extends Activity
return KeyTracker.State.DONE_TRACKING;
}
if (stage == KeyTracker.Stage.LONG_REPEAT) {
- loadHistory();
+ bookmarksOrHistoryPicker(true);
return KeyTracker.State.DONE_TRACKING;
} else if (stage == KeyTracker.Stage.UP) {
// FIXME: Currently, we do not have a notion of the
@@ -2522,13 +2483,6 @@ public class BrowserActivity extends Activity
}
}
- private void loadHistory() {
- Intent intent = new Intent(this, BrowserHistoryPage.class);
- intent.putExtra("maxTabsOpen",
- mTabControl.getTabCount() >= TabControl.MAX_TABS);
- startActivityForResult(intent, CLASSIC_HISTORY_PAGE);
- }
-
// called by a non-UI thread to post the message
public void postMessage(int what, int arg1, int arg2, Object obj) {
mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2, obj));
@@ -2555,8 +2509,7 @@ public class BrowserActivity extends Activity
case ANIMATE_FROM_OVERVIEW:
final HashMap map = (HashMap) msg.obj;
animateFromTabOverview((AnimatingView) map.get("view"),
- msg.arg1 == 1, (String) map.get("url"),
- (Message) map.get("msg"));
+ msg.arg1 == 1, (Message) map.get("msg"));
break;
case ANIMATE_TO_OVERVIEW:
@@ -2723,6 +2676,18 @@ public class BrowserActivity extends Activity
mInLoad = true;
updateInLoadMenuItems();
+ if (!mIsNetworkUp) {
+ if ( mAlertDialog == null) {
+ mAlertDialog = new AlertDialog.Builder(BrowserActivity.this)
+ .setTitle(R.string.loadSuspendedTitle)
+ .setMessage(R.string.loadSuspended)
+ .setPositiveButton(R.string.ok, null)
+ .show();
+ }
+ if (view != null) {
+ view.setNetworkAvailable(false);
+ }
+ }
// schedule to check memory condition
mHandler.sendMessageDelayed(mHandler.obtainMessage(CHECK_MEMORY),
@@ -3884,7 +3849,7 @@ public class BrowserActivity extends Activity
}
mHttpAuthHandler = handler;
- mHttpAuthenticationDialog = new AlertDialog.Builder(this)
+ AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle(titleText)
.setIcon(android.R.drawable.ic_dialog_alert)
.setView(v)
@@ -3920,12 +3885,17 @@ public class BrowserActivity extends Activity
mHttpAuthenticationDialog = null;
mHttpAuthHandler = null;
}})
- .show();
+ .create();
+ // Make the IME appear when the dialog is displayed if applicable.
+ dialog.getWindow().setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+ dialog.show();
if (focusId != 0) {
- mHttpAuthenticationDialog.findViewById(focusId).requestFocus();
+ dialog.findViewById(focusId).requestFocus();
} else {
v.findViewById(R.id.username_edit).requestFocus();
}
+ mHttpAuthenticationDialog = dialog;
}
public int getProgress() {
@@ -3956,16 +3926,20 @@ public class BrowserActivity extends Activity
}
/**
- * http stack says net has come or gone... inform the user
+ * connectivity manager says net has come or gone... inform the user
* @param up true if net has come up, false if net has gone down
*/
public void onNetworkToggle(boolean up) {
- if (up) {
+ if (up == mIsNetworkUp) {
+ return;
+ } else if (up) {
+ mIsNetworkUp = true;
if (mAlertDialog != null) {
mAlertDialog.cancel();
mAlertDialog = null;
}
} else {
+ mIsNetworkUp = false;
if (mInLoad && mAlertDialog == null) {
mAlertDialog = new AlertDialog.Builder(this)
.setTitle(R.string.loadSuspendedTitle)
@@ -3984,8 +3958,7 @@ public class BrowserActivity extends Activity
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
switch (requestCode) {
- case BOOKMARKS_PAGE:
- case CLASSIC_HISTORY_PAGE:
+ case COMBO_PAGE:
if (resultCode == RESULT_OK && intent != null) {
String data = intent.getAction();
Bundle extras = intent.getExtras();
@@ -4202,13 +4175,13 @@ public class BrowserActivity extends Activity
mMenuState = EMPTY_MENU;
}
- private void bookmarksPicker() {
+ private void bookmarksOrHistoryPicker(boolean startWithHistory) {
WebView current = mTabControl.getCurrentWebView();
if (current == null) {
return;
}
Intent intent = new Intent(this,
- BrowserBookmarksPage.class);
+ CombinedBookmarkHistoryActivity.class);
String title = current.getTitle();
String url = current.getUrl();
// Just in case the user opens bookmarks before a page finishes loading
@@ -4228,7 +4201,11 @@ public class BrowserActivity extends Activity
intent.putExtra("url", url);
intent.putExtra("maxTabsOpen",
mTabControl.getTabCount() >= TabControl.MAX_TABS);
- startActivityForResult(intent, BOOKMARKS_PAGE);
+ if (startWithHistory) {
+ intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
+ CombinedBookmarkHistoryActivity.HISTORY_TAB);
+ }
+ startActivityForResult(intent, COMBO_PAGE);
}
// Called when loading from context menu or LOAD_URL message
@@ -4351,7 +4328,7 @@ public class BrowserActivity extends Activity
return composeSearchUrl(inUrl);
}
- /* package */static String composeSearchUrl(String search) {
+ /* package */ String composeSearchUrl(String search) {
return URLUtil.composeSearchUrl(search, QuickSearch_G,
QUERY_PLACE_HOLDER);
}
@@ -4409,6 +4386,7 @@ public class BrowserActivity extends Activity
boolean mCanChord;
private boolean mInLoad;
+ private boolean mIsNetworkUp;
private boolean mPageStarted;
private boolean mActivityInPause = true;
@@ -4503,8 +4481,6 @@ public class BrowserActivity extends Activity
// "source" parameter for Google search through search key
final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
- // "source" parameter for Google search through search menu
- final static String GOOGLE_SEARCH_SOURCE_SEARCHMENU = "browser-menu";
// "source" parameter for Google search through goto menu
final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
// "source" parameter for Google search through simplily type
@@ -4543,10 +4519,9 @@ public class BrowserActivity extends Activity
private BroadcastReceiver mNetworkStateIntentReceiver;
// activity requestCode
- final static int BOOKMARKS_PAGE = 1;
- final static int CLASSIC_HISTORY_PAGE = 2;
- final static int DOWNLOAD_PAGE = 3;
- final static int PREFERENCES_PAGE = 4;
+ final static int COMBO_PAGE = 1;
+ final static int DOWNLOAD_PAGE = 2;
+ final static int PREFERENCES_PAGE = 3;
// the frenquency of checking whether system memory is low
final static int CHECK_MEMORY_INTERVAL = 30000; // 30 seconds
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index 5c509a8..7708e8b 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -162,7 +162,7 @@ public class BrowserBookmarksPage extends Activity implements
}
mBookmarksAdapter = new BrowserBookmarksAdapter(this,
- getIntent().getStringExtra("title"), mCreateShortcut);
+ getIntent().getStringExtra("url"), mCreateShortcut);
mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false);
ListView listView = (ListView) findViewById(R.id.list);
@@ -204,7 +204,7 @@ public class BrowserBookmarksPage extends Activity implements
} else {
final Intent intent = createShortcutIntent(getUrl(position),
getBookmarkTitle(position));
- setResult(RESULT_OK, intent);
+ setResultToParent(RESULT_OK, intent);
finish();
}
}
@@ -231,7 +231,8 @@ public class BrowserBookmarksPage extends Activity implements
}
private void loadUrl(int position) {
- setResult(RESULT_OK, (new Intent()).setAction(getUrl(position)));
+ Intent intent = (new Intent()).setAction(getUrl(position));
+ setResultToParent(RESULT_OK, intent);
finish();
}
@@ -262,7 +263,7 @@ public class BrowserBookmarksPage extends Activity implements
private void openInNewWindow(int position) {
Bundle b = new Bundle();
b.putBoolean("new_window", true);
- setResult(RESULT_OK,
+ setResultToParent(RESULT_OK,
(new Intent()).setAction(getUrl(position)).putExtras(b));
finish();
@@ -367,9 +368,18 @@ public class BrowserBookmarksPage extends Activity implements
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.isDown()) {
- setResult(RESULT_CANCELED);
+ setResultToParent(RESULT_CANCELED, null);
mCanceled = true;
}
return super.dispatchKeyEvent(event);
}
+
+ // This Activity is generally a sub-Activity of CombinedHistoryActivity. In
+ // that situation, we need to pass our result code up to our parent.
+ // However, if someone calls this Activity directly, then this has no
+ // parent, and it needs to set it on itself.
+ private void setResultToParent(int resultCode, Intent data) {
+ Activity a = getParent() == null ? this : getParent();
+ a.setResult(resultCode, data);
+ }
}
diff --git a/src/com/android/browser/BrowserDownloadAdapter.java b/src/com/android/browser/BrowserDownloadAdapter.java
index 0b509ef..38b83fe 100644
--- a/src/com/android/browser/BrowserDownloadAdapter.java
+++ b/src/com/android/browser/BrowserDownloadAdapter.java
@@ -180,6 +180,7 @@ public class BrowserDownloadAdapter extends ResourceCursorAdapter {
sb.append("/");
sb.append(Formatter.formatFileSize(mContext, totalBytes));
sb.append(")");
+ pb.setIndeterminate(false);
pb.setProgress(progressAmount);
} else {
pb.setIndeterminate(true);
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index 3059126..f7e97c0 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -16,14 +16,17 @@
package com.android.browser;
-import android.app.ListActivity;
+import android.app.Activity;
+import android.app.ExpandableListActivity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.os.Bundle;
+import android.os.Handler;
import android.os.ServiceManager;
import android.provider.Browser;
import android.text.IClipboard;
@@ -41,11 +44,11 @@ import android.view.ContextMenu.ContextMenuInfo;
import android.webkit.DateSorter;
import android.webkit.WebIconDatabase.IconListener;
import android.widget.AdapterView;
-import android.widget.ListAdapter;
-import android.widget.ListView;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.TextView;
-import java.util.HashMap;
import java.util.List;
import java.util.Vector;
@@ -53,22 +56,16 @@ import java.util.Vector;
* Activity for displaying the browser's history, divided into
* days of viewing.
*/
-public class BrowserHistoryPage extends ListActivity {
+public class BrowserHistoryPage extends ExpandableListActivity {
private HistoryAdapter mAdapter;
private DateSorter mDateSorter;
private boolean mMaxTabsOpen;
private final static String LOGTAG = "browser";
- // FIXME: Make this a part of Browser so we do not have more than one
- // copy (other copy is in BrowserBookmarksAdapter).
- // Used to store favicons as we get them from the database
- private final HashMap<String, Bitmap> mUrlsToIcons =
- new HashMap<String, Bitmap>();
// Implementation of WebIconDatabase.IconListener
private class IconReceiver implements IconListener {
public void onReceivedIcon(String url, Bitmap icon) {
- mUrlsToIcons.put(url, icon);
setListAdapter(mAdapter);
}
}
@@ -87,7 +84,7 @@ public class BrowserHistoryPage extends ListActivity {
b.putBoolean("new_window", true);
intent.putExtras(b);
}
- setResult(RESULT_OK, intent);
+ setResultToParent(RESULT_OK, intent);
finish();
}
@@ -111,20 +108,25 @@ public class BrowserHistoryPage extends ListActivity {
mAdapter = new HistoryAdapter();
setListAdapter(mAdapter);
- ListView list = getListView();
+ final ExpandableListView list = getExpandableListView();
list.setOnCreateContextMenuListener(this);
LayoutInflater factory = LayoutInflater.from(this);
View v = factory.inflate(R.layout.empty_history, null);
addContentView(v, new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
list.setEmptyView(v);
-
+ list.post(new Runnable() {
+ public void run() {
+ list.expandGroup(0);
+ }
+ });
mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false);
- Browser.requestAllIcons(getContentResolver(), null, mIconReceiver);
+ CombinedBookmarkHistoryActivity.getIconListenerSet(getContentResolver())
+ .addListener(mIconReceiver);
// initialize the result to canceled, so that if the user just presses
// back then it will have the correct result
- setResult(RESULT_CANCELED);
+ setResultToParent(RESULT_CANCELED, null);
}
@Override
@@ -160,9 +162,12 @@ public class BrowserHistoryPage extends ListActivity {
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
- AdapterView.AdapterContextMenuInfo i =
- (AdapterView.AdapterContextMenuInfo)
- menuInfo;
+ ExpandableListContextMenuInfo i =
+ (ExpandableListContextMenuInfo) menuInfo;
+ // Do not allow a context menu to come up from the group views.
+ if (!(i.targetView instanceof HistoryItem)) {
+ return;
+ }
// Inflate the menu
MenuInflater inflater = getMenuInflater();
@@ -174,7 +179,7 @@ public class BrowserHistoryPage extends ListActivity {
// Only show open in new tab if we have not maxed out available tabs
menu.findItem(R.id.new_window_context_menu_id).setVisible(!mMaxTabsOpen);
- // decide whether to show the share link option
+ // decide whether to show the share link option
PackageManager pm = getPackageManager();
Intent send = new Intent(Intent.ACTION_SEND);
send.setType("text/plain");
@@ -188,8 +193,8 @@ public class BrowserHistoryPage extends ListActivity {
@Override
public boolean onContextItemSelected(MenuItem item) {
- AdapterView.AdapterContextMenuInfo i =
- (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
+ ExpandableListContextMenuInfo i =
+ (ExpandableListContextMenuInfo) item.getMenuInfo();
String url = ((HistoryItem)i.targetView).getUrl();
String title = ((HistoryItem)i.targetView).getName();
switch (item.getItemId()) {
@@ -219,13 +224,41 @@ public class BrowserHistoryPage extends ListActivity {
}
@Override
- protected void onListItemClick(ListView l, View v, int position, long id) {
+ public boolean onChildClick(ExpandableListView parent, View v,
+ int groupPosition, int childPosition, long id) {
if (v instanceof HistoryItem) {
loadUrl(((HistoryItem) v).getUrl(), false);
+ return true;
}
+ return false;
+ }
+
+ // This Activity is generally a sub-Activity of CombinedHistoryActivity. In
+ // that situation, we need to pass our result code up to our parent.
+ // However, if someone calls this Activity directly, then this has no
+ // parent, and it needs to set it on itself.
+ private void setResultToParent(int resultCode, Intent data) {
+ Activity a = getParent() == null ? this : getParent();
+ a.setResult(resultCode, data);
}
- private class HistoryAdapter implements ListAdapter {
+ private class ChangeObserver extends ContentObserver {
+ public ChangeObserver() {
+ super(new Handler());
+ }
+
+ @Override
+ public boolean deliverSelfNotifications() {
+ return true;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ mAdapter.refreshData();
+ }
+ }
+
+ private class HistoryAdapter implements ExpandableListAdapter {
// Map of items. Negative values are labels, positive values
// and zero are cursor offsets.
@@ -245,6 +278,7 @@ public class BrowserHistoryPage extends ListActivity {
whereClause, null, orderBy);
buildMap();
+ mCursor.registerContentObserver(new ChangeObserver());
}
void refreshData() {
@@ -255,107 +289,109 @@ public class BrowserHistoryPage extends ListActivity {
}
}
- public void buildMap() {
+ private void buildMap() {
// The cursor is sorted by date
- // Make one pass to build up the ItemMap with the inserted
- // section separators.
- int array[] = new int[mCursor.getCount() + DateSorter.DAY_COUNT];
+ // The ItemMap will store the number of items in each bin.
+ int array[] = new int[DateSorter.DAY_COUNT];
+ // Zero out the array.
+ for (int j = 0; j < DateSorter.DAY_COUNT; j++) {
+ array[j] = 0;
+ }
int dateIndex = -1;
if (mCursor.moveToFirst() && mCursor.getCount() > 0) {
- int itemIndex = 0;
while (!mCursor.isAfterLast()) {
long date = mCursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX);
int index = mDateSorter.getIndex(date);
if (index > dateIndex) {
+ if (index == DateSorter.DAY_COUNT - 1) {
+ // We are already in the last bin, so it will
+ // include all the remaining items
+ array[index] = mCursor.getCount()
+ - mCursor.getPosition();
+ break;
+ }
dateIndex = index;
- array[itemIndex] = dateIndex - DateSorter.DAY_COUNT;
- itemIndex++;
}
- array[itemIndex] = mCursor.getPosition();
- itemIndex++;
+ array[dateIndex]++;
mCursor.moveToNext();
}
- } else {
- // The db is empty, just add the heading for the first item
- dateIndex = 0;
- array[0] = dateIndex - DateSorter.DAY_COUNT;
- }
- // Compress the array as the trailing date sections may be
- // empty
- int extraEntries = DateSorter.DAY_COUNT - dateIndex - 1;
- if (extraEntries > 0) {
- int newArraySize = array.length - extraEntries;
- mItemMap = new int[newArraySize];
- System.arraycopy(array, 0, mItemMap, 0, newArraySize);
- } else {
- mItemMap = array;
}
- }
-
- public View getView(int position, View convertView, ViewGroup parent) {
- if (mItemMap[position] < 0) {
- return getHeaderView(position, convertView);
- }
- return getHistoryItem(position, convertView);
+ mItemMap = array;
}
- View getHistoryItem(int position, View convertView) {
+ public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+ View convertView, ViewGroup parent) {
HistoryItem item;
if (null == convertView || !(convertView instanceof HistoryItem)) {
item = new HistoryItem(BrowserHistoryPage.this);
+ // Add padding on the left so it will be indented from the
+ // arrows on the group views.
+ item.setPadding(item.getPaddingLeft() + 10,
+ item.getPaddingTop(),
+ item.getPaddingRight(),
+ item.getPaddingBottom());
} else {
item = (HistoryItem) convertView;
}
- mCursor.moveToPosition(mItemMap[position]);
+ int index = childPosition;
+ for (int i = 0; i < groupPosition; i++) {
+ index += mItemMap[i];
+ }
+ mCursor.moveToPosition(index);
item.setName(mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
item.setUrl(url);
- item.setFavicon((Bitmap) mUrlsToIcons.get(url));
+ item.setFavicon(CombinedBookmarkHistoryActivity.getIconListenerSet(
+ getContentResolver()).getFavicon(url));
+ item.setIsBookmark(1 ==
+ mCursor.getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX));
return item;
}
- View getHeaderView(int position, View convertView) {
+ public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
TextView item;
if (null == convertView || !(convertView instanceof TextView)) {
LayoutInflater factory =
LayoutInflater.from(BrowserHistoryPage.this);
item = (TextView)
- factory.inflate(android.R.layout.preference_category, null);
+ factory.inflate(R.layout.history_header, null);
} else {
item = (TextView) convertView;
}
- item.setText(mDateSorter.getLabel(
- mItemMap[position] + DateSorter.DAY_COUNT));
+ item.setText(mDateSorter.getLabel(groupPosition));
return item;
}
public boolean areAllItemsEnabled() {
- return false;
+ return true;
}
- public boolean isEnabled(int position) {
- return mItemMap[position] >= 0;
+ public boolean isChildSelectable(int groupPosition, int childPosition) {
+ return true;
}
- public int getCount() {
- return mItemMap.length;
+ public int getGroupCount() {
+ return DateSorter.DAY_COUNT;
}
- public Object getItem(int position) {
+ public int getChildrenCount(int groupPosition) {
+ return mItemMap[groupPosition];
+ }
+
+ public Object getGroup(int groupPosition) {
return null;
}
- public long getItemId(int position) {
- return mItemMap[position];
+ public Object getChild(int groupPosition, int childPosition) {
+ return null;
}
- // 0 for TextView, 1 for HistoryItem
- public int getItemViewType(int position) {
- return mItemMap[position] < 0 ? 0 : 1;
+ public long getGroupId(int groupPosition) {
+ return groupPosition;
}
- public int getViewTypeCount() {
- return 2;
+ public long getChildId(int groupPosition, int childPosition) {
+ return (childPosition << 3) + groupPosition;
}
public boolean hasStableIds() {
@@ -370,8 +406,24 @@ public class BrowserHistoryPage extends ListActivity {
mObservers.remove(observer);
}
+ public void onGroupExpanded(int groupPosition) {
+
+ }
+
+ public void onGroupCollapsed(int groupPosition) {
+
+ }
+
+ public long getCombinedChildId(long groupId, long childId) {
+ return childId;
+ }
+
+ public long getCombinedGroupId(long groupId) {
+ return groupId;
+ }
+
public boolean isEmpty() {
- return getCount() == 1;
+ return mCursor.getCount() == 0;
}
}
}
diff --git a/src/com/android/browser/BrowserProvider.java b/src/com/android/browser/BrowserProvider.java
index 7aa5bb2..0c930c6 100644
--- a/src/com/android/browser/BrowserProvider.java
+++ b/src/com/android/browser/BrowserProvider.java
@@ -16,23 +16,26 @@
package com.android.browser;
+import android.app.ISearchManager;
import android.app.SearchManager;
+import android.content.ComponentName;
import android.content.ContentProvider;
-import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
import android.content.UriMatcher;
import android.database.AbstractCursor;
-import android.database.ContentObserver;
import android.database.Cursor;
-import android.database.DataSetObserver;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemProperties;
import android.provider.Browser;
import android.util.Log;
+import android.server.search.SearchableInfo;
import android.text.util.Regex;
public class BrowserProvider extends ContentProvider {
@@ -40,22 +43,41 @@ public class BrowserProvider extends ContentProvider {
private SQLiteOpenHelper mOpenHelper;
private static final String sDatabaseName = "browser.db";
private static final String TAG = "BrowserProvider";
- private static final String ORDER_BY = "date DESC";
+ private static final String ORDER_BY = "visits DESC, date DESC";
private static final String[] TABLE_NAMES = new String[] {
"bookmarks", "searches"
};
- private static final String[] SUGGEST_PROJECTION = new String [] {
- "0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT,
- "url AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA,
- "url AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
- "title AS " + SearchManager.SUGGEST_COLUMN_TEXT_2,
- "_id"
+ private static final String[] SUGGEST_PROJECTION = new String[] {
+ "_id", "url", "title", "bookmark"
};
private static final String SUGGEST_SELECTION =
"url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ?";
private String[] SUGGEST_ARGS = new String[4];
+ // shared suggestion array index, make sure to match COLUMNS
+ private static final int SUGGEST_COLUMN_INTENT_ACTION_ID = 1;
+ private static final int SUGGEST_COLUMN_INTENT_DATA_ID = 2;
+ private static final int SUGGEST_COLUMN_TEXT_1_ID = 3;
+ private static final int SUGGEST_COLUMN_TEXT_2_ID = 4;
+ private static final int SUGGEST_COLUMN_ICON_1_ID = 5;
+ private static final int SUGGEST_COLUMN_ICON_2_ID = 6;
+ private static final int SUGGEST_COLUMN_QUERY_ID = 7;
+
+ // shared suggestion columns
+ private static final String[] COLUMNS = new String[] {
+ "_id",
+ SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+ SearchManager.SUGGEST_COLUMN_INTENT_DATA,
+ SearchManager.SUGGEST_COLUMN_TEXT_1,
+ SearchManager.SUGGEST_COLUMN_TEXT_2,
+ SearchManager.SUGGEST_COLUMN_ICON_1,
+ SearchManager.SUGGEST_COLUMN_ICON_2,
+ SearchManager.SUGGEST_COLUMN_QUERY};
+
+ private static final int MAX_SUGGESTION_SHORT_ENTRIES = 3;
+ private static final int MAX_SUGGESTION_LONG_ENTRIES = 6;
+
// make sure that these match the index of TABLE_NAMES
private static final int URI_MATCH_BOOKMARKS = 0;
private static final int URI_MATCH_SEARCHES = 1;
@@ -206,221 +228,195 @@ public class BrowserProvider extends ContentProvider {
}
/*
- * Subclass AbstractCursor so we can add "Google Search"
+ * Subclass AbstractCursor so we can combine multiple Cursors and add
+ * "Google Search".
+ * Here are the rules.
+ * 1. We only have MAX_SUGGESTION_LONG_ENTRIES in the list plus
+ * "Google Search";
+ * 2. If bookmark/history entries are less than
+ * (MAX_SUGGESTION_SHORT_ENTRIES -1), we include Google suggest.
*/
private class MySuggestionCursor extends AbstractCursor {
- private Cursor mCursor;
+ private Cursor mHistoryCursor;
+ private Cursor mSuggestCursor;
+ private int mHistoryCount;
+ private int mSuggestionCount;
private boolean mBeyondCursor;
private String mString;
- private Uri mNotifyUri;
- private ContentResolver mContentResolver;
- private AbstractCursor.SelfContentObserver mObserver;
- private final Object mObserverLock = new Object();
-
- public MySuggestionCursor(Cursor c, String string) {
- mCursor = c;
- if (Regex.WEB_URL_PATTERN.matcher(string).matches()) {
- mString = "";
- } else {
- mString = string;
+
+ public MySuggestionCursor(Cursor hc, Cursor sc, String string) {
+ mHistoryCursor = hc;
+ mSuggestCursor = sc;
+ mHistoryCount = hc.getCount();
+ mSuggestionCount = sc != null ? sc.getCount() : 0;
+ if (mSuggestionCount > (MAX_SUGGESTION_LONG_ENTRIES - mHistoryCount)) {
+ mSuggestionCount = MAX_SUGGESTION_LONG_ENTRIES - mHistoryCount;
}
+ mString = string;
mBeyondCursor = false;
}
+ @Override
public boolean onMove(int oldPosition, int newPosition) {
- if (mCursor.getCount() == newPosition) {
- mBeyondCursor = true;
- } else {
- mCursor.moveToPosition(newPosition);
+ if (mHistoryCursor == null) {
+ return false;
+ }
+ if (mHistoryCount > newPosition) {
+ mHistoryCursor.moveToPosition(newPosition);
+ mBeyondCursor = false;
+ } else if (mHistoryCount + mSuggestionCount > newPosition) {
+ mSuggestCursor.moveToPosition(newPosition - mHistoryCount);
mBeyondCursor = false;
+ } else {
+ mBeyondCursor = true;
}
return true;
}
+ @Override
public int getCount() {
if (mString.length() > 0) {
- return mCursor.getCount() + 1;
+ return mHistoryCount + mSuggestionCount + 1;
} else {
- return mCursor.getCount();
+ return mHistoryCount + mSuggestionCount;
}
}
- public boolean deleteRow() {
- return !mBeyondCursor && mCursor.deleteRow();
- }
-
+ @Override
public String[] getColumnNames() {
- return mCursor.getColumnNames();
- }
-
- public int getColumnCount() {
- return mCursor.getColumnCount();
+ return COLUMNS;
}
+ @Override
public String getString(int columnIndex) {
- if (!mBeyondCursor) {
- return mCursor.getString(columnIndex);
- }
- switch (columnIndex) {
- case 2: // SearchManager.SUGGEST_COLUMN_TEXT_1
- return "Google Search for \"" + mString + "\"";
- case 1: // SearchManager.SUGGEST_COLUMN_INTENT_DATA
- return BrowserActivity.composeSearchUrl(mString);
- case 3: // SearchManager.SUGGEST_COLUMN_TEXT_2
- default:
- return "";
- }
- }
-
- public short getShort(int columnIndex) {
- if (!mBeyondCursor) {
- return mCursor.getShort(columnIndex);
- }
- if (0 == columnIndex) {
- return 0;
- }
- return -1;
- }
-
- public int getInt(int columnIndex) {
- if (!mBeyondCursor) {
- return mCursor.getInt(columnIndex);
- }
- if (0 == columnIndex) {
- return 0;
- }
- return -1;
- }
+ if ((mPos != -1 && mHistoryCursor != null)) {
+ switch(columnIndex) {
+ case SUGGEST_COLUMN_INTENT_ACTION_ID:
+ if (mHistoryCount > mPos) {
+ return Intent.ACTION_VIEW;
+ } else {
+ return Intent.ACTION_SEARCH;
+ }
- public long getLong(int columnIndex) {
- if (!mBeyondCursor) {
- return mCursor.getLong(columnIndex);
- }
- if (0 == columnIndex) {
- return 0;
- }
- return -1;
- }
+ case SUGGEST_COLUMN_INTENT_DATA_ID:
+ if (mHistoryCount > mPos) {
+ return mHistoryCursor.getString(1);
+ } else {
+ return null;
+ }
- public float getFloat(int columnIndex) {
- if (!mBeyondCursor) {
- return mCursor.getFloat(columnIndex);
- }
- if (0 == columnIndex) {
- return 0f;
- }
- return -1f;
- }
+ case SUGGEST_COLUMN_TEXT_1_ID:
+ if (mHistoryCount > mPos) {
+ return mHistoryCursor.getString(1);
+ } else if (!mBeyondCursor) {
+ return mSuggestCursor.getString(1);
+ } else {
+ return mString;
+ }
- public double getDouble(int columnIndex) {
- if (!mBeyondCursor) {
- return mCursor.getDouble(columnIndex);
- }
- if (0 == columnIndex) {
- return 0.0;
- }
- return -1.0;
- }
+ case SUGGEST_COLUMN_TEXT_2_ID:
+ if (mHistoryCount > mPos) {
+ return mHistoryCursor.getString(2);
+ } else if (!mBeyondCursor) {
+ return mSuggestCursor.getString(2);
+ } else {
+ return getContext().getString(R.string.search_google);
+ }
- public boolean isNull(int columnIndex) {
- return mCursor.isNull(columnIndex);
- }
+ case SUGGEST_COLUMN_ICON_1_ID:
+ if (mHistoryCount > mPos) {
+ if (mHistoryCursor.getInt(3) == 1) {
+ return new Integer(
+ R.drawable.ic_search_category_bookmark)
+ .toString();
+ } else {
+ return new Integer(
+ R.drawable.ic_search_category_history)
+ .toString();
+ }
+ } else {
+ return new Integer(
+ R.drawable.ic_search_category_suggest)
+ .toString();
+ }
- public boolean supportsUpdates() {
- return false;
- }
+ case SUGGEST_COLUMN_ICON_2_ID:
+ return new String("0");
- public boolean hasUpdates() {
- return false;
+ case SUGGEST_COLUMN_QUERY_ID:
+ if (mHistoryCount > mPos) {
+ return null;
+ } else if (!mBeyondCursor) {
+ return mSuggestCursor.getString(3);
+ } else {
+ return mString;
+ }
+ }
+ }
+ return null;
}
- public boolean updateString(int columnIndex, String value) {
- return false;
+ @Override
+ public double getDouble(int column) {
+ throw new UnsupportedOperationException();
}
- public boolean updateShort(int columnIndex, short value) {
- return false;
+ @Override
+ public float getFloat(int column) {
+ throw new UnsupportedOperationException();
}
- public boolean updateInt(int columnIndex, int value) {
- return false;
+ @Override
+ public int getInt(int column) {
+ throw new UnsupportedOperationException();
}
- public boolean updateLong(int columnIndex, long value) {
- return false;
+ @Override
+ public long getLong(int column) {
+ if ((mPos != -1) && column == 0) {
+ return mPos; // use row# as the _Id
+ }
+ throw new UnsupportedOperationException();
}
- public boolean updateFloat(int columnIndex, float value) {
- return false;
+ @Override
+ public short getShort(int column) {
+ throw new UnsupportedOperationException();
}
- public boolean updateDouble(int columnIndex, double value) {
- return false;
+ @Override
+ public boolean isNull(int column) {
+ throw new UnsupportedOperationException();
}
// TODO Temporary change, finalize after jq's changes go in
public void deactivate() {
- if (mCursor != null) {
- mCursor.deactivate();
+ if (mHistoryCursor != null) {
+ mHistoryCursor.deactivate();
+ }
+ if (mSuggestCursor != null) {
+ mSuggestCursor.deactivate();
}
super.deactivate();
}
public boolean requery() {
- return mCursor.requery();
+ return (mHistoryCursor != null ? mHistoryCursor.requery() : false) |
+ (mSuggestCursor != null ? mSuggestCursor.requery() : false);
}
// TODO Temporary change, finalize after jq's changes go in
public void close() {
super.close();
- if (mCursor != null) {
- mCursor.close();
- mCursor = null;
- }
- }
-
- public void registerContentObserver(ContentObserver observer) {
- super.registerContentObserver(observer);
- }
-
- public void unregisterContentObserver(ContentObserver observer) {
- super.unregisterContentObserver(observer);
- }
-
- public void registerDataSetObserver(DataSetObserver observer) {
- super.registerDataSetObserver(observer);
- }
-
- public void unregisterDataSetObserver(DataSetObserver observer) {
- super.unregisterDataSetObserver(observer);
- }
-
- protected void onChange(boolean selfChange) {
- synchronized (mObserverLock) {
- super.onChange(selfChange);
- if (mNotifyUri != null && selfChange) {
- mContentResolver.notifyChange(mNotifyUri, mObserver);
- }
+ if (mHistoryCursor != null) {
+ mHistoryCursor.close();
+ mHistoryCursor = null;
}
- }
-
- public void setNotificationUri(ContentResolver cr, Uri uri) {
- synchronized (mObserverLock) {
- if (mObserver != null) {
- cr.unregisterContentObserver(mObserver);
- }
- mObserver = new AbstractCursor.SelfContentObserver(this);
- cr.registerContentObserver(uri, true, mObserver);
- mCursor.setNotificationUri(cr, uri);
- super.setNotificationUri(cr, uri);
- mContentResolver = cr;
- mNotifyUri = uri;
+ if (mSuggestCursor != null) {
+ mSuggestCursor.close();
+ mSuggestCursor = null;
}
}
-
- public boolean getWantsAllOnMoveCalls() {
- return mCursor.getWantsAllOnMoveCalls();
- }
}
@Override
@@ -455,13 +451,58 @@ public class BrowserProvider extends ContentProvider {
suggestSelection = SUGGEST_SELECTION;
}
}
- // Suggestions are always performed with the default sort order:
- // date ASC.
+
Cursor c = db.query(TABLE_NAMES[URI_MATCH_BOOKMARKS],
SUGGEST_PROJECTION, suggestSelection, myArgs, null, null,
- ORDER_BY, null);
- c.setNotificationUri(getContext().getContentResolver(), url);
- return new MySuggestionCursor(c, selectionArgs[0]);
+ ORDER_BY,
+ (new Integer(MAX_SUGGESTION_LONG_ENTRIES)).toString());
+
+ if (Regex.WEB_URL_PATTERN.matcher(selectionArgs[0]).matches()) {
+ return new MySuggestionCursor(c, null, "");
+ } else {
+ // get Google suggest if there is still space in the list
+ if (myArgs != null && myArgs.length > 1
+ && c.getCount() < (MAX_SUGGESTION_SHORT_ENTRIES - 1)) {
+ ISearchManager sm = ISearchManager.Stub
+ .asInterface(ServiceManager
+ .getService(Context.SEARCH_SERVICE));
+ SearchableInfo si = null;
+ try {
+ // use the global search to get Google suggest provider
+ si = sm.getSearchableInfo(new ComponentName(
+ getContext(), "com.android.browser"), true);
+
+ // similar to the getSuggestions() in SearchDialog.java
+ StringBuilder uriStr = new StringBuilder("content://");
+ uriStr.append(si.getSuggestAuthority());
+ // if content path provided, insert it now
+ final String contentPath = si.getSuggestPath();
+ if (contentPath != null) {
+ uriStr.append('/');
+ uriStr.append(contentPath);
+ }
+ // append standard suggestion query path
+ uriStr.append('/' + SearchManager.SUGGEST_URI_PATH_QUERY);
+ // inject query, either as selection args or inline
+ String[] selArgs = null;
+ if (si.getSuggestSelection() != null) {
+ selArgs = new String[] {selectionArgs[0]};
+ } else {
+ uriStr.append('/');
+ uriStr.append(Uri.encode(selectionArgs[0]));
+ }
+
+ // finally, make the query
+ Cursor sc = getContext().getContentResolver().query(
+ Uri.parse(uriStr.toString()), null,
+ si.getSuggestSelection(), selArgs, null);
+
+ return new MySuggestionCursor(c, sc, selectionArgs[0]);
+ } catch (RemoteException e) {
+ }
+ }
+ return new MySuggestionCursor(c, null, selectionArgs[0]);
+ }
}
String[] projection = null;
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 6164e38..5038a4e 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -67,7 +67,6 @@ class BrowserSettings extends Observable {
private String homeUrl = "http://www.google.com/m?client=ms-" +
SystemProperties.get("ro.com.google.clientid", "unknown");
private boolean loginInitialized = false;
- private int orientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
private boolean autoFitPage = true;
private boolean showDebugSettings = false;
@@ -231,7 +230,6 @@ class BrowserSettings extends Observable {
loginInitialized = p.getBoolean("login_initialized", loginInitialized);
textSize = WebSettings.TextSize.valueOf(
p.getString(PREF_TEXT_SIZE, textSize.name()));
- orientation = p.getInt("orientation", orientation);
autoFitPage = p.getBoolean("autofit_pages", autoFitPage);
useWideViewPort = true; // use wide view port for either setting
if (autoFitPage) {
@@ -301,22 +299,7 @@ class BrowserSettings extends Observable {
ed.putBoolean("login_initialized", loginInitialized);
ed.commit();
}
-
- public int getOrientation() {
- return orientation;
- }
-
- public void setOrientation(Context context, int o) {
- if (orientation == o) {
- return;
- }
- orientation = o;
- Editor ed = PreferenceManager.
- getDefaultSharedPreferences(context).edit();
- ed.putInt("orientation", orientation);
- ed.commit();
- }
-
+
public WebSettings.TextSize getTextSize() {
return textSize;
}
diff --git a/src/com/android/browser/CombinedBookmarkHistoryActivity.java b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
new file mode 100644
index 0000000..963f179
--- /dev/null
+++ b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.app.Activity;
+import android.app.TabActivity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.provider.Browser;
+import android.webkit.WebIconDatabase.IconListener;
+import android.widget.TabHost;
+import android.widget.TabHost.TabSpec;
+import android.view.Window;
+
+import java.util.HashMap;
+import java.util.Vector;
+
+public class CombinedBookmarkHistoryActivity extends TabActivity
+ implements TabHost.OnTabChangeListener {
+ /* package */ static String BOOKMARKS_TAB = "bookmark";
+ /* package */ static String VISITED_TAB = "visited";
+ /* package */ static String HISTORY_TAB = "history";
+ /* package */ static String STARTING_TAB = "tab";
+
+ static class IconListenerSet implements IconListener {
+ // Used to store favicons as we get them from the database
+ // FIXME: We use a different method to get the Favicons in
+ // BrowserBookmarksAdapter. They should probably be unified.
+ private HashMap<String, Bitmap> mUrlsToIcons;
+ private Vector<IconListener> mListeners;
+
+ public IconListenerSet() {
+ mUrlsToIcons = new HashMap<String, Bitmap>();
+ mListeners = new Vector<IconListener>();
+ }
+ public void onReceivedIcon(String url, Bitmap icon) {
+ mUrlsToIcons.put(url, icon);
+ for (IconListener listener : mListeners) {
+ listener.onReceivedIcon(url, icon);
+ }
+ }
+ public void addListener(IconListener listener) {
+ mListeners.add(listener);
+ }
+ public Bitmap getFavicon(String url) {
+ return (Bitmap) mUrlsToIcons.get(url);
+ }
+ }
+ private static IconListenerSet sIconListenerSet;
+ static IconListenerSet getIconListenerSet(ContentResolver cr) {
+ if (null == sIconListenerSet) {
+ sIconListenerSet = new IconListenerSet();
+ Browser.requestAllIcons(cr, null, sIconListenerSet);
+ }
+ return sIconListenerSet;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ setContentView(R.layout.tabs);
+ TabHost tabHost = getTabHost();
+ tabHost.setOnTabChangedListener(this);
+
+ Bundle extras = getIntent().getExtras();
+ Resources resources = getResources();
+
+ getIconListenerSet(getContentResolver());
+ Intent bookmarksIntent = new Intent(this, BrowserBookmarksPage.class);
+ bookmarksIntent.putExtras(extras);
+ tabHost.addTab(tabHost.newTabSpec(BOOKMARKS_TAB)
+ .setIndicator(resources.getString(R.string.tab_bookmarks),
+ resources.getDrawable(R.drawable.browser_bookmark_tab))
+ .setContent(bookmarksIntent));
+
+ Intent visitedIntent = new Intent(this, MostVisitedActivity.class);
+ visitedIntent.putExtras(extras);
+ tabHost.addTab(tabHost.newTabSpec(VISITED_TAB)
+ .setIndicator(resources.getString(R.string.tab_most_visited),
+ resources.getDrawable(R.drawable.browser_visited_tab))
+ .setContent(visitedIntent));
+
+ Intent historyIntent = new Intent(this, BrowserHistoryPage.class);
+ historyIntent.putExtras(extras);
+ tabHost.addTab(tabHost.newTabSpec(HISTORY_TAB)
+ .setIndicator(resources.getString(R.string.tab_history),
+ resources.getDrawable(R.drawable.
+ browser_history_tab)).setContent(historyIntent));
+
+ String defaultTab = extras.getString(STARTING_TAB);
+ if (defaultTab != null) {
+ tabHost.setCurrentTab(2);
+ }
+ }
+
+ // Copied from DialTacts Activity
+ /** {@inheritDoc} */
+ public void onTabChanged(String tabId) {
+ Activity activity = getLocalActivityManager().getActivity(tabId);
+ if (activity != null) {
+ activity.onWindowFocusChanged(true);
+ }
+ }
+
+
+}
diff --git a/src/com/android/browser/FindDialog.java b/src/com/android/browser/FindDialog.java
index 2b26784..44109ff 100644
--- a/src/com/android/browser/FindDialog.java
+++ b/src/com/android/browser/FindDialog.java
@@ -29,6 +29,7 @@ import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
+import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.EditText;
import android.widget.TextView;
@@ -121,6 +122,8 @@ import android.widget.TextView;
mMatches = (TextView) findViewById(R.id.matches);
mMatchesView = findViewById(R.id.matches_view);
disableButtons();
+ theWindow.setSoftInputMode(
+ WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
}
public void dismiss() {
diff --git a/src/com/android/browser/HistoryItem.java b/src/com/android/browser/HistoryItem.java
index c83ced1..55e43f0 100644
--- a/src/com/android/browser/HistoryItem.java
+++ b/src/com/android/browser/HistoryItem.java
@@ -17,26 +17,31 @@
package com.android.browser;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
import android.content.Context;
+import android.database.Cursor;
import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.graphics.drawable.PaintDrawable;
-import android.view.LayoutInflater;
-import android.widget.LinearLayout;
+import android.net.Uri;
+import android.provider.Browser;
+import android.util.Log;
+import android.view.View;
+import android.webkit.WebIconDatabase;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.Date;
/**
* Layout representing a history item in the classic history viewer.
*/
-/* package */ class HistoryItem extends LinearLayout {
+/* package */ class HistoryItem extends BookmarkItem {
- private TextView mTitleView; // Truncated Title
- private String mUrl; // Full Url
- private TextView mUrlText; // Truncated Url
-
+ private CompoundButton mStar; // Star for bookmarking
+ private CompoundButton.OnCheckedChangeListener mListener;
/**
* Create a new HistoryItem.
* @param context Context for this HistoryItem.
@@ -44,83 +49,79 @@ import android.widget.TextView;
/* package */ HistoryItem(Context context) {
super(context);
- setWillNotDraw(false);
- LayoutInflater factory = LayoutInflater.from(context);
- factory.inflate(R.layout.history_item, this);
- mTitleView = (TextView) findViewById(R.id.title);
- mUrlText = (TextView) findViewById(R.id.url);
+ mStar = (CompoundButton) findViewById(R.id.star);
+ mStar.setVisibility(View.VISIBLE);
+ mListener = new CompoundButton.OnCheckedChangeListener() {
+ public void onCheckedChanged(CompoundButton buttonView,
+ boolean isChecked) {
+ ContentResolver cr = mContext.getContentResolver();
+ Cursor cursor = cr.query(
+ Browser.BOOKMARKS_URI,
+ Browser.HISTORY_PROJECTION,
+ "url = ?",
+ new String[] { mUrl },
+ null);
+ boolean first = cursor.moveToFirst();
+ // Should be in the database no matter what
+ if (!first) {
+ throw new AssertionError("URL is not in the database!");
+ }
+ if (isChecked) {
+ // Add to bookmarks
+ // FIXME: Share code with AddBookmarkPage.java
+ ContentValues map = new ContentValues();
+ map.put(Browser.BookmarkColumns.CREATED,
+ new Date().getTime());
+ map.put(Browser.BookmarkColumns.TITLE, getName());
+ map.put(Browser.BookmarkColumns.BOOKMARK, 1);
+ try {
+ cr.update(Browser.BOOKMARKS_URI, map,
+ "_id = " + cursor.getInt(0), null);
+ } catch (IllegalStateException e) {
+ Log.e("HistoryItem", "no database!");
+ }
+ WebIconDatabase.getInstance().retainIconForPageUrl(mUrl);
+ // catch IllegalStateException?
+ Toast.makeText(mContext, R.string.added_to_bookmarks,
+ Toast.LENGTH_LONG).show();
+ } else {
+ // Remove from bookmarks
+ // FIXME: This code should be shared with
+ // BrowserBookmarksAdapter.java
+ WebIconDatabase.getInstance().releaseIconForPageUrl(mUrl);
+ Uri uri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
+ cursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX));
+ // It is no longer a bookmark, but it is still a visited
+ // site.
+ ContentValues values = new ContentValues();
+ values.put(Browser.BookmarkColumns.BOOKMARK, 0);
+ try {
+ cr.update(uri, values, null, null);
+ } catch (IllegalStateException e) {
+ Log.e("HistoryItem", "no database!");
+ }
+ Toast.makeText(mContext, R.string.removed_from_bookmarks,
+ Toast.LENGTH_LONG).show();
+ }
+ cursor.deactivate();
+ }
+ };
}
void copyTo(HistoryItem item) {
- item.mTitleView.setText(mTitleView.getText());
+ item.mTextView.setText(mTextView.getText());
item.mUrlText.setText(mUrlText.getText());
- }
-
- /**
- * Return the name of this HistoryItem.
- * @return String name of this HistoryItem.
- /
- /* package */ String getName() {
- return mTitleView.getText().toString();
- }
-
- /**
- * Return the url of this HistoryItem.
- * @return String url of this HistoryItem.
- /
- /* package */ String getUrl() {
- return mUrl;
+ item.setIsBookmark(mStar.isChecked());
+ item.mImageView.setImageDrawable(mImageView.getDrawable());
}
/**
- * Set the favicon for this item.
- *
- * @param b The new bitmap for this item.
- * If it is null, will use the default.
- */
- /* package */ void setFavicon(Bitmap b) {
- Drawable[] array = new Drawable[2];
- PaintDrawable p = new PaintDrawable(Color.WHITE);
- p.setCornerRadius(3f);
- array[0] = p;
- if (b != null) {
- array[1] = new BitmapDrawable(b);
- } else {
- array[1] = new BitmapDrawable(mContext.getResources().
- openRawResource(R.drawable.app_web_browser_sm));
- }
- LayerDrawable d = new LayerDrawable(array);
- d.setLayerInset(1, 2, 2, 2, 2);
- d.setBounds(0, 0, 20, 20);
- mTitleView.setCompoundDrawables(d, null, null, null);
- }
-
- /**
- * Set the name for this HistoryItem.
- * If the name is longer that BrowserSettings.MAX_TEXTVIEW_LEN characters,
- * the name is truncated to BrowserSettings.MAX_TEXTVIEW_LEN characters.
- * The History activity does not expose a UI element that can show the
- * full title.
- * @param name String representing new name for this HistoryItem.
- */
- /* package */ void setName(String name) {
- if (name != null && name.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
- name = name.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN);
- }
- mTitleView.setText(name);
- }
-
- /**
- * Set the url for this HistoryItem.
- * @param url String representing new url for this HistoryItem.
+ * Set whether or not this represents a bookmark, and make sure the star
+ * behaves appropriately.
*/
- /* package */ void setUrl(String url) {
- mUrl = url;
- // Truncate the url for the screen
- if (url.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
- mUrlText.setText(url.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN));
- } else {
- mUrlText.setText(url);
- }
+ void setIsBookmark(boolean isBookmark) {
+ mStar.setOnCheckedChangeListener(null);
+ mStar.setChecked(isBookmark);
+ mStar.setOnCheckedChangeListener(mListener);
}
}
diff --git a/src/com/android/browser/MostVisitedActivity.java b/src/com/android/browser/MostVisitedActivity.java
new file mode 100644
index 0000000..aeaf2a6
--- /dev/null
+++ b/src/com/android/browser/MostVisitedActivity.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.app.Activity;
+import android.app.ListActivity;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Browser;
+import android.webkit.WebIconDatabase.IconListener;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.Vector;
+
+public class MostVisitedActivity extends ListActivity {
+
+ private MyAdapter mAdapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mAdapter = new MyAdapter();
+ CombinedBookmarkHistoryActivity.getIconListenerSet(getContentResolver())
+ .addListener(new IconReceiver());
+ setListAdapter(mAdapter);
+ }
+
+ private class IconReceiver implements IconListener {
+ public void onReceivedIcon(String url, Bitmap icon) {
+ setListAdapter(mAdapter);
+ }
+ }
+
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ TextView tv = (TextView) v.findViewById(R.id.url);
+ String url = tv.getText().toString();
+ loadUrl(url, false);
+ }
+
+ private void loadUrl(String url, boolean newWindow) {
+ Intent intent = new Intent().setAction(url);
+ if (newWindow) {
+ Bundle b = new Bundle();
+ b.putBoolean("new_window", true);
+ intent.putExtras(b);
+ }
+ setResultToParent(RESULT_OK, intent);
+ finish();
+ }
+
+ private class MyAdapter implements ListAdapter {
+ private Vector<DataSetObserver> mObservers;
+ private Cursor mCursor;
+ // These correspond with projection below.
+ private final int mUrlIndex = 0;
+ private final int mTitleIndex = 1;
+ private final int mBookmarkIndex = 2;
+
+ MyAdapter() {
+ mObservers = new Vector<DataSetObserver>();
+ String[] projection = new String[] {
+ Browser.BookmarkColumns.URL,
+ Browser.BookmarkColumns.TITLE,
+ Browser.BookmarkColumns.BOOKMARK };
+ String whereClause = Browser.BookmarkColumns.VISITS + " != 0";
+ String orderBy = Browser.BookmarkColumns.VISITS + " DESC";
+ mCursor = managedQuery(Browser.BOOKMARKS_URI, projection,
+ whereClause, null, orderBy);
+ mCursor.registerContentObserver(new ChangeObserver());
+ }
+
+ private class ChangeObserver extends ContentObserver {
+ public ChangeObserver() {
+ super(new Handler());
+ }
+
+ @Override
+ public boolean deliverSelfNotifications() {
+ return true;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ MyAdapter.this.refreshData();
+ }
+ }
+
+ void refreshData() {
+ mCursor.requery();
+ for (DataSetObserver o : mObservers) {
+ o.onChanged();
+ }
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ HistoryItem item;
+ if (null == convertView) {
+ item = new HistoryItem(MostVisitedActivity.this);
+ } else {
+ item = (HistoryItem) convertView;
+ }
+ mCursor.moveToPosition(position);
+ item.setName(mCursor.getString(mTitleIndex));
+ String url = mCursor.getString(mUrlIndex);
+ item.setUrl(url);
+ item.setFavicon(CombinedBookmarkHistoryActivity.getIconListenerSet(
+ getContentResolver()).getFavicon(url));
+ item.setIsBookmark(1 == mCursor.getInt(mBookmarkIndex));
+ return item;
+ }
+
+ public boolean areAllItemsEnabled() {
+ return true;
+ }
+
+ public boolean isEnabled(int position) {
+ return true;
+ }
+
+ public int getCount() {
+ return mCursor.getCount();
+ }
+
+ public Object getItem(int position) {
+ return null;
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ // Always a HistoryItem
+ public int getItemViewType(int position) {
+ return 0;
+ }
+
+ public int getViewTypeCount() {
+ return 1;
+ }
+
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ public void registerDataSetObserver(DataSetObserver observer) {
+ mObservers.add(observer);
+ }
+
+ public void unregisterDataSetObserver(DataSetObserver observer) {
+ mObservers.remove(observer);
+ }
+
+ public boolean isEmpty() {
+ return getCount() == 0;
+ }
+ }
+
+ // This Activity is generally a sub-Activity of CombinedHistoryActivity. In
+ // that situation, we need to pass our result code up to our parent.
+ // However, if someone calls this Activity directly, then this has no
+ // parent, and it needs to set it on itself.
+ private void setResultToParent(int resultCode, Intent data) {
+ Activity a = getParent() == null ? this : getParent();
+ a.setResult(resultCode, data);
+ }
+}
+
diff --git a/src/com/android/browser/TabControl.java b/src/com/android/browser/TabControl.java
index dfac185..69610bf 100644
--- a/src/com/android/browser/TabControl.java
+++ b/src/com/android/browser/TabControl.java
@@ -17,7 +17,9 @@
package com.android.browser;
import android.content.Context;
+import android.net.http.SslError;
import android.os.Bundle;
+import android.os.Message;
import android.util.Config;
import android.util.Log;
import android.view.Gravity;
@@ -25,8 +27,10 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
+import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
+import android.webkit.SslErrorHandler;
import android.webkit.WebBackForwardList;
import android.webkit.WebChromeClient;
import android.webkit.WebHistoryItem;
@@ -79,6 +83,26 @@ class TabControl {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return mClient.shouldOverrideUrlLoading(view, url);
}
+ @Override
+ public void onReceivedSslError(WebView view, SslErrorHandler handler,
+ SslError error) {
+ mClient.onReceivedSslError(view, handler, error);
+ }
+ @Override
+ public void onReceivedHttpAuthRequest(WebView view,
+ HttpAuthHandler handler, String host, String realm) {
+ mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
+ }
+ @Override
+ public void onFormResubmission(WebView view, Message dontResend,
+ Message resend) {
+ mClient.onFormResubmission(view, dontResend, resend);
+ }
+ @Override
+ public void onReceivedError(WebView view, int errorCode,
+ String description, String failingUrl) {
+ mClient.onReceivedError(view, errorCode, description, failingUrl);
+ }
}
// Subclass of WebChromeClient to display javascript dialogs.
private class SubWindowChromeClient extends WebChromeClient {