diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-02-10 15:44:04 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-02-10 15:44:04 -0800 |
commit | b7775e1e46a6c8ce0f07747d44c1b1792bb0ce1c (patch) | |
tree | 5955e8e4ec01ed58967626e02c703e40a10bd6a8 /src/com/android/browser | |
parent | d9effa543b8c81d48b8324aac00410b8c2a355a0 (diff) | |
download | packages_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.java | 63 | ||||
-rw-r--r-- | src/com/android/browser/AddNewBookmark.java | 6 | ||||
-rw-r--r-- | src/com/android/browser/BookmarkItem.java | 28 | ||||
-rw-r--r-- | src/com/android/browser/BrowserActivity.java | 193 | ||||
-rw-r--r-- | src/com/android/browser/BrowserBookmarksPage.java | 20 | ||||
-rw-r--r-- | src/com/android/browser/BrowserDownloadAdapter.java | 1 | ||||
-rw-r--r-- | src/com/android/browser/BrowserHistoryPage.java | 202 | ||||
-rw-r--r-- | src/com/android/browser/BrowserProvider.java | 383 | ||||
-rw-r--r-- | src/com/android/browser/BrowserSettings.java | 19 | ||||
-rw-r--r-- | src/com/android/browser/CombinedBookmarkHistoryActivity.java | 124 | ||||
-rw-r--r-- | src/com/android/browser/FindDialog.java | 3 | ||||
-rw-r--r-- | src/com/android/browser/HistoryItem.java | 165 | ||||
-rw-r--r-- | src/com/android/browser/MostVisitedActivity.java | 191 | ||||
-rw-r--r-- | src/com/android/browser/TabControl.java | 24 |
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 { |